A diferencia del primer post, aquí vamos a ver cómo utilizar contenedores de imágenes ya existentes y utilizar Docker-Compose para gestionarlas como servicios partiendo de un entorno virtualizado y limpio.
Si hemos seguido los pasos del anterior post, partiremos, como hemos mencionado anteriormente, de un entorno virtualizado y limpio con Docker, el cual gestionaremos con Vagrant.Usaremos un sistema muy extendido como ejemplo: Una base de datos no relacional MongoDB para nuestra información persistente y una aplicación Web que se comunicará con ella. La aplicación web utilizará Spring Boot para un prototipado rápido, con un servidor Tomcat embebido. El esquema sería el siguiente:
Se utilizarán los puertos 27017 para MongoDB y 8085 para Tomcat. Externamente, desde nuestro windows local, se mapearán dichos puertos al 27018 y 8087, respectivamente.
1. Manos a la masa. Y ahora ¿qué?
En primer lugar, instalaremos la base de datos. Buscamos en DockerHub una imagen actual de MongDB: (https://hub.docker.com/_/mongo/). Para obtener el contenedor, es tan fácil como utilizar el comando “run” de docker con los parámetros específicos de la imagen que queremos (que se explican en la propia página de DockerHub):
$> docker run --name mongodb -d mongo:latest
vagrant@ubuntu-xenial:~$ docker run --name mongodb -d mongo:latest
Unable to find image 'mongo:latest' locally
latest: Pulling from library/mongo
7b8b6451c85f: Pull complete
[...]
cd245aa9c426: Pull complete
Digest: sha256:0823cc2000223420f88b20d5e19e6bc252fa328c30d8261070e4645b02183c6a
Status: Downloaded newer image for mongo:latest
91c4a067c2d7c4552076a356d80e55cf6bf21feef64578ea7364f52989dda692
$>
¡Listo! Ya tenemos el primer contenedor con MongoDB funcionando en nuestra máquina virtual. Podemos ver el estado con el comando “ls” sobre los containers de docker:
$> docker container ls
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
91c4a067c2d7 mongo:latest "docker-entrypoint.s…" Up 8 seconds 27017/tcp mongodb
Recordemos que los contenedores forman la unidad de software de Docker. Cuando se requieren varios contenedores en un mismo sistema la opción anterior de “run” de Docker se queda pequeña y poco manejable. A continuación, es el turno de Docker-Compose. Por tanto, antes de seguir, detenemos el contenedor actual y lo eliminamos para no tener problemas en próximos pasos:
$> docker stop mongodb
mongodb
$> docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
2. Rizando el rizo, Docker-Compose
Docker-Compose nos permite tratar contenedores como si fuesen servicios. Permite configurarlos y adaptarlos a cada entorno según las necesidades (certificación, producción, etc.). La mejor manera de entenderlo es probando como funciona. Por ello, vamos a instalarlo en nuestra máquina virtual:
$> sudo apt-get update
$> sudo curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 617 0 617 0 0 897 0 --:--:-- --:--:-- --:--:-- 896
100 11.2M 100 11.2M 0 0 1172k 0 0:00:09 0:00:09 --:--:-- 1284k
$> sudo chmod +x /usr/local/bin/docker-compose
Para instalar la última versión de Docker-Compose, podéis revisar los comandos anteriores en: https://github.com/docker/compose/releasesDocker-Compose utiliza un archivo docker-compose en formato YML. Nos vamos a la carpeta /docker (que hemos creado en nuestro home: /home/vagrant) y creamos un archivo docker-compose.yml con el siguiente contenido:
version: '3'
services:
mongodb:
image: mongo:latest
container_name: "mongodb"
volumes:
- ./data/:/data/
ports:
- 27017:27017
A continuación, ejecutamos el comando “up” de Docker-Compose, que leerá el archivo docker-compose.yml y levantará los servicios con la configuración indicada. Posteriormente, utilizaremos el parámetro “-d” para que inicie los servicios en segundo plano:
$> docker-compose up -d Creating mongodb ... done
¡Recuerda! Si queremos ver los logs, podemos hacerlo en cualquier momento desde nuestro contenedor/servicio con el comando “logs”.
$> docker-compose logs -f mongodb
Attaching to mongodb
mongodb | 2018-12-05T13:15:28.191+0000 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
mongodb | 2018-12-05T13:15:28.199+0000 I CONTROL [initandlisten] MongoDB starting : pid=1 port=27017 dbpath=/data/db 64-bit host=d2de9617fefd
[...]
Por último, comprobamos que nuestro servicio MongoDB esté funcionando:
$> docker-compose ps
Name Command State Ports
------------------------------------------------------------------------
mongodb docker-entrypoint.sh mongod Up 0.0.0.0:27017->27017/tcp
Si queremos detener los servicios, podemos hacerlo en cualquier momento con el comando “stop”:
$> docker-compose stop
Stopping mongodb ... done
¡Genial! Ya volvemos a tener la instancia de MongoDB funcionando con un poco más de control sobre la configuración. Por otra parte, el puerto 27017 esta abierto en la máquina virtual. Si queremos tener acceso a él desde fuera de la Vagrant, es decir, desde nuestro sistema local, tenemos que abrir dicho puerto en la configuración del Vagrantfile:
Vagrant.configure("2") do |config|
# Every Vagrant development environment requires a box.
config.vm.box = "ubuntu/xenial64"
# Share an additional folder to the guest VM.
config.vm.synced_folder "./docker", "/home/vagrant/docker"
config.vm.synced_folder "./shared", "/home/vagrant/shared"
# Mongo
config.vm.network "forwarded_port", guest: 27017, host: 27018
# VirtualBox specific configuration
config.vm.provider "virtualbox" do |vb|
vb.memory = "6144"
vb.cpus = "2"
end
end
Cambiando el Vagrantfile y reiniciando la Vagrant, tendremos el puerto 27018 accesible desde nuestro sistema local Windows, que conectará a su vez con el 27017 de la máquina virtual donde está escuchando MongoDB. Para conectarnos a MongoDB podemos utilizar cualquier cliente (RoboMongo, por ejemplo).
3. Genial, quiero más
En pocos pasos, y con Docker instalado, tenemos una base de datos MongoDB funcionando sin necesitad de instalar nada en nuestro local. Podemos ir más allá, y montar un sistema tan equipado como queramos, añadiendo contenedores como un Apache Kafka, ElasticSearch, etc. Docker-Compose se encargará de establecer la configuración, levantar las instancias y comunicar entre sí cada servicio.En el siguiente, y último post, veremos como generar un contenedor de una aplicación propia y distribuirla.