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ónguestbookva 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
redisse 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
redisy lo volvemos a crear podemos comprobar la persistencia de la información.
Ejercicio
- Crea un contenedor de redis que se llame
bd_redis. - 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 imageniesgn/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 imageniesgn/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 microserviciofrontendva a poder acceder abackendal puerto 5000 porque están conectado a la misma red. - Al nombrar al contenedor de backend con
temperaturas-backendse crea una entrada en el DNS que resuelve ese nombre con la ip del contenedor. Como hemos indicado, por defecto, el microserviciofrontendusa ese nombre para acceder.
Ejercicio
- Crea un contenedor de
temperaturas_backendque se llameapi-temp. - Despliega el contenedor de
temperaturas_froontendy 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_mysqlejecuta un scriptdocker-entrypoint.shque 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
mariadbhan 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ámetrobind-address. - Del mismo modo el contenedor
servidor_wpejecuta un scriptdocker-entrypoint.sh, que entre otras cosas, a partir de las variables de entorno, ha creado el ficherowp-config.phpde 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_HOSTla 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 nombreservidor_mysqlestará 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 contenedorservidor_wppuede acceder al puerto 3306 delservidor_mysqlsin 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:
- Crea una red de tipo bridge.
- 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.
- 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.
- Accede a la aplicación usando un navegador web.