Immich DB: misma imagen desde GHCR, sólo metadatos — 20 octubre 2026¶
Verificación00:49CEST desde el equipo local contra HTTPS oficial de GHCR. Sin SSH, Bazzite, export de VM208, pull/load ni descarga de capas. Autenticación anónima mediante bearer de lectura guardado exclusivamente en memoria; no se ha impreso ni persistido. El coordinador aportó previamente la asociación Docker readonly de ImageID de producción y RepoDigest; esta tarea contrasta su cadena en el registro.
Resultado¶
Repositorio exacto: ghcr.io/immich-app/postgres.
| Objeto | SHA256 | Tamaño |
|---|---|---|
| RepoDigest aportado: OCI index, no manifest de una plataforma | <REDACTED> |
1609bytes |
| Manifest único del index para linux/amd64 | <REDACTED> |
4281bytes |
| Config del manifest, igual al ImageID producción | <REDACTED> |
15677bytes |
El JSON de configuración confirma os=linux, architecture=amd64. Se recalculó SHA256 sobre los bytes recibidos de los tres objetos, comprobando igualdad con cada digest solicitado; tamaños de manifest/config coinciden con sus descriptores y las cabeceras Docker-Content-Digest de index/manifest coinciden. Sólo se consultaron esos metadatos, sin imprimir Env ni comandos de la configuración.
El manifest refiere 21capas gzip, tamaños declarados sumados 208950383bytes (~199.27MiB). Capas+config:208966060bytes; metadatos descargados index+manifest+config:21567bytes, sin contar headers/token. Son tamaños comprimidos declarados; no garantizan espacio descomprimido ni tráfico exacto del futuro pull (caché, protocolo y reintentos influyen). No se han descargado ni hasheado las capas en esta tarea.
Qué acredita¶
OCI index describe manifests por plataforma; el manifest OCI referencia por digest config y capas ordenadas. La configuración OCI incluye identidad del sistema de archivos mediante diff_ids; su hash es el ImageID. Los descriptores OCI vinculan contenido, digest y tamaño. Esta cadena identifica el mismo config/ImageID aportado de producción, sin depender de un tag mutable. No demuestra estado de una base de datos, ejecución exitosa ni autenticidad mediante firma del editor.
Método revisado: OCI serial limitado, no ejecutado por el revisor¶
La propuesta inicial de pull nativo queda sustituida por el método autorizado por Root para mantener 4MiB/s: descargar serialmente desde GHCR el manifest fijado, config y21capas con comprobación de digest/tamaño, construir OCIarchive y cargarla en el Podman rootless existente. Un pull nativo sin limitador no cumple ese presupuesto. La cadena de imagen anterior permanece válida; no hay tag mutable ni export de VM208.
Revisión independiente de fuentes del agente propietario:
scripts/original-backups/immich-recovery-oci.pySHA256<REDACTED>.scripts/original-backups/immich-recovery-offhost-inputs.pySHA256<REDACTED>.test_offhost_inputs.py: 14/14 PASS ejecutados independientemente, con HTTP falso y árboles/procesos sintéticos locales. No se ejecutó NAS, SSH, Bazzite, descarga de capas ni Podman real desde la revisión.
Resultado de review: sin bloqueantes concretos pendientes en esos hashes para la fase de inputs. Se corrigieron durante revisión el crédito de velocidad tras pausas, la lectura HTTP que podía ocultar el deadline, el comando image-exists fuera del grupo de procesos acotado y la falta de alarm autónoma del receptor remoto. El limitador ahora no acumula crédito idle, con fragmentos máximos64KiB; HTTP usa read1/sockettimeout20s y deadline autónomo1200s. Los redirects sólo admiten HTTPS en hosts GHCR/GitHub permitidos y eliminan bearer al cambiar de host.
El flujo de dump utiliza exclusivamente generación NAS19 y su SHA esperado, descarga a staging Mac privado nuevo, verifica tamaño/hash/CRC y manifest, luego transmite a staging Bazzite nuevo. No hay canal de VM208 ni TerraMaster. Stages existentes y operandos no privados se rechazan. Host trust usa StrictHostKeyChecking=yes; credenciales del NAS se consumen desde el almacén local existente en memoria/PTY, sin incluirlas en argv ni fuentes versionadas. Archivos y directorios de prueba se sincronizan antes del proof.
Preflight Bazzite exige memoria disponible3GiB y espacio32GiB; durante operación reserva memoria2GiB y disco24GiB. El stage se limita8GiB, las transferencias4MiB/s y deadlines1200s. Carga de imagen acotada300s e inspect10s; procesos propios en sesión/grupo separado y limpieza limitada a ellos. Tras cargar OCI sin tags se exige ImageID769aa218…/linux/amd64 exactos. Ningún helper crea contenedor SQL.
Límites y rollback: el image store de Podman está fuera del límite8GiB del staging y su carga no es atómica; queda protegido por el guard global de espacio libre24GiB, no por una promesa de rollback transaccional. Se registra si la imagen esperada preexistía antes del load. No se ejecuta image prune/rmi ni se eliminan capas compartidas. Fallos conservan stages privados para inspección, sin reintento o sobrescritura automática. Cualquier retirada posterior debe limitarse a artefactos propios comprobados y revisarse por separado. Los tests simulados no acreditan integración real NAS/CDN/Podman ni garantizan interrupción instantánea de IO bloqueada en kernel.
La fase siguiente requiere que el propietario entregue proof de inputs y Root lo revise antes de autorizar un contenedor o SQL. Podman oficial describe referencias por digest/plataforma; aquí se conserva esa identidad mediante OCI verificado y comprobación posterior, respetando el rate limit que el pull nativo no proporciona. Esta revisión no ejecutó el método ni cambió fuentes del propietario.
Revisión del último cambio de observabilidad: tres eventos JSON de progreso con fase, stageID, tamaño o hash, sin SQL/secretos; sin cambio del flujo. Hash offhost final3dbf1ef8… y OCI217b6325… comprobados;14tests repetidos PASS.
Delta de ruta canónica y diagnóstico — revisión posterior¶
El propietario comunicó que el primer preflight rechazó correctamente /home por ser un symlink del sistema Bazzite hacia /var/home, antes de adquirir inputs. Lectura del propietario acreditó la raíz canónica privada /var/home/monxas/.local/state/immich-recovery-input, UID1000/modo0700. Se revisó el cambio de ROOT/REMOTE_ROOT a ese pathname canónico en ambos helpers, conservando las guardas que rechazan symlinks; eventos phase/error_class sólo revelan metadatos sanitizados. Delta PASS;14tests repetidos independientemente PASS. Hashes finales revisados offhost <REDACTED>, OCI <REDACTED>. El alcance sigue inputs-only y los límites anteriores permanecen. El revisor no accedió a Bazzite/NAS ni ejecutó transferencias.
Delta final de fase OCI separada — revisión independiente¶
El propietario y Root comunicaron que el primer intento había verificado dump+manifest privados en Mac/Bazzite, pero falló en GETconfig dejando0bytes: manifest4281bytes válido, sin archive/ownership/imageproof y sin load. El diagnóstico puntual posterior de config pasó15677bytes/SHA769aa218…; causa inicial desconocida, sin atribución al reboot ni relajación de TLS/allowlist.
Root autorizó una única fase OCI nueva 20261020-oci0105, reutilizando el dump del stage0055 en sólo lectura y sin repetir NAS/streaming ni escribir ese stage previo. El nuevo modo verifica propietario, privacidad, nlink1, tamaño/hash/CRC del dump, manifest e identidad antes/después; publica combinedproof únicamente en stage nuevo y metadata Mac nueva. El presupuesto8GiB agrega el padre canónico con todos los stages, incluido0055; image store sigue fuera de ese agregado, protegido por reserva de disco.
Se revisó observabilidad phase/digest/error_class/http_status sin URL firmada, token ni texto arbitrario de excepción. CURRENT_STAGE se fija sólo después de crear layout exclusivo: un intento accidental sobre layout viejo no añade failureproof allí. SSH Bazzite fija direct192.168.0.XXX/ProxyJumpnone/ProxyCommandnone con host trust existente; TCPpreflight usa las mismas opciones. Root confirmó previamente que los proxies efectivos ya eran none, sin vincularlos al fallo HTTP.
Hashes revisados finales: offhost <REDACTED>, OCI <REDACTED>. 19/19tests PASS ejecutados independientemente. Review PASS para esa única fase inputs; este revisor no ejecutó HTTP adicional, SSH, transfers, load ni SQL. El propietario debe entregar proof de inputs a Root antes de cualquier contenedor/SQL.
Inputs preparados en Bazzite; todavía sin SQL¶
El coordinador autorizó adquirir la misma imagen sin usar VM208 ni tags. Para
respetar4MiB/s también en imagen se sustituyó el pull nativo propuesto por descarga
OCI serial HTTPS del manifest886090/config769 y21capas, con SHA/tamaño verificados,
token anónimo solo RAM, TLS/redirect allowlist y sin credenciales nuevas.
OCIarchive208.998.400 bytes SHA256
<REDACTED>.
Se ejecutó un único load rootless; la imagen no existía antes. No se creó contenedor.
La primera inspección postload falló por usar .Id en lugar de .ID de Podman.
Se preservó el failure histórico y el coordinador revisó/autorizó reconciliación
solo de lecturas, sin refetch ni segundo load. Confirmó imagen exacta
sha256:<REDACTED>,
linux/amd64, rehash de todos los objetos y dump19 CRC/hash idéntico, origen0055
sin modificar. No se relajó hosttrust, TLS, políticas ni allowlist.
Proof remoto0400/UID1000 en
/var/home/monxas/.local/state/immich-recovery-input/20261020-oci0105/combined-inputs-verified.json,
SHA256 <REDACTED>.
Inputs agregados601.653.248 bytes, disco libre276.318.248.960,
MemAvailable25.980.825.600, SwapFree16.771.444.736. Python existente3.14.8.
Mac conserva copia privada del mismo JSON. Los stages0105/0055 y fallos previos
se preservan; no prune/rmi automático. El imagestore queda fuera de8GiB de inputs,
cubierto por guardia global de espacio24GiB.
Esto acredita inputs disponibles e identidad exacta; todavía no se ha ejecutado restore PostgreSQL ni SQL, ni se ha acreditado coherencia con originales. El runner corregido queda pendiente de publicación y autorización posterior. Detalles y límites en informe de recuperación.
Primer ensayo DB posterior: sin creación de contenedor¶
Tras publicar4e6a091 y autorización explícita, una ejecución del runner659e7a pasó
plan/preflight pero Podman5.8.7 rechazó uid=999 dentro de --tmpfs, antes de crear
el objeto. container exists del nombre propio devolvió1, ausencia verificada.
No kernelproof, SELECT1 ni SQL. El result privado registra cleanup unavailable
porque el objeto nunca existió; no equivale a un stop ejecutado. Work0120, fuentes
y logs privados se preservan. Inputs/proof029f… e imagen cargada exacta siguen
válidos; no se volvió a cargar ni descargar imagen. No reintento hasta corregir,
revisar/publicar la compatibilidad tmpfs y nueva autorización del coordinador.
Segundo ensayo: kernelproof válido; falta compatibilidad de socket bootstrap¶
Publicado765dad4, runnerc52391e0/podman-pland07b5f92, nuevo code/work0125 y una
única ejecución autorizada. No nuevo fetch/load; inputs exactos preservados.
Gate argv/controlRO/PGDATA vacío y límites efectivos1GiB/swap0/.5CPU/pids128,
rednone/rootfsRO/User999:999 y mapping UID/GID quedaron probados y guardados
antes de liberar initdb. El entrypoint luego falló: servidor temporal en /tmp,
psql interno buscando /var/run/postgresql. Salida propia2/OOMfalse; runnerexit1,
stoppedtrue, cleanup_errors=[]; dump no importado. No reintento/restart.
Bootstrap privado2580B SH
Kernelproof0125:980bytes, UID1000/mode0600,
SHA256<REDACTED>.
Lectura posterior del entrypoint exacto desde el contenedor propio detenido:
14179bytes, copia privada600/fsync en work0125/docker-entrypoint.original.sh,
SHA256<REDACTED>.
Confirma que docker_process_sql limpia PGHOST/PGHOSTADDR: la propuesta envPGHOST
por sí sola queda descartada. Ajuste fuente propuesto por Root: socketserver en
/tmp,/var/run/postgresql, ambos tmpfs ya revisados, preservando runner-h/tmp.
Pendiente revisión/publicación y nueva autorización; ningún restart/exec/SQL.
Tercer ensayo: DB-only restaurada, imagen exacta acreditada ejecutándose¶
Publicado5bbc06c, nuevo code/work0132, runnerc52391e0/baseplanc65ed776:
UNA ejecución terminóexit0/statusdb_restored. Imagen769aa… y dump6c3b… idénticos;
no fetch/load adicional. Gate+proof duradero precedieron bootstrap/SQL; límites
kernel1GiB/swap0/.5CPU/pids128/rednone/rootfsRO/User999:999/mapping correctos.
Conteos assets31595/photos10803/pics20792/content_sha110803/path_sha120792.
Owncontainer c920ccf0f843 parado, lectura runningfalse/exit0/OOMfalse,
cleanup_errors=[]; MemAvailable25.805.119.488,SwapFree16.771.444.736 sin cambio,
disco274.693.378.048, aggregateinput+work1.943.101.440B, sin blockers.
Kernelproof1000B SHA<REDACTED>;
result872B SHA<REDACTED>;
restorelog9871B SHA<REDACTED>.
Todos privadosUID1000/600 y preservados en work0132. database_restored=true;
restore_complete globalfalse/originals_verifiedfalse/coherence_verifiedfalse:
no se acredita restauración completa Immich ni originales. Intentos anteriores
conservados, sin podas ni retry automático.
Productor natural20 leído una vez01:31:16+02: final ausente, temporal58.982.400B, pg-dumps activo y RunWisp systemunit active/running. PENDING, sin hash/export ni trigger/retryloop. Publisher diario continúa OFF hasta validación final y revisión.
Manifiesto privado de referencias y productor natural20¶
Assembler fuente publicada e5ce2e7, revisión16tests sintéticos: primera lectura falló cerrada sin output por una línea ajena aasset>1MiB. Diagnóstico acotado confirmó in_assetfalse/is_COPYprefixfalse; corrección revisada descarta únicamente esas líneas por chunks1MiB+1, manteniendo SHA/CRC completos,8GiB/300s y límites estrictos sobre asset/COPY/EOF. No se ampliaron límites ni se leyeron fotos.
UNA ejecución corregida local produjo NUEVO manifiesto privado0600 en
~/.local/state/immich-recovery-references/20261020-0144/references.ndjson
(parent0700), sin alterar dump0055. DumpSHA6c3b…/CRC/identidad antes-después PASS.
Referencias31595 (photos10803,pics20792), únicasU31595, directoriosD10266;
operaciones metadata estimadas4D+U+64=72723≤80000. NDJSON4219168B,
SHA256<REDACTED>;
bodySHA256<REDACTED>.
Se descartó1línea ajena de5047430bytes. Rutas/filenames sólo dentro del artefacto
privado; salidas e informe contienen agregados. NAS filesystem coverage pendiente.
Checker fuent
Segunda lectura metadata natural autorizada01:41:05+02: dump20final existe, regularUID1000/mode0600/nlink1,183629054bytes, mtime01:31:41.053609+02; temporales0, productorPIDs[], RunWispactive/runningmonxasPID830. Sin contenido/hash/export/trigger/retryloop. Productor natural final/frescura metadata PASS, sin acreditar aún CRC del dump20 ni su copia externa. Publisher no se activa por este agente y conserva condición de revisiónCAS del coordinador.
Cobertura metadata NAS31595: PASS y publicación automática habilitada¶
Tras publicar8d88baf y reviewsRoot+maint, UNA ejecución del bridge96464a0 con checker e6c2d7 y manifiesto0144pinned terminóexit0/statusmetadata_match. ASKPASSforce autenticó UID1026 directo, sin sudo ni ficheros remotos nuevos; stdinPIPE exacto/EOF separado de autenticación. Shimlocal700 sin secreto/PYc eliminado al salir; recibo local privado0600/fsync. No fotos abiertas ni NASwrites.
coverage_complete=true, processed_references31595/pending0/unique31595, root_changed=false tras reanchor final. Photos10803 y pics20792: todos archivos regulares, no vacíos y propietario esperado. Missing/symlink/unexpected_type/ unexpected_uid/empty_file/unavailable=0 en ambos grupos. 72461 operaciones metadata≤80000, ritmo≤100/s, peak_owned_fds8≤60; 900s NAS/1000s transporte. Manifiesto3bffd1ff…/bodyb409bb2e…/dump6c3b… idénticos. No hubo retry ni relajación de límites. content_verified=false y coherence_verified=false: existencia/tipo/propiedad no prueban todos los bytes ni restauración completa Immich.
Recibo local1340bytes bajo
~/.local/state/immich-recovery-references/20261020-check0149/receipt.json,
SHA256<REDACTED>.
Candidatos de originales, todavía sin leer sus archivos¶
Una ejecución local sourcecb72a5f releyó exclusivamente dump0055SHA/CRC/identidad
PASS y produjo manifest idéntico más candidatos privados en NUEVOstage0158:
library0/upload100, JSON0600 SHA256
<REDACTED>.
Contienen sólo rutas upload y checksums SHA1 del dump para futura selección;
no fotos leídas/copias/stat adicionales ejecutados. Las muestras históricas3encoded-video
siguen acreditando derivados; no se sustituyen por originales sin ensayo de bytes.
Estado actual de la publicación diaria¶
El coordinador habilitó el flag en fuente e4d4cfb y runtime RunWisp por CAS:
configSHA256<REDACTED>,
backend/helper hashes intactos,19jobs/otros18intactos, reloadrc0.
RPC01:48:59+02 healthytrue/schedulingtrue/config_stalefalse/TZEuropeMadrid;
originals_backup siguiente11:10. Último estado613875… intacto y rollback privado
~/runwisp/rollbacks/dump-publication-q8_uhj04. Esto reemplaza el estadoOFF previo
sin reescribir su historia. Primera publicación automática PENDING11:10,
sin job manual; las5métricas aún reflejan último enabled0 hasta completar la tarea.
Tres originales upload recuperados: PASS02:05CEST¶
Fuentes336d44f, revisión32tests+integración y nativecompileNASPython2.7.18/euid1026 antes de leer originales. UNAejecución real sesión76249 terminóexit0: samples_verified3 / sample_bytes6098264 / sample_content_verifiedtrue. OrigenDBdump19SHA6c3… + NASphotosgeneración20261019/pool100uploadSHA80bf…; SHA1 del dump verificado en origen y en tres relecturaslocales, más SHA256 remoto/local. No son las muestras encoded-video históricas: éstos son tres originalesupload.
Nuevo stage local privado700
~/.local/state/immich-recovery-references/20261020-samples0210:
archive.tar/tresanónimos/proof/receipt600;0210identifica stage, hora real02:05.
ReceiptSHA256<REDACTED>.
Máximo16MiBporarchivo/48MiBtotal,4MiB/s combinado,120sNAS/180sparent,
FDnofollow/pins/reanchor; TARUSTARREG-only verificado y extracciónmanual exclusiva,
sinNASwrites ni cambios de producción. Artefactos y pruebas previas se conservan.
originals_verified=false y coherence_verified=false: resultado sólo de3muestras, no todos los bytes ni restauración completa de Immich. DB-only31.595y cobertura metadata31.595yaPASS son evidencias separadas. Publicación diaria habilitada, primera automática11:10aún pendiente. Detalles y fuentes en informe de originales.
Admisión local de otra generación: fuente del 21oct, sin ejecución real¶
El éxito ordinario del 21oct11:24:34 de la publicación y la copia retomada
20261020 está registrado en el ciclo canónico.
No convierte las pruebas anteriores del dump19/SHA6c3b… y originales20261019
en pruebas de20. El manifiesto privado anterior sigue en
~/.local/state/immich-recovery-references/20261020-0144/references.ndjson,
SHA3bffd1ff…; la fecha del directorio identifica el ensayo, no otra generación.
El assembler existente immich-recovery-reference-manifest.py incorpora una
entrada local explícita para otra publicación, conservando su CLI histórico
fijado a19. No se ha usado con ningún dump real nuevo. La entrada nueva exige
juntos --publication-manifest, --publication-sha256, --expected-photos y
--expected-pics, además de --dump y --output. Los dos recuentos son el
contrato de revisión suministrado por el operador: no se obtienen del propio
manifiesto ni se calculan automáticamente para hacer pasar la comparación.
No son, por sí solos, una prueba independiente de coherencia o de contenido.
La revisión debe dejar constancia de qué evidencia justifica esos valores;
no reutilizar10803/20792 por comodidad para otra generación.
El modo nuevo realiza únicamente estas comprobaciones/preparación locales:
- Exige archivos privados, regulares, propios, sin symlinks/hardlinks y padres privados; comprueba el SHA explícito del manifiesto de publicación.
- Reutiliza
immich-dump-publisher.py::validate_manifest, sin reconstruir otra receta de identidad. Exige formato2: su identidad liga todos los campos, incluidas las referencias de originales; formato1 no se admite aquí. - Requiere exactamente contexto
photosypics, ambos con la misma fecha de generación válida. La fecha del dump puede ser distinta: una generación retomada no se renombra al día de publicación. Contextos mixtos o ausentes se rechazan; este cambio no resuelve su soporte. - Comprueba nombre, tamaño y SHA del dump local contra la publicación; consume gzip completo/CRC y el COPY asset con sus guardas existentes, comparando los recuentos con los aportados explícitamente. Revalida la publicación antes de escribir el resultado exclusivo0600 con fsync.
- Genera referencias v2 ligadas al SHA del manifiesto de publicación y a su
identidad inmutable.
original_generationssigue siendo contexto del publisher: no prueba presencia, hashes de bytes ni coherencia DB/originales.
Se conservan35.000filas,16MiB de manifiesto,8GiB expandidos,300s y80.000operaciones
metadata estimadas. El publisher valida además su límite existente2GiB para el
dump. Exceder un presupuesto provoca rechazo; no se amplía para admitir20.
El modo no descarga archivos, consulta NAS, restaura SQL, crea contenedores ni
arranca Immich. Sus resultados declaran content_verified=false,
coherence_verified=false, database_restored=false y restore_complete=false.
El checker y bridge de referencias y los helpers de muestras siguen fijados al ensayo19. No se modificaron sus constantes/hashes/pins para aceptar el resultado nuevo: el checker histórico rechaza v2 antes de acceder a originales. No enviar un manifiesto20 por el bridge19 ni interpretar ese rechazo como fallo de los backups. Parametrizar el consumidor remoto exige su revisión independiente con pins actuales, los mismos límites y un contrato que valide toda la cadena.
Próximo resultado real, todavía pendiente: adquirir de forma autorizada los
inputs locales exactos de la publicación20 y el contrato de recuentos revisado,
preparar sus referencias, y después admitir por separado verificación de todos
los originales y una recuperación aislada dimensionada. Siguen faltando hashes
de todos los uploads, SHA256 independiente de externos con SHA1 de ruta, tamaño
real del dataset temporal y ensayo funcional aislado. No repetir DB-only como
si cerrase esos pendientes. complete_recovery_spec: false no cambia.
La validación de esta fuente usa únicamente gzip/COPY, publicaciones y árboles sintéticos locales. Incluye generación nueva, publicación cambiada durante parsing, CRC corrupto, contexto incompleto/mixto, schema/identidad/hash erróneos, recuentos inválidos, privacidad y CLI parcial, más rechazo de v2 por el checker histórico. No acredita que los inputs20 ya estén disponibles o verificados.