Tutorial

Docker Compose en producción: checklist de 10 puntos

Despliegue8 min de lectura10 pasos

Un archivo docker-compose.yml que funciona en su equipo no sobrevive tal cual a la producción. Reinicio tras un reboot, límites de recursos, secretos, rotación de logs: son otros tantos ajustes ausentes por defecto que provocan averías silenciosas una vez el servicio está expuesto. Esta checklist reúne los 10 parámetros que hay que controlar antes de desplegar su primera stack Compose en un VPS. Cada uno cabe en unas pocas líneas de YAML y le ahorra una incidencia nocturna.

Contenido· Por qué una checklist antes de producción1/10
  1. 01Por qué una checklist antes de producción
  2. 02Los 10 puntos de un vistazo
  3. 03Requisitos previos
  4. 04Los 10 pasos en detalle
  5. 05Valores por defecto de dev frente a ajustes de prod
  6. 06Solución de problemas
  7. 07CVE-2026-17106 (CopyEscape): actualizar Docker Engine
  8. 08Gestión de secretos de Docker: rotación sin downtime
  9. 09Hacer copias de seguridad de los volúmenes sin corrupción
  10. 10Conclusión

Por qué una checklist antes de producción

Docker Compose se diseñó para el desarrollo: sus valores por defecto priorizan la simplicidad, no la robustez. Un contenedor no se reinicia tras un reinicio del host, sus logs crecen sin límite, puede consumir toda la RAM de la máquina y escucha en todas las interfaces de red. En desarrollo, ninguno de estos comportamientos supone un problema, porque usted relanza la stack a mano varias veces al día. En producción, esos ajustes ausentes se convierten en incidentes: disco lleno a las tres de la madrugada, base de datos perdida tras un docker compose down, servicio inaccesible tras un corte de corriente. La buena noticia: endurecer una stack Compose no exige reescribirla, solo una decena de añadidos concretos. Repase cada punto de esta lista antes de publicar y su servicio aguantará la carga y los reinicios sin vigilancia constante.

Los 10 puntos de un vistazo

  • restart: unless-stopped — el contenedor se reinicia tras un reinicio del host o un fallo
  • healthcheck — Docker detecta un contenedor bloqueado y permite reinicios progresivos
  • límites de CPU/memoria — un servicio desbocado ya no puede asfixiar a sus vecinos
  • secretos vía .env o Docker secrets — nunca una contraseña en claro en el archivo Compose
  • volúmenes con nombre — los datos sobreviven a un docker compose down
  • rotación de logsmax-size y max-file impiden que el disco se llene
  • aislamiento de red — separe frontend y backend, no exponga todo en el bridge por defecto
  • binding de puertos127.0.0.1:PORT detrás de un reverse proxy, no 0.0.0.0
  • tags de imagen fijados — una versión o un digest, nunca latest
  • depends_on con condiciónservice_healthy evita las carreras en el arranque

Requisitos previos

Antes de aplicar esta checklist, asegúrese de disponer de un VPS con Docker Engine y el plugin Compose v2 instalados (el comando es docker compose, sin guion, desde 2022). Compruebe la versión con docker compose version: la sintaxis deploy.resources fuera de Swarm exige Compose v2. Coloque su archivo en una carpeta de proyecto dedicada, por ejemplo /opt/monapp, con un archivo .env al lado y permisos restringidos (chmod 600 .env). Prevea un reverse proxy por delante — Traefik, Caddy o Nginx — porque varios ajustes, en particular el binding de puertos, dan por supuesto que el tráfico público nunca llega directamente a sus contenedores. Por último, mantenga una copia de su archivo Compose bajo control de versiones.

Los 10 pasos en detalle

  1. 1. Política de reinicio

    Añada restart: unless-stopped a cada servicio. El contenedor se reinicia tras un fallo o un reinicio del host, pero permanece detenido si usted lo paró voluntariamente. Evite restart: always, que relanzaría incluso un contenedor que quería dejar parado.

  2. 2. Healthcheck

    Declare un bloque healthcheck: con un test (por ejemplo curl -f http://localhost:8080/health || exit 1), un interval, un timeout y unos retries. Docker marca entonces el contenedor como healthy o unhealthy, lo que permite a los demás servicios reaccionar ante un bloqueo.

  3. 3. Límites de recursos

    En deploy.resources.limits, fije cpus y memory (por ejemplo memory: 512M). Sin límite, un servicio con una fuga puede consumir toda la RAM y hacer que el OOM killer mate a los demás. Añada también reservations para garantizar un mínimo.

  4. 4. Secretos fuera del archivo

    Nunca ponga una contraseña en claro en el YAML. Refiéralas mediante env_file: .env o ${VARIABLE}, o utilice el mecanismo secrets: de Docker, que monta el secreto como archivo dentro del contenedor. Añada .env a su .gitignore.

  5. 5. Volúmenes con nombre

    Declare sus datos en volúmenes con nombre y con un driver explícito, en lugar de un bind-mount anónimo. Un volumen con nombre sobrevive a docker compose down; solo down -v lo borra. Documente cada volumen para saber de qué hace copia de seguridad.

  6. 6. Rotación de logs

    Añada un bloque logging: con driver: json-file y las opciones max-size: "10m" y max-file: "3". Sin ello, los logs de un contenedor hablador llenan el disco hasta provocar la caída. Aplíquelo a cada servicio.

  7. 7. Aislamiento de red

    Cree redes con nombre — una frontend para lo que está expuesto, una backend para la base de datos — y conecte cada servicio solo a las redes que necesita. Su base de datos únicamente debe ser accesible desde la aplicación, nunca desde el bridge por defecto compartido.

  8. 8. Binding de puertos

    Detrás de un reverse proxy, publique en 127.0.0.1:8080:8080 y no en 8080:8080 (que equivale a 0.0.0.0). De lo contrario, el puerto sigue accesible desde Internet pese al proxy, esquivando sus reglas de TLS y de autenticación.

  9. 9. Tags de imagen fijados

    Sustituya image: postgres:latest por una versión precisa (postgres:16.3) o, mejor, por un digest (postgres@sha256:...). latest cambia sin avisar y hace que sus despliegues no sean reproducibles. Combínelo con pull_policy: missing para un comportamiento previsible.

  10. 10. Orden de arranque

    Utilice depends_on con condition: service_healthy para que un servicio no espere solo al lanzamiento, sino a la disponibilidad real de su dependencia. Esto supone un healthcheck en el servicio dependiente (paso 2) y elimina las carreras en el arranque.

Valores por defecto de dev frente a ajustes de prod

Desplace la tabla

ParámetroPor defecto en devRecomendado en prod
restartnounless-stopped
healthcheckausentedefinido con interval y retries
memoriasin límitelimit fijado (p. ej. 512M)
secretosen claro posible.env o Docker secrets
volúmenesanónimoscon nombre y con driver
logssin límitemax-size + max-file
redbridge por defectofrontend / backend separados
puertos0.0.0.0127.0.0.1 detrás de proxy
imagenlatestversión o digest fijado
depends_onsolo arranquecondition: service_healthy

Pruebe siempre su stack endurecida en local antes de llevarla a producción: lance docker compose config para validar la sintaxis, después docker compose up, y simule un reinicio con docker compose restart. Compruebe que los contenedores vuelven a estar healthy y que los datos persisten tras un down seguido de un up.

Solución de problemas

Si un contenedor se queda bloqueado en estado starting, su healthcheck está fallando: pruebe el comando test a mano con docker compose exec service sh y compruebe que devuelve 0. Un servicio que se reinicia en bucle (Restarting) suele esconder un error en el arranque — consulte docker compose logs -f service. Si deploy.resources.limits parece ignorarse, recuerde que en Compose v2 fuera de Swarm los límites sí se aplican, pero las reservations solo lo hacen en modo Swarm. Un puerto que sigue accesible pese a 127.0.0.1 suele señalar un cortafuegos ausente o una regla de Docker que esquiva UFW — compruébelo con ss -tlnp. Por último, si un docker compose down ha borrado sus datos, casi siempre es porque quedaba un -v de más o porque el volumen era anónimo en lugar de tener nombre.

CVE-2026-17106 (CopyEscape): actualizar Docker Engine

CVE-2026-17106, bautizada CopyEscape, es una race condition en docker cp divulgada el 10 de agosto de 2026. Un contenedor no confiable puede producir un archivo tar incoherente que sigue un enlace simbólico fuera del destino, lo que acaba sobrescribiendo un archivo arbitrario en el host — incluido el binario runc. La superficie: todo VPS que ejecute docker cp desde un contenedor cuyo contenido usted no controla. La corrección está disponible en Docker Engine ≥ 29.7.2 y Docker Desktop ≥ 4.86.0. Compruebe su versión con docker version y actualice antes de exponer un nuevo servicio. Si no puede actualizar de inmediato, evite docker cp desde contenedores no confiables y aplique el principio de mínimo privilegio (--cap-drop ALL).

Gestión de secretos de Docker: rotación sin downtime

Las variables de entorno en claro dentro de un archivo Compose son la primera fuga de secretos en producción: aparecen en docker inspect, en los logs de error y en los volcados de proceso. El mecanismo secrets: de Docker — o un gestor externo como Vault o Infisical — monta los secretos en forma de archivos en /run/secrets/, fuera del alcance de inspect. Para una rotación sin downtime, el método recomendado consiste en versionar el secreto (crear un nuevo secreto db_password_v2 en paralelo al v1), actualizar el servicio para que lea v2, redesplegar en rolling update (docker compose up -d --no-deps service) y después eliminar v1 una vez validado el despliegue. Ninguna interrupción de servicio, ninguna ventana de secreto expuesto entre las dos versiones.

Hacer copias de seguridad de los volúmenes sin corrupción

Copiar los archivos de un volumen PostgreSQL o MySQL en caliente con rsync o tar produce casi con toda seguridad una copia de seguridad corrupta: el motor escribe de forma continua durante la copia y las páginas de datos se capturan en puntos de control distintos. La regla es hacer siempre un dump SQL antes del snapshot del volumen: pg_dump o mysqldump producen un estado coherente que usted puede archivar o transferir. Para automatizar este enfoque en un VPS con Docker, herramientas como Restic y Offen Docker Backup orquestan la congelación de la base de datos, el dump SQL, el snapshot cifrado y el envío a un almacenamiento remoto. Documente cada volumen con nombre (paso 5 de la checklist) y asócielo a una estrategia de restauración probada: una copia de seguridad sin prueba de restauración es un dato no respaldado.

Conclusión

Estos diez ajustes convierten un archivo Compose de desarrollo en una stack de producción capaz de sobrevivir a los reinicios, a los picos de carga y a las noches sin vigilancia. Ninguno exige una herramienta adicional: todo cabe en el YAML que usted ya tiene. Adquiera la costumbre de recorrer esta checklist antes de cada puesta en línea, idealmente en forma de revisión de docker compose config integrada en su despliegue. Una vez asentados estos cimientos, puede añadir un reverse proxy como Traefik o Caddy, o una capa de orquestación como Coolify, con total confianza.

Despliegue su stack Compose en producción

Un VPS ServOrbit le da el acceso root, la RAM y el control de red necesarios para hacer funcionar una stack Docker Compose endurecida. Elija su configuración y despliegue en unos minutos.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva