Docker autónomo: configuración del host en .env e imagen fijada

- Puertos, carpeta de mangas, PUID/PGID, URL pública y registro se
  configuran en .env (plantilla en .env.example); sin .env arranca con
  valores portables (0.0.0.0:3352, ./mangas).
- Publicar en 0.0.0.0 evita fallar al arrancar si la IP de la LAN o de
  Tailscale aún no existe; el acceso lo siguen limitando las reglas
  DOCKER-USER del host.
- Imagen base fijada a node:24.22.2-alpine3.24 (node:sqlite es experimental).
- ALLOW_SIGNUP=false por defecto (el primer usuario puede registrarse igual).
- Comprobación de permisos al arrancar con mensaje claro (chown / PUID).
- README: qué guardar y cómo mover el servicio a otro servidor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 00:59:55 -06:00
co-authored by Claude Opus 5.5
parent 73fc1d5849
commit af90d34c95
8 changed files with 93 additions and 19 deletions
+18 -1
View File
@@ -20,7 +20,24 @@ const UA = 'manga-reader-selfhosted/1.0'
const SESSION_DAYS = 120
// ---------- Base de datos ----------
fs.mkdirSync(DATA_DIR, { recursive: true })
// Comprobación de permisos al arrancar: con un UID distinto en el host, el error de SQLite sería críptico.
function checkWritable(dir, fatal) {
try {
fs.mkdirSync(dir, { recursive: true })
const probe = path.join(dir, `.write-test-${process.pid}`)
fs.writeFileSync(probe, '')
fs.rmSync(probe)
return true
} catch (e) {
const uid = process.getuid?.(), gid = process.getgid?.()
console.error(`${fatal ? 'ERROR' : 'AVISO'}: no se puede escribir en ${dir} (${e.code || e.message}) como uid ${uid}:${gid}.
Solución: en el host, "sudo chown -R ${uid}:${gid} <carpeta>" o pon PUID/PGID en .env con el dueño de la carpeta (id -u / id -g).`)
if (fatal) process.exit(1)
return false
}
}
checkWritable(DATA_DIR, true)
checkWritable(MANGA_DIR, false) // sin esto solo fallan las descargas
const db = new DatabaseSync(path.join(DATA_DIR, 'manga.db'))
const SECRET_FILE = path.join(DATA_DIR, 'secret')
if (!fs.existsSync(SECRET_FILE)) fs.writeFileSync(SECRET_FILE, crypto.randomBytes(32).toString('hex'), { mode: 0o600 })