Cómo pasar variables de entorno a un contenedor Docker con -e y --env-file
Introducción
Cuando trabajás con contenedores Docker, una de las tareas más frecuentes es configurar el entorno de ejecución de la aplicación mediante variables de entorno. Estas variables permiten cambiar el comportamiento de un servicio sin modificar su imagen: por ejemplo, activar modo debug, definir puertos de conexión a bases de datos, o especificar claves de API.
En este artículo vas a aprender:
- Qué son las variables de entorno y por qué son útiles en contenedores.
- Cómo pasarlas a un contenedor usando la bandera
-e(una a una). - Cómo pasarlas mediante un archivo con la opción
--env-file. - Cuál es la diferencia entre ambos enfoques y cuándo conviene usar cada uno.
- Buenas prácticas, errores comunes y cómo depurar problemas relacionados con el entorno.
El contenido está pensado para desarrolladores, DevOps y cualquier persona que ya tenga nociones básicas de Docker y quiera profundizar en la gestión de configuración. Los ejemplos incluyen comandos de terminal que podés copiar y pegar, junto con la salida esperada para que veás exactamente qué ocurre.
Variables de entorno en Docker: concepto rápido
Una variable de entorno es un par NAME=VALUE que el proceso dentro del contenedor puede leer mediante el entorno del sistema operativo. En Linux, cualquier programa puede acceder a estas variables mediante getenv() (en C), os.getenv() (en Python), process.env (en Node.js) o simplemente leyendo el entorno del shell.
Docker aísla el entorno del contenedor del host, pero provee mecanismos para inyectar variables desde el host al contenedor al momento de crear o ejecutar el contenedor. Las dos formas más usadas son:
-eo--env: permite especificar una variable directamente en la línea de comandos.--env-file: indica un archivo que contiene una lista de variables, una por línea, en formatoNAME=VALUE.
Ambas opciones se pueden combinar; las variables definidas con -e sobrescriben a las del mismo nombre que provienen del archivo.
Pasar variables con -e
Sintaxis básica
docker run -e VAR_NAME=value imagen:etiqueta comandoCada -e agrega una variable. Si necesitás pasar varias, repetís la opción tantas veces como sea necesario.
Ejemplo interactivo sin Docker
Para ilustrar el efecto sin depender de Docker, podemos usar el comando env de Bash, que muestra todas las variables de entorno del proceso actual. Vamos a crear un subproceso que reciba una variable y luego la imprima.
VAR_SALUDO="Hola desde -e"
bash -c 'echo "$VAR_SALUDO"'Salida esperada
Hola desde -eEn este ejemplo, la variable VAR_SALUDO se define en el shell padre y luego se pasa al subproceso mediante la herencia de entorno (el -c de bash recibe el entorno del proceso que lo invoca). En Docker, el mecanismo es análogo, pero la inyección se hace desde el daemon hacia el proceso del contenedor.
Ejemplo con Docker (no ejecutable en el playground)
Supongamos que tenés una imagen simples que solo imprime el valor de una variable llamada APP_MODE. Podés usar la imagen oficial alpine y el comando sh -c 'echo "APP_MODE=$APP_MODE"'.
docker run --rm -e APP_MODE=production alpine:latest sh -c 'echo "APP_MODE=$APP_MODE"'Salida esperada
APP_MODE=productionSi la variable no está definida, el contenedor imprimirá una cadena vacía:
docker run --rm alpine:latest sh -c 'echo "APP_MODE=$APP_MODE"'Salida esperada
APP_MODE=Pasar varias variables con -e
docker run --rm \
-e DB_HOST=db.example.com \
-e DB_PORT=5432 \
-e DB_USER=appuser \
-e DB_PASS=secreto \
alpine:latest sh -c 'echo "DB_HOST=$DB_HOST DB_PORT=$DB_PORT"'Salida esperada
DB_HOST=db.example.com DB_PORT=5432Pasar variables con --env-file
Formato del archivo
El archivo pasado a --env-file debe contener una variable por línea, en formato NAME=VALUE. Los comentarios se pueden iniciar con # y las líneas en blanco se ignoran. No se permiten espacios alrededor del signo = (aunque algunas versiones de Docker los toleran, es buena práctica evitarlos).
Ejemplo de archivo .env:
# Configuración de la aplicación
APP_ENV=staging
LOG_LEVEL=debug
MAX_WORKERS=4
# Credenciales (no subir este archivo a repositorios públicos)
DB_PASSWORD=supersecreto
API_KEY=abc123def456Uso básico
docker run --rm --env-file .env alpine:latest sh -c 'echo "APP_ENV=$APP_ENV LOG_LEVEL=$LOG_LEVEL"'Salida esperada
APP_ENV=staging LOG_LEVEL=debugCreando el archivo y probándolo (executable)
Podemos demostrar el mismo efecto sin Docker usando el comando env y el builtin export de Bash para cargar el archivo en el entorno del proceso actual.
cat > demo.env <<'EOF'
FOO=bar
BAZ=qux
EOF
# Cargar el archivo en el entorno actual
export $(grep -v '^#' demo.env | xargs)
echo "FOO=$FOO, BAZ=$BAZ"Salida esperada
FOO=bar, BAZ=quxEn este bloque, grep -v '^#' elimina las líneas de comentario, xargs las convierte en argumentos para export, y luego las variables están disponibles en la shell.
Sobrescribiendo variables con -e
Cuando usás tanto --env-file como -e, las variables definidas con -e tienen prioridad y reemplazan a las del mismo nombre que vienen del archivo.
docker run --rm \
--env-file .env \
-e LOG_LEVEL=error \
alpine:latest sh -c 'echo "LOG_LEVEL=$LOG_LEVEL"'Salida esperada
LOG_LEVEL=errorAquí el archivo .env define LOG_LEVEL=debug, pero la opción -e LOG_LEVEL=error la sobrescribe.
Comparación entre -e y --env-file
| Característica | -e |
--env-file |
|---|---|---|
| Cantidad de variables | Ideal para pocas (1‑5) | Ideal para muchas o configuraciones complejas |
| Legibilidad en CLI | Puede tornar el comando muy largo | Mantiene la línea de comandos limpia |
| Facilidad de versionado | Difícil de versionar | Fácil de versionar con Git (añadiendo el archivo) |
| Sobrescritura | Sobrescribe variables del archivo | No puede sobrescribirse por sí mismo (necesita -e) |
| Portabilidad | Depende de la línea de comandos | El archivo puede reutilizarse en múltiples contenedores |
| Seguridad (manejo de secrets) | Se ve en ps y en el historial |
También se ve si el archivo está legible; mejor usar Docker secrets o un vault |
Cuándo usar cada uno
-ees práctico cuando necesitás probar rápidamente una configuración, pasar un único flag de depuración, o cuando la variable proviene de otro proceso (por ejemplo, salida de un comando).--env-filees la opción recomendada para entornos de producción, donde tenés un conjunto estable de variables que no cambian frecuentemente. Permite mantener eldocker runcorto y delegar la gestión de configuración a un archivo que puede ser versionado, revisado y desplegado junto con tu código.
Buenas prácticas
- Nunca incluyas secrets en archivos de texto sin cifrar que vayan a repositorios públicos. Usa
.gitignorepara excluir.envo, mejor aún, emplea herramientas como Docker Secrets, HashiCorp Vault o AWS Secrets Manager. - Documentá el formato esperado de tu archivo de entorno. Un
README.env.examplecon variables de ejemplo (sin valores reales) ayuda a nuevos integrantes del equipo. - Usá nombres en mayúsculas y guiones bajos (
SERVICE_PORT,FEATURE_FLAG) para seguir la convención de variables de entorno. - Validá las variables dentro del contenedor al inicio de la aplicación. Un script de entrada (
entrypoint.sh) puede chequear que variables obligatorias estén definidas y fallar con un mensaje claro si falta alguna. - Evité espacios alrededor del
=en el archivo de entorno; aunque Docker a veces los ignora, otras herramientas (comodotenven Node.js opython-dotenv) pueden fallar. - Versioná el archivo de ejemplo, no el archivo con valores reales. Así el repositorio muestra qué variables se necesitan sin exponer información sensible.
- Combínalas con
-epara overrides temporales (por ejemplo, activar modo debug en un entorno de staging sin modificar el archivo). - Limpiá el historial de la shell después de definir variables sensibles con
-e(unset VARohistory -c) para evitar que queden registradas.
Errores comunes y cómo depurarlos
1. Variable no definida dentro del contenedor
Síntomas: La aplicación falla porque espera una variable que no está.
Posibles causas:
- Error de tipografía en el nombre (p.ej.
DB_HOSTvsDB-HOST). - El archivo
--env-fileno se encuentra en la ruta especificada. - La línea en el archivo tiene espacios extra o está comentada inadvertidamente.
Cómo diagnosticar:
Ejecutá un contenedor con un shell interactivo y viste el entorno:
docker run --rm --env-file .env -e EXTRA=test alpine:latest envEsto imprimirá todas las variables definidas. Buscá la que esperás y verificá su valor.
2. Valor vacío o inesperado
Síntomas: La variable está definida pero contiene una cadena vacía o un valor distinto al esperado.
Posibles causas:
- La línea en el archivo termina con un espacio después del
=(p.ej.API_KEY=). - Se usó comillas simples o dobles que fueron parte del valor (p.ej.
API_KEY="abc123"). - La variable fue sobrescrita por una
-eposterior sin darse cuenta.
Cómo diagnosticar:
Revisá el archivo con cat -A .env para mostrar caracteres invisibles (como ^M para carriage return). También podés usar set -a; source .env; set +a en una shell y luego echo "$API_KEY" para ver el valor tal como lo interpreta Bash.
3. El archivo no se lee por permisos
Síntomas: Docker muestra un error como "cannot open .env: permission denied).
Posibles causas:
- El archivo no es legible por el usuario que ejecuta el daemon Docker (generalmente
root). - El archivo está dentro de un volumen montado con opciones
roque no permiten lectura.
Cómo diagnosticar:
Verificá los permisos con ls -l .env y, si es necesario, cambiálos con chmod 644 .env.
Conclusión
Pasar variables de entorno a un contenedor es una operación sencilla pero fundamental para configurar aplicaciones de forma flexible y segura. Las dos opciones principales de Docker, -e y --env-file, cumplen funciones complementarias:
- Usá
-ecuando necesitás pasar pocas variables, hacer pruebas rápidas o sobreescribir valores de forma puntual. - Recurrí a
--env-filecuando tenés un conjunto amplio de configuraciones que querés mantener versionadas, legibles y reutilizables en múltiples contenedores.
Recordá siempre validar que las variables lleguen correctamente al contenedor, evitando dejar secrets en archivos sin proteger y siguiendo las buenas prácticas de nomenclatura y documentación. Con estos conocimientos podés gestionar la configuración de tus contenedores de forma profesional, reduciendo errores de despliegue y facilitando la colaboración en equipo.
Próximos pasos
Si querés profundizar, investigá sobre:
- Docker Secrets y cómo manejar información sensible de forma más segura que con
-eo--env-file. - Archivos de composición (
docker-compose.yml) y la sintaxisenv_fileyenvironmentpara definir variables en servicios múltiples. - Integración con herramientas de orquestación como Kubernetes (ConfigMaps y Secrets) y cómo se traducen las mismas ideas a esos entornos.
Con eso tendrás una visión completa de la gestión de configuración en el mundo de los contenedores, desde el sencillo docker run hasta plataformas de producción escalables.
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.