Clase 8: Docker - Ejemplos de despliegue

Ejemplo 1: Despliegue de la aplicación Guestbook

En este ejemplo vamos a desplegar una aplicación web que requiere de dos servicios (servicio web y servicio de base de datos) para su ejecución. La aplicación se llama GuestBook y necesita los dos siguientes servicios:

  • La aplicación guestbook es una aplicación web desarrollada en python que es servida por el puerto 5000/tcp. Utilizaremos la imagen iesgn/guestbook.
  • Esta aplicación guarda la información en una base de datos no relacional redis, que utiliza el puerto 6379/tcp para conectarnos. Usaremos la imagen redis.

Configuración de la aplicación guestbook

Podemos definir la variable de entorno (llamada REDIS_SERVER) donde se configura el nombre del servidor de base de datos redis al que se accede, por defecto el valor de esta variable es redis.

Volúmenes

Si estudiamos la documentación de la imagen redis en Docker Hub, para que la información de la base de datos se guarde en un directorio /data del contenedor hay que ejecutar el proceso redis-server con los argumentos --appendonly yes.

Redes

Los dos contenedores tienen que estar en la misma red y deben tener acceso por nombres (resolución DNS) ya que de principio no sabemos que ip va a coger cada contenedor. Por lo tanto vamos a crear los contenedores en la misma red:

$ docker network create red_guestbook
$ docker run -d --name redis --network red_guestbook -v /opt/redis:/data redis redis-server --appendonly yes
$ docker run -d -p 80:5000 --name guestbook --network red_guestbook -e REDIS_SERVER=redis  iesgn/guestbook

Algunas observaciones:

  • No es necesario mapear el puerto de redis, ya que no vamos a acceder desde el exterior. Sin embargo la aplicación guestbook va a poder acceder a la base de datos porque están conectado a la misma red.
  • Al nombrar al contenedor de la base de datos con redis se crea una entrada en el DNS que resuelve ese nombre con la ip del contenedor. Como hemos indicado, por defecto, la aplicación guestbook usa ese nombre para acceder.
  • Si eliminamos el contenedor de redis y lo volvemos a crear podemos comprobar la persistencia de la información.

Ejercicio

  1. Crea un contenedor de redis que se llame bd_redis.
  2. Despliega el contenedor de guestbook y comprueba que funciona.

Ejemplo 2: Despliegue de la aplicación Temperaturas

Vamos a hacer un despliegue completo de una aplicación llamada Temperaturas. Esta aplicación nos permite consultar la temperatura mínima y máxima de todos los municipios de España. Esta aplicación está formada por dos microservicios:

  • frontend: Es una aplicación escrita en Python que nos ofrece una página web para hacer las búsquedas y visualizar los resultados. Este microservicio hará peticiones HTTP al segundo microservicio para obtener la información. Este microservicio ofrece el servicio en el puerto 3000/tcp. Usaremos la imagen iesgn/temperaturas_frontend.
  • backend: Es el segundo microservicio que nos ofrece un servicio web de tipo API Restful. A esta API Web podemos hacerles consultas sobre los municipios y sobre las temperaturas. En este caso, se utiliza el puerto 5000/tcp para ofrecer el servicio. Usaremos la imagen iesgn/temperaturas_backend.

En frontend podemos indicar la variable de entorno TEMP_SERVER para indicar el nombre del servidor y el puerto de acceso del microservicio frontend y que debe corresponder con el nombre y el puerto del microservicio backend. Por defecto esta variable tiene como valor temperaturas-backend:5000.

Vamos a crear una red para conectar los dos contenedores:

$ docker network create red_temperaturas
$ docker run -d --name temperaturas-backend --network red_temperaturas iesgn/temperaturas_backend
$ docker run -d -p 80:3000 --name temperaturas-frontend -e TEMP_SERVER=temperaturas-backend:5000 --network red_temperaturas iesgn/temperaturas_frontend

Algunas observaciones:

  • Este es un tipo de aplicación, que se caracteriza por no necesitar guardar información para su funcionamiento. Son las denominadas aplicaciones sin estado, por lo tanto no necesitamos almacenamiento adicional para la aplicación.
  • No es necesario mapear el puerto de backend, ya que no vamos a acceder desde el exterior. Sin embargo el microservicio frontend va a poder acceder a backend al puerto 5000 porque están conectado a la misma red.
  • Al nombrar al contenedor de backend con temperaturas-backend se crea una entrada en el DNS que resuelve ese nombre con la ip del contenedor. Como hemos indicado, por defecto, el microservicio frontend usa ese nombre para acceder.

Ejercicio

  1. Crea un contenedor de temperaturas_backend que se llame api-temp.
  2. Despliega el contenedor de temperaturas_froontend y comprueba que funciona.

Ejemplo 3: Despliegue de Wordpress + mariadb

Para la instalación de WordPress necesitamos dos contenedores: la base de datos (imagen mariadb) y el servidor web con la aplicación (imagen wordpress). Los dos contenedores tienen que estar en la misma red y deben tener acceso por nombres (resolución DNS) ya que de principio no sabemos que ip va a coger cada contenedor. Por lo tanto vamos a crear los contenedores en la misma red:

$ docker network create red_wp

Siguiendo la documentación de la imagen mariadb y la imagen wordpress podemos ejecutar los siguientes comandos para crear los dos contenedores:

$ docker run -d --name servidor_mysql \
                --network red_wp \
                -v /opt/mysql_wp:/var/lib/mysql \
                -e MARIADB_DATABASE=bd_wp \
                -e MARIADB_USER=user_wp \
                -e MARIADB_PASSWORD=asdasd \
                -e MARIADB_ROOT_PASSWORD=asdasd \
                mariadb
                
$ docker run -d --name servidor_wp \
                --network red_wp \
                -v /opt/wordpress:/var/www/html/wp-content \
                -e WORDPRESS_DB_HOST=servidor_mysql \
                -e WORDPRESS_DB_USER=user_wp \
                -e WORDPRESS_DB_PASSWORD=asdasd \
                -e WORDPRESS_DB_NAME=bd_wp \
                -p 80:80 \
                wordpress

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
5b2c5a82a524        wordpress           "docker-entrypoint.s…"   9 minutes ago       Up 9 minutes        0.0.0.0:80->80/tcp   servidor_wp
f70f22aed3d1        mariadb             "docker-entrypoint.s…"   9 minutes ago       Up 9 minutes        3306/tcp             servidor_mysql

Algunas observaciones:

  • El contenedor servidor_mysql ejecuta un script docker-entrypoint.sh que es el encargado, a partir de las variables de entorno, configurar la base de datos: crea usuario, crea base de datos, cambia la contraseña del usuario root,… y termina ejecutando el servidor mariadb.
  • Al crear la imagen mariadb han tenido en cuenta de que tiene que permitir la conexión desde otra máquina, por lo que en la configuración tenemos comentado el parámetro bind-address.
  • Del mismo modo el contenedor servidor_wp ejecuta un script docker-entrypoint.sh, que entre otras cosas, a partir de las variables de entorno, ha creado el fichero wp-config.php de wordpress, por lo que durante la instalación no te ha pedido las credenciales de la base de datos.
  • Si te das cuenta la variable de entorno WORDPRESS_DB_HOST la hemos inicializado al nombre del servidor de base de datos. Como están conectada a la misma red definida por el usuario, el contenedor wordpress al intentar acceder al nombre servidor_mysql estará accediendo al contenedor de la base de datos.
  • Al servicio al que vamos a acceder desde el exterior es al servidor web, es por lo que hemos mapeado los puertos con la opción -p. Sin embargo en el contenedor de la base de datos no es necesario mapear los puertos porque no vamos a acceder a ella desde el exterior. Sin embargo, el contenedor servidor_wp puede acceder al puerto 3306 del servidor_mysql sin problemas ya que están conectados a la misma red.

Ejercicio

Vamos a desplegar la aplicación Nextcloud con una base de datos (NOTA: Para que no te de errores utiliza la imagen mariadb:10.5). Te puede servir el ejercicio que hemos realizado para desplegar Wordpress. Para ello sigue los siguientes pasos:

  1. Crea una red de tipo bridge.
  2. Crea el contenedor de la base de datos conectado a la red que has creado. La base de datos se debe configurar para crear una base de datos y un usuario. Además el contenedor debe utilizar almacenamiento (volúmenes o bind mount) para guardar la información. Puedes seguir la documentación de mariadb para crear una base de datos.
  3. A continuación, siguiendo la documentación de la imagen Nextcloud, crea un contenedor conectado a la misma red, e indica las variables adecuadas para que se configure de forma adecuada y realice la conexión a la base de datos. El contenedor también debe ser persistente usando almacenamiento.
  4. Accede a la aplicación usando un navegador web.