Resolve the Seafile host over IPv4 only (musl/Alpine ENOTFOUND on IPv6 NXDOMAIN); v2.17.3
Publish Container / build (push) Successful in 14m53s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-12 10:01:13 -04:00
1 parent 22c0038ebb
commit 1bf11a3669
4 files changed
+36 -3

No files matched your search

+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "siteforge", "name": "siteforge",
"version": "2.17.2", "version": "2.17.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "siteforge", "name": "siteforge",
"version": "2.17.2", "version": "2.17.3",
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.1135.0", "@aws-sdk/client-s3": "^3.1135.0",
"@dnd-kit/core": "^6.3.1", "@dnd-kit/core": "^6.3.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "siteforge", "name": "siteforge",
"private": true, "private": true,
"version": "2.17.2", "version": "2.17.3",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+3
View File
@@ -67,6 +67,7 @@ import { register as registerNuggets } from './server/routes/nuggets.js'
import { register as registerNuggetsHostUpload } from './server/routes/nuggets-host-upload.js' import { register as registerNuggetsHostUpload } from './server/routes/nuggets-host-upload.js'
import { register as registerNuggetsWorkflow } from './server/routes/nuggets-workflow.js' import { register as registerNuggetsWorkflow } from './server/routes/nuggets-workflow.js'
import { register as registerPodcastWorkflow } from './server/routes/podcast-workflow.js' import { register as registerPodcastWorkflow } from './server/routes/podcast-workflow.js'
import { preferIpv4ForSeafile } from './server/seafile-dns.js'
import { startNuggetsSeafileWatcher } from './server/nuggets-seafile-watcher.js' import { startNuggetsSeafileWatcher } from './server/nuggets-seafile-watcher.js'
import { register as registerFeed } from './server/routes/feed.js' import { register as registerFeed } from './server/routes/feed.js'
import { register as registerQrCodes } from './server/routes/qr-codes.js' import { register as registerQrCodes } from './server/routes/qr-codes.js'
@@ -74,6 +75,8 @@ import { register as registerBiblePassage } from './server/routes/bible-passage.
import { register as registerNewsletter } from './server/routes/newsletter.js' import { register as registerNewsletter } from './server/routes/newsletter.js'
import { register as registerPublic } from './server/routes/public.js' import { register as registerPublic } from './server/routes/public.js'
preferIpv4ForSeafile()
const app = express() const app = express()
app.use(express.json({ limit: '10mb' })) app.use(express.json({ limit: '10mb' }))
const trustProxyHops = Number(process.env.TRUST_PROXY_HOPS ?? 1) const trustProxyHops = Number(process.env.TRUST_PROXY_HOPS ?? 1)
+30
View File
@@ -0,0 +1,30 @@
import dns from 'node:dns'
import { SEAFILE_URL } from './config.js'
// Alpine's resolver (musl) fails the whole lookup when a DNS server answers the IPv6 (AAAA)
// query with "no such name" even though the IPv4 answer is fine, so Node reports ENOTFOUND for
// a host that resolves. Ask for IPv4 only, and only for the Seafile host.
export function preferIpv4ForSeafile() {
let host = ''
try {
host = SEAFILE_URL ? new URL(SEAFILE_URL).hostname : ''
} catch {
return
}
if (!host) return
const originalLookup = dns.lookup
dns.lookup = function lookup(hostname, options, callback) {
if (hostname === host) {
if (typeof options === 'function') {
callback = options
options = {}
} else if (typeof options === 'number') {
options = { family: options }
}
if (!options?.family) options = { ...options, family: 4 }
}
return originalLookup.call(this, hostname, options, callback)
}
console.log(`[seafile-dns] resolving ${host} over IPv4 only`)
}