Gestionar Docker Secrets con Compose
Qué cubre este artículo sobre Docker Secrets con Compose
- Qué son Docker Secrets y por qué son más seguros que las variables de entorno.
- Qué métodos existen para gestionar Secrets en Docker Compose.
- Cómo utilizar Secrets externos con Docker Swarm y Compose.
- Cómo usar correctamente archivos .env y qué debes evitar.
- Cuáles son los errores típicos con Secrets en Docker y cómo resolverlos.
Introducción: Docker Secrets explicado de forma clara
Los Secrets son datos confidenciales como contraseñas, claves de API, tokens y certificados. En Docker Compose, estos Secrets deben llegar a los contenedores sin que aparezcan en texto plano en el archivo docker-compose.yml o en la línea de comandos. Docker Secrets es un mecanismo que resuelve esto de forma segura.
Este artículo está dirigido a desarrolladores que usan Docker Compose y quieren gestionar Secrets de manera segura. Deberías entender cómo funciona Docker Compose y qué significa Secret Management. Si te interesa profundizar en seguridad en Docker, encontrarás más información en IRC-Security.de.
¿Por qué necesito Docker Secrets?
Imagina que administras un stack Docker con Nextcloud, PostgreSQL y Ollama. Cada servicio necesita contraseñas: la base de datos del administrador, Nextcloud para la conexión a la BD, Ollama para la API. Si escribes estas contraseñas como variables de entorno en docker-compose.yml, cualquiera que vea el archivo puede leerlas.
Aún peor: las variables de entorno son visibles dentro del contenedor. Cualquiera que acceda al contenedor puede ejecutar env para ver todas las contraseñas. Aparecen en logs, en volcados de memoria y en listas de procesos que cualquier usuario del sistema puede consultar.
Docker Secrets soluciona esto porque monta los Secrets en archivos visibles solo para el contenedor específico. No aparecen en variables de entorno, no aparecen en la lista de procesos y no aparecen en los logs.
Docker Secrets en breve
Docker Secrets son datos confidenciales que Docker gestiona y pone a disposición de los contenedores como archivos. El contenedor lee el Secret desde un archivo bajo /run/secrets/ en lugar de recibirlo como variable de entorno. El archivo existe solo en la memoria del contenedor y nunca se escribe en disco.
La idea central es simple: los Secrets pertenecen en archivos, no en variables de entorno. Los archivos pueden protegerse, rotarse y auditarse; las variables de entorno no.
¿A quién va dirigido Docker Secrets?
- Desarrolladores que ejecutan stacks Docker Compose con datos sensibles.
- Administradores de sistemas que gestionan Secrets en entornos Docker.
- Responsables de seguridad que quieren garantizar que los Secrets no se expongan en texto plano.
- Self-hosters que desean ejecutar sus servicios de forma segura.
Es útil tener experiencia previa con Docker Compose y conocimientos básicos de Secret Management. Si nunca has trabajado con Docker Compose, deberías leer primero los conceptos fundamentales.
Términos clave sobre Docker Secrets
- Secret - Datos confidenciales como contraseñas, claves de API, tokens. Útil: en cualquier servicio que necesite autenticarse.
- Docker Compose - Herramienta para definir stacks multi-contenedor. Útil: para cualquier stack Docker.
- Docker Swarm - Orquestación de contenedores con Secret Management integrado. Útil: cuando quieres gestionar Secrets de forma nativa.
- Archivo .env - Archivo con variables de entorno que Docker Compose carga automáticamente. Útil: para valores que no son críticos.
- HashiCorp Vault - Sistema centralizado de Secret Management. Útil: con muchos Secrets y rotación necesaria.
- Infisical - Gestor de Secrets de código abierto. Útil: como alternativa a Vault.
- Mozilla SOPS - Herramienta para cifrar Secrets en archivos. Útil: si quieres versionar Secrets en Git.
Métodos para Secrets en Docker Compose
Existen varios métodos para gestionar Secrets en Docker Compose. Cada uno tiene sus ventajas e inconvenientes.
Método 1: Variables de entorno (no recomendado)
El método más simple pero inseguro. Las contraseñas aparecen como variables de entorno en el contenedor y son visibles para cualquiera que acceda a él.
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: "mein-geheimes-passwort"
Solo deberías usar este método para datos no sensibles. Las contraseñas y claves de API no tienen lugar aquí.
Método 2: Archivo .env
El archivo .env está en el mismo directorio que docker-compose.yml y Docker Compose lo carga automáticamente. Las variables se referencian en el archivo Compose.
.env:
POSTGRES_PASSWORD=mein-geheimes-passwort
docker-compose.yml:
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
El archivo .env no debe subirse al repositorio Git. Agrégalo a .gitignore. Este método es mejor que tener contraseñas en texto plano en la Compose, pero las contraseñas aún terminan como variables de entorno en el contenedor.
Método 3: Docker Compose Secrets (recomendado)
Docker Compose soporta Secrets desde la versión 1.27. Defines los Secrets en la sección secrets y los vinculas a los contenedores. Los Secrets se ponen a disposición como archivos bajo /run/secrets/ en el contenedor.
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
secrets:
- postgres_password
secrets:
postgres_password:
file: ./secrets/postgres_password.txt
El archivo ./secrets/postgres_password.txt contiene la contraseña en texto plano. Docker lee el archivo y pone el contenido a disposición del contenedor como archivo bajo /run/secrets/postgres_password. La contraseña no aparece en variables de entorno, sino que la aplicación la lee del archivo.
Importante: muchas imágenes oficiales soportan la convención *_FILE. En lugar de POSTGRES_PASSWORD usas POSTGRES_PASSWORD_FILE e indicas la ruta al archivo del Secret. Esto aplica a PostgreSQL, MySQL, Redis, Nextcloud y muchos otros.
Método 4: Secrets externos con Docker Swarm
Si usas Docker Swarm, puedes gestionar Secrets de forma centralizada y ponerlos a disposición de los contenedores. Los Secrets se almacenan cifrados en el Swarm y solo son accesibles para los contenedores que los necesitan.
# Crear Secret
echo "mein-geheimes-passwort" | docker secret create postgres_password -
# Usar Secret en Compose
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
secrets:
- postgres_password
secrets:
postgres_password:
external: true
Este método es el más seguro porque los Secrets no residen en archivos en disco, sino que se almacenan en el Swarm. El requisito es tener un Swarm en ejecución.
Método 5: Herramientas de gestión de secretos
Para configuraciones más grandes vale la pena usar un sistema central de gestión de secretos como HashiCorp Vault o Infisical. Estos sistemas administran los secretos de forma centralizada, los rotan automáticamente y registran cada acceso.
La integración en Docker Compose suele hacerse a través de contenedores init o contenedores sidecar que obtienen los secretos y los ponen a disposición como archivo.
Ejemplo práctico: un stack con Docker Secrets
Imagina que quieres configurar un stack con PostgreSQL, Nextcloud y Ollama. Los tres necesitan contraseñas. La estructura con Docker Secrets se vería así:
- Crear directorio de secretos:
mkdir -p secrets - Generar secretos:
openssl rand -base64 32 > secrets/postgres_password.txt openssl rand -base64 32 > secrets/nextcloud_password.txt openssl rand -base64 32 > secrets/ollama_api_key.txt chmod 600 secrets/*.txt - docker-compose.yml con secretos:
services: postgres: image: postgres:16 environment: POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password secrets: - postgres_password volumes: - postgres-data:/var/lib/postgresql/data nextcloud: image: nextcloud:latest environment: POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password NEXTCLOUD_ADMIN_PASSWORD_FILE: /run/secrets/nextcloud_password secrets: - postgres_password - nextcloud_password depends_on: - postgres ollama: image: ollama/ollama:latest environment: OLLAMA_API_KEY_FILE: /run/secrets/ollama_api_key secrets: - ollama_api_key volumes: - ollama-data:/root/.ollama secrets: postgres_password: file: ./secrets/postgres_password.txt nextcloud_password: file: ./secrets/nextcloud_password.txt ollama_api_key: file: ./secrets/ollama_api_key.txt volumes: postgres-data: ollama-data: - Adaptar .gitignore: añade
secrets/para que los secretos no terminen en Git. - Iniciar stack:
docker compose up -d
Las contraseñas no están en docker-compose.yml, no aparecen en variables de entorno y no se registran en los logs. Cada contenedor lee solo el secreto que necesita.
Rotar secretos
Los secretos deben rotarse regularmente, especialmente en servicios que se usan a largo plazo. La rotación con Docker Compose Secrets funciona así:
- Generar nuevo secreto:
openssl rand -base64 32 > secrets/postgres_password.txt.new - Guardar secreto anterior:
cp secrets/postgres_password.txt secrets/postgres_password.txt.bak - Activar nuevo secreto:
mv secrets/postgres_password.txt.new secrets/postgres_password.txt - Reiniciar servicio:
docker compose up -d postgres
Importante: en bases de datos, la contraseña debe cambiarse también en la base de datos misma. El secreto en el archivo no es suficiente, la contraseña debe actualizarse en la BD. En PostgreSQL se hace con ALTER USER postgres PASSWORD 'nueva-contraseña';.
Para rotación automatizada vale la pena usar una herramienta como HashiCorp Vault o Infisical que maneje la rotación automáticamente. El artículo Automatizar rotación de secretos lo explica en detalle.
Trampa tipícas con Docker Secrets
- Secretos en Git: el archivo .env y el directorio secrets no deben ir a Git. Revisa tu
.gitignore. - Permisos de archivo incorrectos: los archivos de secreto deben tener
chmod 600, para que solo el propietario pueda leerlos. - Convención
*_FILEno soportada: no todas las imágenes soportan leer contraseñas desde archivos. Revisa la documentación de la imagen. - Secretos en logs: algunas aplicaciones registran contraseñas cuando las leen desde archivos. Revisa los logs después de iniciar.
- Sin rotación: quien usa la misma contraseña durante años corre el riesgo de que sea comprometida. La rotación regular es obligatoria.
- Secretos en variables de entorno como alternativa: si una imagen no soporta
*_FILE, las contraseñas suelen terminar en variables de entorno de todos modos. Es mejor buscar otra imagen o construir una propia. - Sin backup de secretos: si se pierden los archivos de secreto, los servicios quedan inaccesibles. Guarda los secretos en un lugar seguro.
- Secretos en la imagen: algunos Dockerfiles contienen contraseñas como variables de entorno. Eso es un riesgo de seguridad masivo, porque cualquiera puede inspeccionar la imagen.
Enlaces y recursos sobre Docker Secrets
- Optimizar Docker Compose - mejores prácticas para archivos Compose.
- Docker Swarm - orquestación con gestión nativa de secretos.
- Seguridad Docker - asegurar contenedores.
- Gestión de secretos - descripción de herramientas de gestión de secretos.
- HashiCorp Vault - gestión central de secretos.
- Automatizar rotación de secretos - rotar contraseñas automáticamente.
- Variables de entorno - ventajas e inconvenientes de .env.
Puntos clave:
- Docker Secrets es más seguro que variables de entorno porque están disponibles como archivo en el contenedor.
- La convención
*_FILEpermite que muchas imágenes lean contraseñas desde archivos. - Los archivos .env son mejores que texto plano en el archivo Compose, pero no son ideales.
- Secretos externos con Docker Swarm es el método más seguro.
- Rotación, backup y .gitignore no son opcionales, son obligatorios.
Preguntas frecuentes: Docker Secrets con Compose
¿Qué son Docker Secrets?
¿Cuál es la diferencia entre .env y Docker Secrets?
¿Qué es la convención *_FILE?
¿Necesito Docker Swarm para usar Secrets?
¿Cómo roto Docker Secrets?
¿Cómo evito que los secretos terminen en Git?
¿Qué hago si una imagen no soporta *_FILE?
¿Cómo hago backup de Docker Secrets?
¿Puedo usar HashiCorp Vault con Docker Compose?
¿Puedo versionear secretos cifrados en Git?
Fuentes y lecturas adicionales
- Docker Secrets Documentación - Documentación oficial de Docker Secrets.
- Docker Compose Secrets - Secrets en Compose.
- HashiCorp Vault - Gestión centralizada de secretos.
- Mozilla SOPS - Secretos cifrados en Git.
- Infisical - Gestor de secretos de código abierto.


