Introducción
The Riverside Archive puede conectarse a PostgreSQL, pero su sitio web de catálogo se inicia antes de terminar la importación única. Añade la dependencia funcional que falta: el catálogo solo puede abrirse tras una importación correcta y debe permanecer sin iniciar si la entrada es inválida.
Completa primero Wait for the Archive Database o conoce su YAML, comprobaciones de salud, proyectos Compose, registros y reinicio limitado con datos nuevos. No se requiere SQL ni programación de aplicaciones. Este laboratorio prepara una base de datos, datos fuente y referencia independientes; no necesita archivos de la VM anterior. La base de datos inicial proporcionada ya tiene la comprobación de salud TCP final correcta.
Usa Workstation, Reference Archive, Your Archive y Collection Notes. Los registros son sintéticos. Las demoras declaradas muestran estados didácticos; la disponibilidad real y los estados de salida de importación gobiernan el resultado. Calcula unos 45 minutos, incluidos la lectura y los errores habituales; es una estimación del autor.
Abre solo después de una importación correcta
En este paso, condicionarás el catálogo a una importación terminada, demostrarás que un fallo real lo bloquea y recuperarás el funcionamiento con la entrada original.
Compara la disponibilidad de base de datos y de la aplicación
Empieza en Reference Archive. Busca Market morning, abre ambos registros coincidentes y descarga sus distintas transcripciones. Vuelve con Back to collection e inspecciona Ferry voices. Your Archive no está disponible, mientras Collection Notes ya puede explicar la colección sin leer filas importadas.
Cambia a Workstation, que comienza en /home/labex/project/archive-opening:
cd /home/labex/project/archive-opening
cat compose.yaml
docker compose -p archive ps -a
docker compose -p archive logs importer catalog
La base de datos pasa a estar saludable y el importador termina su trabajo real. Pero el catálogo intentó leer la tabla demasiado pronto y terminó con un error como relation "entries" does not exist. Una base de datos que acepta conexiones no significa que existan los datos de la aplicación. El sitio web carece deliberadamente de reintentos ocultos al iniciar, por lo que la dependencia debe expresar este requisito.
Este entorno usa los mismos cuatro roles y relaciones de puertos que el laboratorio guiado anterior. db ya tiene una comprobación de salud TCP e importer espera service_healthy. El problema restante es catalog.depends_on.importer.condition: service_started. Permite iniciar el catálogo en cuanto empieza el proceso de importación, cuando aún faltan su demora didáctica declarada de seis segundos y la transacción real.
Condiciona el consumidor real
Sustituye esa condición por service_completed_successfully. Comprueba la finalización correcta, no simplemente que el proceso haya terminado: un estado de importación distinto de cero debe bloquear el catálogo. Que un importador único termine Exited 0 es correcto y no debe mantenerse Running ni recibir una política de reinicio interminable. Conserva welcome independiente porque sus notas estáticas de colección no necesitan una tabla importada.
El here-document literal completo conserva todos los ajustes proporcionados y la comprobación de salud existente de base de datos. Como en el laboratorio anterior, > sustituye solo compose.yaml; el marcador entre comillas mantiene literal el contenido:
cat > compose.yaml <<'COMPOSE'
services:
db:
image: dk04-postgres:16
environment:
POSTGRES_USER: archivist
POSTGRES_PASSWORD: training-archive
POSTGRES_DB: archive
TRAINING_DB_DELAY: "8"
volumes:
- data:/var/lib/postgresql/data
- ./scenario/slow-init.sh:/docker-entrypoint-initdb.d/10-training-delay.sh:ro
healthcheck:
test: ["CMD", "pg_isready", "-h", "127.0.0.1", "-U", "archivist", "-d", "archive"]
interval: 1s
timeout: 2s
retries: 40
importer:
image: dk04-archive:1
entrypoint: ["python3", "-B", "/app/importer.py"]
environment:
PGHOST: db
PGUSER: archivist
PGPASSWORD: training-archive
PGDATABASE: archive
TRAINING_IMPORT_DELAY: "6"
volumes:
- ./scenario:/scenario:ro
depends_on:
db:
condition: service_healthy
catalog:
image: dk04-archive:1
entrypoint: ["python3", "-B", "/app/archive.py", "catalog"]
environment:
PGHOST: db
PGUSER: archivist
PGPASSWORD: training-archive
PGDATABASE: archive
ARCHIVE_TITLE: "The Riverside Archive"
ports:
- "8090:8080"
depends_on:
importer:
condition: service_completed_successfully
welcome:
image: dk04-archive:1
entrypoint: ["python3", "-B", "/app/archive.py", "notes"]
environment:
ARCHIVE_TITLE: "The Riverside Archive"
ports:
- "8091:8080"
volumes:
data:
labels:
labex.course: dk04
COMPOSE
docker compose -p archive config
Si falla el análisis, corrige la sangría indicada usando el bloque mostrado antes de iniciar servicios. Conserva sin cambios la aplicación, el importador, el CSV, la autenticación y los puertos proporcionados.
Demuestra que una importación fallida no puede abrir el catálogo
compose.bad.yaml es un archivo de sustitución proporcionado que dirige el importador a otro CSV inválido. Su ID de registro contiene texto donde la tabla real PostgreSQL requiere un entero. El importador usa una transacción real y propaga el estado distinto de cero de la base de datos; no finge éxito. El escenario válido original permanece intacto.
Primero inspecciona el volumen del alumno y confirma las etiquetas de proyecto y curso como aprendiste antes:
docker volume inspect archive_data --format '{{json .Labels}}'
Espera com.docker.compose.project: archive y labex.course: dk04. El siguiente comando elimina deliberadamente solo los datos de práctica desechables de este proyecto para que la prueba de entrada incorrecta no pueda aprovechar una tabla importada previamente:
docker compose -p archive down --volumes
Dos argumentos -f combinan la configuración normal y esta sustitución proporcionada, en ese orden. Se espera deliberadamente que el siguiente inicio falle con estado nativo 1 porque el importador termina con un valor distinto de cero:
docker compose -f compose.yaml -f compose.bad.yaml -p archive up -d --pull never --no-build
docker compose -f compose.yaml -f compose.bad.yaml -p archive ps -a
docker compose -f compose.yaml -f compose.bad.yaml -p archive logs importer
Lee el error de entero inválido. La base de datos puede seguir saludable, el importador está Exited con un código distinto de cero y el catálogo debe estar Created, sin haberse iniciado nunca. El servicio de bienvenida sigue funcionando. Un catálogo que se inicia y después falla es un resultado diferente: se le permitió consumir una importación fallida.
Cambia a Your Archive y recarga: no debe haber ningún catálogo disponible. Cambia a Collection Notes: su página independiente sigue funcionando. Son estados de servicios reales, no una presentación de éxito preparada.
Recupera con la entrada válida y usa los registros
Cambia a Workstation. Verifica otra vez las mismas etiquetas del volumen del curso antes de limpiar:
docker volume inspect archive_data --format '{{json .Labels}}'
docker compose -f compose.yaml -f compose.bad.yaml -p archive down --volumes
Inicia sin la sustitución para volver a la entrada válida original. Este nuevo almacén de datos debe importar desde cero:
docker compose -p archive up -d --pull never --no-build
docker compose -p archive ps -a
docker compose -p archive logs importer
Espera base de datos Healthy, importador Exited 0 y ambos roles web Running. Ante un error habitual de ruta ausente o YAML, vuelve al directorio de trabajo indicado, lee compose config o el registro del servicio, corrige la configuración editable y repite solo el reinicio limitado a este curso. No edites filas fuente, ocultes errores ni reinicies la VM para disimular el problema.
Cambia a Your Archive y recarga. Busca Market morning: deben aparecer dos registros con distintos ID, años, categorías e historias. Abre cada uno y usa Download transcript, volviendo con Back to collection. Busca Ferry, abre Ferry voices y descarga su transcripción. Borra la búsqueda para mostrar los cuatro registros. Inspecciona también The shared garden y su descarga. Una URL de registro desconocida debe mostrar Record not found, distinto de un fallo de conexión o un catálogo no disponible.
El catálogo completo conserva las cuatro identidades, incluidos los dos registros Market morning distintos:

Cambia a Collection Notes: su página independiente de bienvenida debe seguir disponible. Reference Archive debe seguir ofreciendo la colección completa original. Mantén tu archivo final en ejecución. Las comprobaciones observan primero tu base de datos real, la importación terminada y los resultados completos del funcionamiento. Después ejecutan tus opciones de salud y dependencia sin modificar en almacenes nuevos, separados y desechables, con distintas demoras didácticas declaradas y una muestra de importación inválida. Esos escenarios de prueba nunca inicializan ni reparan tu archivo real. Otra prueba aislada ejecuta tu comando de salud sin modificar sin ningún servidor de base de datos; debe rechazar ese destino no disponible.
Resumen
Separaste una base de datos utilizable de un catálogo producido correctamente. El consumidor ahora espera el estado de salida 0 del importador, permanece sin iniciar tras un fallo real de importación y abre un catálogo nuevo completo después de restaurar la entrada válida. La página independiente de bienvenida sigue siendo útil durante todo el proceso.



