Empecemos con cosas más complicadas, ahora vamos a preparar un entorno que se comunique entre sí y en el que podamos crear varios contenedores que se comuniquen entre con un solo comando.
Para poder hacer esto, empezaremos a ver algo que se llama docker-compose, esto son otra serie de comandos pertenecientes al entorno de Docker, en el que básicamente se busca un fichero docker-compose.yml con las instrucciones que se deben seguir.
Lo primero, en nuestra carpeta visits donde hemos creado anteriormente nuestro dockerfile con nuestra aplicación en NodeJS, nos creamos el fichero docker-compose.yml y vayamos poco a poco
version: '3'
services:
- version: Hace referencia a la versión de la composición, esto le indica a docker, cuando ejecutamos comandos del CLI de docker-compose, si es versión más actual de docker-compose (a fecha de este texto es la 3).
- services: Dentro del fichero, la propiedad services hace referencia a los contenedores, no a un servicios, dentro de este apartado indicaremos todos los contenedores que crearemos mediante esta composición.
version: '3'
services:
redis-server:
image: 'redis'
node-app:
build: .
ports:
- "4001:8081"
Dentro del apartado de services hemos indicado 2 contenedores: redis-server y node-app. Un detalle importante antes de continuar: TODOS LOS CONTENEDORES DENTRO DEL MISMO DOCKER-COMPOSE ESTÁN DENTRO DE LA MISMA RED, es decir, tienen comunicación entre ellos, y una forma de llamarse unos a otros es con el propio nombre que hemos indicado en el fichero de docker-compose.yml, por lo que si volvemos a nuestro fichero index.js donde tenemos nuestra aplicación de NodeJS, tenemos que hacer un pequeño cambio que antes habíamos ignorado, cuando creamos nuestro cliente de redis es necesario indicarle el host y el puerto del servidor que tiene el servicio de redis-server (siempre es necesario indicarlo menos cuando está en el mismo servidor que el cliente). Para indicarlo en este caso solo es necesario con:
const client = redis.createClient({
host: 'redis-server',
port: 6379
});
Si nos fijamos hemos puesto el mismo nombre que en nuestro docker-compose, realmente lo que esta sucediendo es que cuando la petición llega a la red interna de docker el está reconociendo el nombre y sabe donde ir a buscarlo.
Sabiendo esto y ya teniendo el cambio continuemos con nuestro docker-compose.yml, teniamos esto:
version: '3'
services:
redis-server:
image: 'redis'
node-app:
build: .
ports:
- "4001:8081"
Siguiendo con lo que nos faltaba:
- image: Básicamente le estamos indicando que ese contenedor use la imagen de contenedor con nombre redis (ya sea nuestra o de la docker store)
- build: Le indicamos que inicie el proceso de build con el fichero dockerfile que se encuentra en la ruta indicada.
- ports: Puertos a mapear en este contenedor de nuestro equipo local.
Con esto ya tendríamos todo listo para que nuestro conjunto de contenedores funcionaran, vamos a probarlos. Para ello basta con ejecutar:
docker-compose up
Como vemos tenemos los dos contenedores levantados con los nombres que le hemos indicado en el fichero docker-compose.yml. Si ahora accedemos a localhost:4001 (recordad que hemos cambiado el puerto al hacer el mapeo)
Vemos como funciona perfectamente.
Comandos docker-compose
Veamos algunos comandos de docker-compose:
- docker-compose up: Funciona como docker run, busca el fichero docker-compose up y ejecuta lo que aparece en el.
- docker-compose up --build: Fuerza a rehacer los contenedores antes de ejecutarlos. Muy útil si hemos realizado algún cambio en nuestro código de aplicación.
- docker-compose up -d: Arranca los contenedores en segundo plano.
- docker-compose down: Para los contenedores y elimina tanto los contenedores como la red que crea entre ellos.
- docker-compose start: Arranca los contenedores si están parados (OJO parados que no eliminados)
- docker-compose stop: Para los contenedores y NO elimina nada.
- docker-compose ps: Al igual que docker ps, vemos el estado de nuestra composición de contenedores.
TODOS LOS COMANDOS DE DOCKER COMPOSE NECESITAN EL FICHERO DE docker-compose.yml PARA FUNCIONAR
Reinicio automático de contenedores
Puede pasar que alguno de nuestros contenedores se detenga, por algún error por ejemplo, en este caso docker ya está preparado para automáticamente reiniciar los contenedores según como lo configuremos en nuestro docker-compose.yml. Tenemos estas opciones de reinicio:
- "no": Es la configuración por defecto de los contenedores. No se reinician en ningún caso. Para poner explicitamente no es necesario ponerlo entre ""
- always: Siempre que se pare, sea cual sea la razón, automáticamente se reinicia.
- on-failure: Solo se reinicia cuando se pare con un error code. En general si el código de salida ha sido un 0, eso significa que se ha parado de manera controlada o porque ha terminado su ejecución correctamente, sin embargo, si el código con el termina es distinto de 0 entonces lo tomará como un error y reiniciará el contenedor.
- unless-stopped: Siempre se reinicia a menos que lo hayamos parado nosotros manualmente.
Para configurar estas opciones solo tenemos que indicarselo en el fichero de la siguiente forma:
version: '3'
services:
redis-server:
image: 'redis'
node-app:
restart: always <--Con esta opción
build: .
ports:
- "4001:8081"
Esto último era un extra que nos puede ser útil a la hora de configurar nuestro contenedor. Nos vemos en el siguienteeee, un abrazooor.


