Saltar al contenido

Capítulo 13 de 13

Proyecto · fallos, copias y publicación

Demostrar reconexión, persistencia y restauración y preparar el paso del catálogo a un servidor con HTTPS.

#El éxito incluye poder recuperarse

Esta tercera parte continúa con el catálogo conectado y al menos un libro insertado. Mantén la misma carpeta y proyecto de Compose. Vas a distinguir tres escenarios: dependencia temporalmente caída, aplicación reemplazada y datos restaurados en otra instancia. No son la misma prueba.

#Fase 8 · Hacer fallar una dependencia y recuperarla

docker compose stop db
curl --max-time 10 -i http://127.0.0.1:8080/health/live
curl --max-time 10 -i http://127.0.0.1:8080/health/ready
curl --max-time 10 -i http://127.0.0.1:8080/libros

Espera 200 en liveness y 503 en las operaciones dependientes de base. El proxy ya estaba arrancado; la condición inicial de Compose no lo detiene por sí sola. La aplicación puede explicar su indisponibilidad sin desaparecer ni esperar infinitamente.

docker compose start db
docker compose exec db pg_isready -h 127.0.0.1 -U postgres -d catalogo

Repite pg_isready hasta ver accepting connections. Solo entonces comprueba la API:

curl --fail --max-time 10 http://127.0.0.1:8080/health/ready
curl --fail http://127.0.0.1:8080/libros

No hay que reiniciar la API: cada petición abre una conexión nueva. Si tu siguiente versión usa un pool, deberá detectar conexiones rotas y renovarlas.

Ahora sustituye solo la API:

docker compose up -d --no-deps --force-recreate --wait api
curl --fail http://127.0.0.1:8080/libros

El libro debe permanecer. El contenedor de API no era su almacenamiento. Puede haber una interrupción breve durante la sustitución; el proyecto no promete alta disponibilidad con una única instancia.

#Fase 9 · Copiar y restaurar datos con evidencia

Primero crea una copia con el administrador, sin terminal interactivo:

docker compose exec -T db pg_dump -U postgres -d catalogo -Fc > backups/catalogo.dump

Comprueba que el comando terminó con éxito. En una automatización, escribe a un temporal y renombra solo si el comando pasa. El dump no incluye el rol y su contraseña; por eso conservamos la definición de roles y secretos por un mecanismo seguro aparte.

Vamos a restaurar en un contenedor y volumen separados que no publican puertos. Esta copia sirve para el ensayo y no sustituye guardar otra fuera del servidor:

docker volume create catalogo-restore-lab
docker run -d --name catalogo-restore-lab \
  -e POSTGRES_USER=postgres -e POSTGRES_DB=catalogo \
  -e POSTGRES_PASSWORD_FILE=/run/secrets/db_password \
  --mount type=bind,src="$(pwd)/secrets/db_password",dst=/run/secrets/db_password,readonly \
  --mount type=bind,src="$(pwd)/secrets/app_password",dst=/run/secrets/app_password,readonly \
  --mount type=bind,src="$(pwd)/init-db.sh",dst=/docker-entrypoint-initdb.d/10-init.sh,readonly \
  --mount type=volume,src=catalogo-restore-lab,dst=/var/lib/postgresql/data \
  postgres:17-alpine
docker exec catalogo-restore-lab pg_isready -h 127.0.0.1 -U postgres -d catalogo

Espera a que acepte TCP. La inicialización crea rol y tabla vacía. Para restaurar el dump completo sobre este destino desechable, limpia sus objetos equivalentes:

docker exec -i catalogo-restore-lab pg_restore \
  -U postgres -d catalogo --clean --if-exists --exit-on-error --no-owner \
  < backups/catalogo.dump
docker exec catalogo-restore-lab psql -U postgres -d catalogo \
  -c 'SET ROLE catalogo; SELECT id, titulo FROM libros ORDER BY id;'

--clean elimina los objetos que va a reconstruir en el destino. Aquí el destino es exclusivamente el laboratorio de restauración; no lo apuntes a tu única base de producción. SET ROLE catalogo comprueba permisos de lectura con el rol de aplicación. Para comprobar también la contraseña y TCP, ejecuta dentro del contenedor:

docker exec catalogo-restore-lab sh -c \
  'PGPASSWORD="$(cat /run/secrets/app_password)" psql -h 127.0.0.1 -U catalogo -d catalogo -c "SELECT count(*) FROM libros;"'

La contraseña no está escrita literalmente en el comando; existe temporalmente en el entorno de psql dentro del contenedor de administración. No actives trazas de shell ni vuelques su entorno. Esperas el mismo número de filas, y tu libro debe estar presente. Eso verifica contenido, rol y autenticación; un archivo .dump con tamaño mayor que cero no lo habría demostrado.

Después elimina solamente la instancia y el volumen de restauración: docker stop catalogo-restore-lab, docker rm catalogo-restore-lab y docker volume rm catalogo-restore-lab. La aplicación principal continúa intacta.

#Fase 10 · Publicar una versión y operarla

Para pasar a un servidor, sigue Despliegue y HTTPS con estos mismos nombres de servicio. Construye y prueba una imagen, publícala en tu registro, fija su digest en APP_IMAGE, conserva el anterior y descarga ese artefacto en el servidor. El archivo Compose de servidor puede omitir build: . porque no necesita código ni herramientas de construcción allí.

Cambia Caddy a tu dominio real y publica únicamente 80/443 del proxy. Lleva los secretos por un canal de administración seguro y prepara copias fuera de la máquina. Verifica por HTTPS lectura, rechazo sin token, escritura y readiness; después mide memoria, logs y tiempo de recuperación.

El proyecto ya muestra contenedores complementarios, datos persistentes, permisos, observación y recuperación. Para crecer, decide qué necesidad apareció: paginar resultados, limitar conexiones con un pool, añadir usuarios en lugar del token compartido o ejecutar una tarea larga en un worker. Introduce cada pieza con su fallo esperado y su comprobación; no porque el diagrama "parezca más de producción".

#Qué queda fuera y por qué

El token compartido es un mecanismo sencillo de administración, no un sistema de cuentas ni permisos por usuario. No hay rate limiting distribuido, búsqueda compleja, backups programados a un proveedor ni despliegue multi-host. Su necesidad depende del servicio que construyas. Lo que sí debes conservar al extenderlo es la separación de permisos, los límites de tiempo, la compatibilidad de migraciones y el ensayo de restauración.

Al terminar la práctica, docker compose down elimina cómputo y redes conservando los volúmenes. docker compose down -v elimina también los datos de este proyecto: úsalo solo si has decidido descartar el laboratorio. Conserva una copia comprobada antes de cualquier operación de eliminación que afecte a datos útiles.

#Fuentes de las piezas que acabas de conectar

    ↑ ↓ para recorrer · Intro para abrir · Ctrl K para buscar