3.4 · Variables, perfiles y sobrecargas por entorno

Nivel 3 · Docker Compose

3.4Variables, perfiles y sobrecargas por entorno

Objetivo: declinar un compose en dev / prod sin duplicar el archivo.
Tiempo estimado: 12 min · lectura autónoma · Si solo tienes 5 min: lee «Lo esencial en 30s» + el esquema.

Lo esencial en 30 segundos

  • El .env : un valor, varias caras : ${PORT:-3000} lee la variable o su defecto — un archivo .env por entorno, un solo compose para N caras.
  • Las sobrecargas : base + variante : compose.override.yml autocargado en dev, -f compose.yml -f compose.prod.yml en prod — cada archivo solo describe su diferencia.
  • Los perfiles : servicios opt-in : profiles: [dev] deja adminer ausente por defecto, presente con --profile dev — el stack por defecto es mínimo y seguro.

Mini-caso hilado — Idir unifica dev y prod

Idir, devops junior en Argel, mantiene dos compose.yml copiados (dev con adminer, prod sin) — divergen, y un día la consola dev se va a producción. Refunde : una base única con ${PORT:-3000}, adminer bajo profiles: [dev], .env por entorno no commiteado. Dev : --profile dev up -d ; prod : up -d, sobria por defecto. Una sola fuente de verdad, dos caras — la prod ya nunca contiene las herramientas de dev.

Este mismo caso vuelve en el curso, el esquema, el guion y el reto 48h.

1. Interpolación y .env : parametrizar sin duplicar

En compose.yml, ${PORT:-3000} lee la variable PORT o 3000 por defecto : el compose se vuelve PARAMETRIZABLE. Un archivo .env junto al compose fija los valores por entorno (dev : puertos publicados + adminer ; prod : otros valores, sin adminer) — cargado automáticamente. Un archivo, N caras : la misma imagen, la misma estructura, valores que cambian.

Regla de higiene : el .env con secretos NUNCA se commitea — se versiona un .env.example ficticio que documenta las claves esperadas. Y los defectos ${X:-…} se eligen prod-seguros : sin variable, el stack arranca en su forma más sobria, no la más abierta.

2. Sobrecargas -f y perfiles : variantes y opt-in

Las SOBRECARGAS : se guarda un compose.yml BASE y se añaden variantes — compose.override.yml, cargado automáticamente en dev (bind mounts, debug), o compose.prod.yml llamado explícitamente (-f compose.yml -f compose.prod.yml). Cada archivo solo describe su DIFERENCIA ; de izquierda a derecha, cada -f sobrecarga al anterior. Se acabó la duplicación integral por entorno.

Los PERFILES : profiles: [dev] en adminer lo vuelve OPT-IN — ausente por defecto, presente con --profile dev. Se acabó el « olvidé quitar la consola en prod » : por defecto, el stack es mínimo y seguro, las herramientas dev se activan explícitamente. Base mínima, opciones en perfiles, defecto prod-seguro.

Error frecuente de interpretación: « Un compose por entorno es más claro, y los perfiles dev pueden quedar activos por defecto ». No, dos veces. Dos archivos copiados DIVERGEN — toda corrección debe aplicarse dos veces, y un día la consola dev se va a prod. Y un perfil activo por defecto ya no es un perfil : el opt-in solo existe si el defecto es sobrio. Una base, sobrecargas, opt-in.
Declinar sin duplicar Base, valores, variantes, opt-in Base versionadacompose.yml + ${VAR:-defecto prod-seguro}+Valores por env.env local no commiteado + .env.example+Variantes + opt-inSobrecargas -f, override dev, profiles Por defecto : mínimo y seguro ; el dev se activa explícitamente.
Base, valores, variantes, opt-in
Versión en texto del esquema (SEO / lectores de pantalla / traducción): 1) Base : Idir escribe un compose único con ${PORT:-3000} en lugar de dos archivos copiados. 2) Valores : .env por entorno no commiteado, .env.example versionado, defectos prod-seguros. 3) Variantes : override auto en dev, -f prod explícito, adminer en perfil dev — sobrio por defecto. Lección : una base, valores, diferencias en sobrecarga.

🔎 Ejemplo concreto — Dev rico, prod sobria : misma base, dos caras

Idir parametriza el puerto, pone adminer en perfil dev, y lanza cada entorno.

# compose.yml (base)
services:
  api:
    build: ./api
    ports: ["${PORT:-3000}:3000"]
    networks: [appnet]
  adminer:
    image: adminer:4.8
    profiles: [dev]
    ports: ["8081:8080"]
    networks: [appnet]
networks:
  appnet:
# .env (dev, NO commiteado) : PORT=3000
# Dev  : docker compose --profile dev up -d
# Prod : PORT=80 docker compose up -d

Lectura : misma base, adminer solo en dev, puerto por variable.

Lección : la prod nunca contiene las herramientas de dev — sobria por defecto.

Vocabulario de la sección

Interpolación
${VAR:-defecto} resuelto desde el entorno o el .env : el compose parametrizable.

Ejemplo sencillo: El ${PORT:-3000} de Idir, 3000 sin variable.

Lo que no es: un puerto en duro duplicado en dos archivos.

Reflejo: defecto prod-seguro tras cada :-.

Sobrecarga
Archivo -f adicional que modifica la base : cada -f sobrecarga al anterior, de izquierda a derecha.

Ejemplo sencillo: -f compose.yml -f compose.prod.yml en producción.

Lo que no es: un segundo compose copiado 95 % idéntico.

Reflejo: cada variante solo describe su diferencia.

override
Sobrecarga dev (compose.override.yml) cargada automáticamente : binds, debug, sin tocar la base.

Ejemplo sencillo: Los montajes live de Idir solo en dev.

Lo que no es: binds de dev que se fugan a producción.

Reflejo: dev en el override, nunca en la base.

Perfil
Grupo opt-in (profiles: [dev]) activado por --profile : servicio ausente por defecto.

Ejemplo sencillo: Adminer presente solo con --profile dev.

Lo que no es: la consola dev que se va a prod por olvido.

Reflejo: herramientas dev en perfiles, stack sobrio por defecto.

.env
Archivo local de valores junto al compose, cargado auto — no commiteado si contiene secretos.

Ejemplo sencillo: El .env de Idir con PORT y contraseñas locales.

Lo que no es: un .env con secretos subido al repositorio.

Reflejo: versionar .env.example, nunca los secretos.

En la práctica — Dev/prod sin duplicación

  1. Añada ${PORT:-3000} y un perfil dev (adminer) a su compose base.
  2. Lance sin perfil : verifique que adminer está ausente (stack sobrio).
  3. Relance con --profile dev : adminer aparece — opt-in explícito.
  4. Cambie PORT vía el entorno y relance : el puerto sigue, sin tocar el archivo.
Una sola base sirve a todos los entornos : valores por env, diferencias en sobrecarga, herramientas en opt-in.

Guion listo para decir — justificar la base única (30 s)

« Un solo compose base : el puerto viene de una variable, la consola dev de un perfil opt-in, las diferencias de la prod de una sobrecarga. Dev rico con --profile dev, prod sobria por defecto — ningún archivo copiado que diverge, ninguna herramienta dev que se fuga a prod. »

Para decir en revisión de arquitectura ; mostrar el diff vacío entre dev y prod.

Modelo copiar-pegar — base parametrizada + perfil dev

# Base : dev rico en opt-in, prod sobria por defecto.
services:
  api:
    build: ./api
    ports:
      - "${PORT:-3000}:3000"
    environment:
      DATABASE_URL: ${DATABASE_URL}
    networks:
      - appnet
  adminer:
    image: adminer:4.8
    profiles:
      - dev
    ports:
      - "8081:8080"
    networks:
      - appnet

networks:
  appnet:
# Dev  : docker compose --profile dev up -d
# Prod : docker compose -f compose.yml -f compose.prod.yml up -d

Independiente

Base + .env.example y cada cliente declina sin tocar el archivo.

PYME en Argel

Idir unifica dev y prod : una base, dos .env, cero divergencia.

Equipo de proyecto

Imponer base mínima + perfiles opt-in + defectos prod-seguros en la carta.

Principiante

Esta semana : una variable ${PORT:-3000} + un servicio en perfil dev.

Prudencia: Nunca un .env con secretos commiteado : versione un .env.example ficticio, guarde los valores reales en local (o secreto gestionado en prod). Los defectos ${X:-…} quedan prod-seguros — el stack sin variable arranca sobrio, nunca abierto.

✓ Buenas prácticas

  • Mantenga la base mínima, ponga las opciones en perfiles opt-in.
  • Elija defectos prod-seguros tras cada :- (${X:-…}).
  • Versione un .env.example, nunca los secretos reales.

✗ Errores frecuentes

  • Duplicar todo el archivo por entorno : las copias divergen.
  • Perfiles dev activos por defecto : el opt-in ya no existe, la consola se fuga a prod.
  • Commitear un .env con contraseñas : secreto expuesto en el historial.

Puntos clave

  • ${VAR:-defecto} vuelve el compose parametrizable : un archivo, N caras.
  • SOBRECARGAS para las diferencias (-f, override dev) : nunca duplicación.
  • PERFILES opt-in para las herramientas : ausente por defecto, --profile dev para activar.
  • DEFECTO = prod segura ; .env.example versionado, secretos nunca commiteados.

Reto 48h — aplique mañana

Fusione 2 compose copiados en 1 base + 1 perfil dev + 1 sobrecarga, y demuestre que la prod arranca sobria.

Lista de salida de la sección
  • Mi base única sirve a dev y prod sin copiar-pegar.
  • Mis herramientas dev están en opt-in, sobrias por defecto.
  • Mis secretos están fuera del repositorio, mis defectos prod-seguros.
Autoevaluación 1-5 : ¿cuántos compose casi idénticos me quedan ?¿mi prod arranca sobria sin ninguna variable ?

Preguntas frecuentes

¿Varios -f, en qué orden, y override o prod ?

De IZQUIERDA A DERECHA : cada -f sobrecarga al anterior — la base primero, la variante después (-f compose.yml -f compose.prod.yml). compose.override.yml es la excepción : cargado AUTOMÁTICAMENTE (sin -f), lleva el dev (binds, debug). Regla : dev = override auto, prod = -f explícito, y cada archivo solo describe su diferencia.

Comprueba tu comprensión

Adminer solo debe existir en dev. ¿Qué mecánica ?

Recursos adicionales (opcional, para ir más allá)

Examen del nivel 3Preguntas inéditas y más difíciles para validar tus conocimientos