Definición de los servicios de Docker Compose
Cuando comenzamos a ejecutar contenedores utilizando cada vez más la funcionalidad de docker run, los comandos pueden comenzar a ser bastante largos y difíciles de recordar.
Afortunadamente, Docker Compose nos permite escribirlos en YAML.
Tomemos un comando docker run suficientemente complicado para iniciar un contenedor MySQL configurado usando variables de entorno y convertirlo en YAML en a docker-compose.yml. Aquí está el comando con el que comenzamos:
$ docker run -d
--name mysql:5.7
-p 3306:3306
-e MYSQL_ROOT_PASSWORD=secret_password
-e MYSQL_DATABASE=rootdesdezero
mysql
Podemos crear este contenedor exacto como un “servicio” dentro de un archivo docker-compose.yml después de configurar un poco la plantilla. Aquí está nuestro comienzo:
docker-compose.yml
version: "3" services: mysql: image: "mysql" environment: MYSQL_ROOT_PASSWORD: "secret_password" MYSQL_DATABASE: "rootdesdezero" ports: - "3306:3306"
Hay algunas versiones diferentes de la sintaxis utilizada para el archivo docker-compose.yml, pero casi siempre deberíamos estar usando la más nueva, que es 3.x dependiendo de nuestra versión de docker. A partir de ahí, declaramos que queremos definir “servicios” y cualquiera de los elementos aquí debajo será un contenedor que Docker Compose creará y ejecutará para nosotros.
Dentro de la definicion mysql de nuestro servicio, tenemos claves que podemos establecer en ese mapa muy de cerca a las opciones que usamos cuando lo usamos manualmente docker run. Vale la pena señalar que si una opción toma una lista y los valores no incluyen un signo igual ( =), usaremos una lista YAML (comenzando con -), de lo contrario usaremos pares clave/valor YAML como lo hicimos en la sección environment.
Desde el directorio donde creamos el archivo docker-compose.yml, podemos crear y ejecutar nuestros contenedores en segundo plano usando docker-compose up -d, para demonizar los contenedores:
$ docker-compose up -d
Eliminar variables de entorno codificadas
Una mejora que podemos hacer a nuestro servicio mysql sería no codificar las variables de entorno. Lo ideal es que deseemos agregar nuestros archivos docker-compose.yml a un repositorio de código y no queremos comprometer nuestras credenciales en nuestro repositorio de código git.
Afortunadamente, Docker Compose proporciona una excelente manera para que pasemos nuestros valores variables de entorno existentes. Lo primero que debemos hacer es eliminar los valores de nuestro archivo docker-compose.yml manteniendo las claves:
docker-compose.yml
version: "3" services: mysql: image: "mysql:5.7" environment: MYSQL_ROOT_PASSWORD: MYSQL_DATABASE: ports: - "3306:3306"
Para probar esto, queremos eliminar el contenedor que Docker Compose creó usando docker-compose down:
$ docker-compose down
A continuación, definiremos nuestras variables de entorno en línea cuando estemos ejecutando docker-compose up:
$ MYSQL_ROOT_PASSWORD=secret_password MYSQL_DATABASE=rootdesdezero docker-compose up -d
Ya no estamos configurando estos valores en nuestro archivo, pero si inspeccionamos el contenedor MYSQL_las variables de entorno, podemos ver que los valores están configurados correctamente.
Nota: Puede encontrar el nombre de su contenedor usando docker-compose ps
$ docker inspect docker-compose-example_mysql_1 | grep MYSQL_
Orquestando Contenedores
Saber cómo crear un contenedor con Docker Compose nos acerca bastante a poder orquestar múltiples contenedores. Seguiremos los mismos pasos creando otro objeto al mismo nivel que nuestra clave mysql.
En este ejemplo, creemos un contenedor de blog Ghost que requerirá y se conectará a nuestro servicio mysql:
docker-compose.yml
version: "3" services: mysql: image: "mysql:5.7" environment: MYSQL_ROOT_PASSWORD: MYSQL_DATABASE: ports: - "3306:3306" blog: image: "ghost:2-alpine" ports: - "8080:2368" environment: DATABASE__CLIENT: mysql DATABASE__CONNECTION__HOST: mysql DATABASE__CONNECTION__USER: root DATABASE__CONNECTION__DATABASE: DATABASE__CONNECTION__PASSWORD: depends_on: - mysql
Tendremos que tener en cuenta aquí es nuestra clave depends_on en el servicio blog. Al especificar esto, le estamos diciendo a Docker Compose que el servicio mysql debe iniciarse antes que el servicio blog porque el servicio blog necesita que se ejecute.
Además, cuando estamos configurando la conexión de la base de datos para nuestro blog, especificamos el “host” de nuestra base de datos como tal mysql. Esto parece muy extraño, pero en la red interna que Docker Compose creó para nuestros contenedores, mysql otros contenedores (concretamente nuestro contenedor blog) pueden acceder al contenedor utilizando el nombre de dominio completo (FQDN) de mysql.
Ya tenemos el contenedor mysql en ejecución, pero aún podemos ejecutarlo docker-compose up y ejecutará nuestro contenedor adicional:
$ MYSQL_ROOT_PASSWORD=secret_password MYSQL_DATABASE=rootdesdezero DATABASE__CONNECTION__PASSWORD=secret_password DATABASE__CONNECTION__DATABASE=rootdesdezero docker-compose up -d
Ahora podemos acceder a nuestro blog conectándonos a la dirección IP de nuestro host Docker en el puerto 8080.
Crear volúmenes
Vamos a echar un vistazo de cómo mejorar la forma en que almacenamos datos para nuestro blog montando un volumen para que nuestra base de datos persista. Este cambio nos permitirá conservar nuestros datos incluso si eliminamos el contenedor mysql.
Docker Compose facilita esto porque considera que los volúmenes y las redes son objetos de nivel superior al igual que los “servicios”. Creemos un volumen llamado db-data y lo montamos en nuestro contenedor mysql:
docker-compose.yml
version: "3" volumes: db-data: external: false services: mysql: image: "mysql:5.7" environment: MYSQL_ROOT_PASSWORD: MYSQL_DATABASE: ports: - "3306:3306" volumes: - "db-data:/var/lib/mysql" blog: image: "ghost:2-alpine" ports: - "8080:2368" environment: DATABASE__CLIENT: mysql DATABASE__CONNECTION__HOST: mysql DATABASE__CONNECTION__USER: root DATABASE__CONNECTION__DATABASE: DATABASE__CONNECTION__PASSWORD: depends_on: - mysql
Esto creará el volumen para nosotros. La configuracion external:false le dice a Docker Compose que no creamos el volumen “externamente” para Docker Compose.
Para que nuestro servicio mysql use esto, necesitamos crear un nuevo contenedor.
Ejecutaremos docker-compose down
Ahora podemos recrear nuestros contenedores para que los datos se escriban en un volumen.
$ MYSQL_ROOT_PASSWORD=secret_password MYSQL_DATABASE=rootdesdezero DATABASE__CONNECTION__PASSWORD=secret_password DATABASE__CONNECTION__DATABASE=rootdesdezero docker-compose up -d




