La traducción de la transcripción del podcast se ha preparado en anticipación al lanzamiento del curso

Docker Compose es una herramienta sorprendente para crear un entorno de trabajo
para la pila utilizada en su aplicación. Le permite definir
cada componente de su aplicación siguiendo una sintaxis clara y simple en .
Con la llegada de estos archivos YAML se pueden usar directamente en un entorno de trabajo, al trabajar con
un clúster .
Pero, ¿significa eso que puede usar el mismo archivo docker-compose en
el proceso de desarrollo y en el entorno de producción? ¿O usar este mismo archivo para
staging? Bueno, en general, sí, pero para esa funcionalidad necesitamos lo siguiente:
- Interpolación de variables: uso de variables de entorno para algunos
valores que cambian en cada entorno. - Sobrescritura de configuración: la capacidad de definir un segundo (o cualquier
otro archivo docker-compose posterior) que cambie algo respecto al
primero, y docker compose se encargará de fusionar ambos archivos.
Diferencias entre archivos para desarrollo y producción
Durante el desarrollo, es probable que desee verificar los cambios de código en
tiempo real. Para ello, generalmente, el volumen con el código fuente se monta en
el contenedor en el que se aloja el runtime para su aplicación. Pero para un entorno de producción,
este enfoque no sirve.
En producción, tiene un clúster con múltiples nodos, y el volumen es local en
relación al nodo donde se ejecuta su contenedor (o servicio), por lo que no
puede montar el código fuente sin operaciones complicadas que impliquen
sincronización de código, señales, etc.
En su lugar, normalmente queremos crear una imagen con una versión específica de su código.
Se acostumbra marcarla con una etiqueta correspondiente (puede usar la
versiones semánticas u otro sistema a su conveniencia).
Sobrescritura de configuración
Dadas las diferencias y que sus dependencias pueden variar en los escenarios de
desarrollo y producción, está claro que necesitaremos diferentes archivos de configuración.
Docker compose admite la combinación de diferentes archivos compose para
obtener la configuración final. Cómo funciona se puede ver con el siguiente ejemplo:
$ cat docker-compose.yml
version: "3.2"
services:
whale:
image: docker/whalesay
command: ["cowsay", "hello!"]
$ docker-compose up
Creating network "composeconfigs_default" with the default driver
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ________
whale_1 |
whale_1 | --------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0Como se mencionó, docker compose admite la combinación de varios compose-
archivos, lo que permite sobrescribir diferentes parámetros en el segundo archivo. Por ejemplo:
$ cat docker-compose.second.yml
version: "3.2"
services:
whale:
command: ["cowsay", "bye!"]
$ docker-compose -f docker-compose.yml -f docker-compose.second.yml up
Creating composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ______
whale_1 |
whale_1 | ------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0Esta sintaxis no es muy conveniente durante el desarrollo, cuando el comando
necesita ejecutarse muchas veces.
Afortunadamente, docker compose busca automáticamente un archivo especial llamado
docker-compose.override.yml para sobrescribir valores docker-compose.yml. Si
renombrar el segundo archivo, entonces obtendrás el mismo resultado, solo que usando el comando original:
$ mv docker-compose.second.yml docker-compose.override.yml
$ docker-compose up
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ______
whale_1 |
whale_1 | ------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0Bien, así es más fácil recordar.
Interpelación de variables
Los archivos de configuración admiten y valores predeterminados. Es decir, puedes hacer lo siguiente:
services:
my-service:
build:
context: .
image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
...Y si ejecutas docker-compose build (o push) sin la variable de entorno
$MY_SERVICE_VERSION, se utilizará el valor latest, pero si estableces
el valor de la variable de entorno antes de la construcción, se usará al construir o subir
al registro private.registry.mine.
Mis principios
Los enfoques que son convenientes para mí también pueden ser útiles para ti. Sigo estas
reglas simples:
- Todos mis stacks para producción, desarrollo (u otros entornos) se definen a través de
archivos docker-compose. - Los archivos de configuración necesarios para abarcar todos mis entornos evitan al máximo
la duplicación. - Necesito un solo comando sencillo para trabajar en cada entorno.
- La configuración principal se define en el archivo docker-compose.yml.
- Las variables de entorno se utilizan para definir etiquetas de imágenes u otras
variables que pueden cambiar de un entorno a otro (staging, integración,
producción). - Los valores de las variables para producción se utilizan como valores por
defecto, esto minimiza los riesgos en caso de ejecutar el stack en producción sin
una variable de entorno establecida. - Para iniciar el servicio en el entorno de producción se utiliza el comando docker stack deploy --compose-file docker-compose.yml --with-registry-auth my-stack-name.
- El entorno de trabajo se inicia con el comando docker-compose up -d.
Veamos un ejemplo simple.
# docker-compose.yml
...
services:
my-service:
build:
context: .
image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
environment:
API_ENDPOINT: ${API_ENDPOINT:-https://production.my-api.com}
...Y
# docker-compose.override.yml
...
services:
my-service:
ports: # This is needed for development!
- 80:80
environment:
API_ENDPOINT: https://devel.my-api.com
volumes:
- ./:/project/src
...Puedo usar docker-compose (docker-compose up), para iniciar el stack en
modo de desarrollo con el código fuente montado en /project/src.
¡Puedo usar estos mismos archivos en producción! Y podría usar exactamente
el mismo archivo docker-compose.yml para staging. Para desplegar esto en
producción, solo necesito construir y enviar la imagen con una etiqueta predefinida
en la etapa de CI:
export MY_SERVICE_VERSION=1.2.3
docker-compose -f docker-compose.yml build
docker-compose -f docker-compose.yml pushEn producción, esto se puede ejecutar con los siguientes comandos:
export MY_SERVICE_VERSION=1.2.3
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-authY si quieres hacer lo mismo en staging, solo necesitas definir
las variables de entorno necesarias para trabajar en el entorno de staging:
export MY_SERVICE_VERSION=1.2.3
export API_ENDPOINT=http://staging.my-api.com
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-authAl final, utilizamos dos archivos docker-compose diferentes, que sin
duplicar configuraciones se pueden usar para cualquier entorno que tengas.
Descubre más sobre el curso
Fuente: habr.com
