Bases de datos en Docker | Nicolás Garzón
Texto
Copiar container reemplazable
+ image versionada
+ volume persistente
+ backups externos
+ topología de réplica/failover
→ servicio de datos operableEl error más común es aplicar el modelo stateless de una API a un motor stateful. Reiniciar o recrear un proceso es sencillo; conservar consistencia, disponibilidad y capacidad de recuperación exige procedimientos propios del motor.
versión del motor explícita;
entorno reproducible;
aislamiento de dependencias;
configuración declarativa;
desarrollo e integración local rápidos;
lifecycle uniforme para procesos;
redes y mounts definidos.
Docker no aporta automáticamente:
alta disponibilidad;
replicación;
backup;
point-in-time recovery;
failover;
cifrado;
upgrade compatible;
monitoreo del motor;
garantía de durabilidad del host.
YAML
Copiar services :
db :
image : postgres: 17
environment :
POSTGRES_USER : app
POSTGRES_DB : app
POSTGRES_PASSWORD_FILE : /run/secrets/db_password
secrets :
- db_password
volumes :
- db- data: /var/lib/postgresql/data
networks : [ data]
healthcheck :
test : [ "CMD-SHELL" , "pg_isready -U app -d app" ]
interval : 5s
timeout : 3s
retries : 10
stop_grace_period : 60s
volumes :
db-data :
networks :
data :
internal : true
secrets :
db_password :
file : ./secrets/db_password.txtEl ejemplo sirve para desarrollo y un single host controlado. No demuestra HA ni backup.
La ruta del mount debe coincidir con la versión e imagen utilizadas.
Texto
Copiar volume correcto
→ directorio real del motor
→ datos sobreviven al containerMontar una ruta equivocada produce una falsa sensación de persistencia. Verifica:
Bash
Copiar docker inspect db --format '{{json .Mounts}}'
docker volume inspect project_db-dataImágenes oficiales suelen ejecutar scripts de inicialización únicamente cuando el directorio de datos está vacío.
Texto
Copiar volume vacío
→ entrypoint inicializa cluster
→ ejecuta scripts iniciales
volume existente
→ scripts no vuelven a ejecutarsePor eso no son un sistema de migrations recurrentes.
crear estructura inicial en desarrollo;
usuarios o bases iniciales;
fixtures efímeros.
upgrades de producción;
cambios repetibles de schema;
tareas que deben ejecutarse en cada deploy.
Las migrations deben ser:
versionadas;
ordenadas;
observables;
idempotentes cuando aplique;
compatibles con despliegues graduales;
ejecutadas una vez de forma coordinada.
YAML
Copiar services :
migrate :
image : registry.example.com/api@sha256: ...
command : [ "npm" , "run" , "migrate" ]
depends_on :
db :
condition : service_healthy
restart : "no" No ejecutes migrations destructivas simultáneamente desde cada réplica de la API.
Para despliegues sin downtime:
Texto
Copiar 1. expand: agregar nueva columna/tabla compatible
2. desplegar código que soporta viejo y nuevo modelo
3. migrar/backfill
4. cambiar lecturas/escrituras
5. contract: retirar estructura antiguaUna migration que renombra o elimina una columna antes de actualizar todas las instancias puede romper el rollout.
Un volume local sobrevive al container, pero normalmente no a la pérdida completa del host o disco.
Texto
Copiar host A / volume db-data
≠
host B / volume db-dataEl mismo nombre en otro host no contiene automáticamente los mismos datos.
Para varios nodos necesitas:
replicación del motor;
almacenamiento compartido soportado;
servicio administrado;
estrategia explícita de failover.
Persistencia no es backup.
Un backup protege frente a:
eliminación accidental;
corrupción;
bug de aplicación;
fallo de disco;
ransomware;
upgrade defectuoso;
pérdida del host.
Bash
Copiar docker exec db pg_dump -U app -Fc app > backup.dump
portable entre ciertos entornos;
permite restauración lógica;
inspeccionable mediante tooling.
puede tardar;
consume CPU/I/O;
restore puede ser lento;
no siempre conserva todo el estado del cluster.
Pueden ser más rápidos o permitir PITR, pero deben coordinarse con el motor. Copiar archivos activos arbitrariamente puede producir una copia inconsistente.
Un backup solo es válido después de restaurarlo.
crea entorno aislado;
restaura en volume nuevo;
arranca la versión compatible;
valida integridad;
ejecuta consultas funcionales;
verifica usuarios/extensiones;
mide RTO;
registra evidencia.
Bash
Copiar docker volume create db-restore
RPO: cuánto dato puedes perder;
RTO: cuánto tardas en recuperar.
Texto
Copiar postgres:14 → postgres:17no es equivalente a actualizar una API. El formato del directorio puede ser incompatible.
Antes de una versión mayor:
lee procedimiento oficial;
inventaría extensiones;
crea backup probado;
ensaya con copia;
mide downtime;
define rollback;
comprueba clientes y drivers;
revisa cambios de configuración.
dump/restore;
herramientas de upgrade in-place;
réplica lógica;
migración blue/green.
No asumas que volver al tag anterior funciona después de modificar el formato.
Una database debe recibir la señal y disponer de tiempo para checkpoint y cierre.
Bash
Copiar docker stop --time 60 dbEvita docker kill salvo incidente controlado. El motor suele poder recuperarse mediante WAL/journal, pero eso no elimina riesgo ni tiempo de recovery.
pg_isready indica disponibilidad del servidor, no necesariamente:
migrations completas;
espacio suficiente;
replicas sincronizadas;
consultas dentro del SLO;
permisos correctos para la app.
health básico del proceso;
métricas del motor;
checks funcionales controlados;
alertas de capacidad y replicación.
memory buffers/cache;
CPU;
I/O;
shared memory;
file descriptors;
connections;
temporary disk.
Un límite arbitrario puede causar OOM o degradar consultas.
active connections;
cache hit ratio;
locks;
slow queries;
replication lag;
WAL/binlog growth;
disk latency;
filesystem capacity;
inodes;
checkpoint duration.
No dimensionar solo con datos actuales. Incluye:
índices;
WAL/binlogs;
temporary files;
vacuum/compaction;
upgrades;
restore;
snapshots;
crecimiento esperado.
Disco lleno puede dejar el motor no disponible o comprometer durabilidad.
La database normalmente debe permanecer en una network interna.
Texto
Copiar API → db:5432
host/internet ✕ dbNo publiques el puerto por comodidad. Para administración usa:
acceso local restringido;
VPN;
bastion;
tunnel;
tooling de plataforma.
La network no reemplaza password, TLS ni roles mínimos.
Evita usar superuser desde la aplicación.
Crea identidades separadas:
runtime app;
migrations;
backup;
monitoring;
administration.
Cada una con permisos mínimos. Rotar el password puede requerir compatibilidad temporal y recreación de pools.
Dentro de una red privada, TLS puede seguir siendo necesario si:
el host es compartido;
existe tráfico multi-host;
hay requisitos regulatorios;
la red no es plenamente confiable.
Gestiona certificados, hostname verification y rotación. No desactives TLS para solucionar errores de confianza.
Texto
Copiar restart policy
→ recupera crash del proceso
host perdido;
disk failure;
corrupción;
mantenimiento;
pérdida de zona;
split brain;
failover.
HA requiere topología del motor y un mecanismo para elegir/descubrir el primary.
Antes de desplegar réplicas define:
consistencia;
lag aceptable;
routing de lecturas;
failover;
fencing;
backups;
monitorización;
recuperación del nodo antiguo.
Montar el mismo volume en dos instancias no crea un cluster y puede corromper datos.
Servicio administrado puede aportar:
backups;
patching;
HA;
monitoring;
failover;
soporte.
precio;
menor control;
límites del proveedor;
egress/lock-in.
Operar en Docker es razonable para desarrollo, CI, edge o equipos con capacidad real de DBA/infra. Para producción crítica, compara el coste operativo completo.
project name cambió;
se creó otro volume;
path destino incorrecto;
docker compose down -v;
anonymous volume;
mount ocultó datos;
container escribía en writable layer.
Bash
Copiar docker compose ls
docker volume ls
docker inspect db --format '{{json .Mounts}}'
docker volume inspect volume-nameNo ejecutes prune antes de identificar los volumes.
El volume ya está inicializado. Usa migration explícita.
Puede fallar por formato, extensión o encoding.
No protege frente a pérdida del host.
La aplicación necesita conocer consistencia eventual.
El límite incluye buffers y procesos del motor; ajusta queries y configuración.
Conserva backup y prueba rollback antes.
Persistencia en ruta equivocada.
El host sigue siendo punto único de fallo.
Docker empaqueta el motor; no administra la integridad del negocio.
El volume sobrevive al container, no necesariamente al host.
Init scripts no reemplazan migrations.
Backup sin restore probado es una esperanza.
Upgrades mayores requieren procedimiento específico.
Restart policy no es alta disponibilidad.
Comprueba lo aprendido
Diseña backup, restore y PITR para PostgreSQL.
¿Por qué los init scripts no sirven como migrations permanentes?
Planifica un upgrade de versión mayor con rollback.
Explica por qué compartir un volume entre dos primaries es peligroso.
Decide entre database administrada y container propio para un SaaS.
CI/CD con Docker , donde el artefacto se construye una vez, se prueba por digest y se promociona sin reconstrucciones ocultas.