Saltar a contenido

Levantar un WordPress con Compose

El cliente de Docker es engorroso para crear contenedores, así como para crear el resto de objetos y vincularlos entre sí.

Para automatizar la creación, inicio y parada de un contenedor o un conjunto de ellos, Docker proporciona un plugin llamada Compose.

Para esta parte vamos a detener y borrar lo que hemos creado:

Example

Borra el trabajo actual:

docker container stop wordpress wordpress-db
docker container rm wordpress wordpress-db
docker volume rm wordpress-db

Docker Compose

Compose es una herramienta para definir y ejecutar aplicaciones multi-contenedor. Con un solo comando podremos crear e iniciar todos los servicios que necesitamos para nuestra aplicación.

Los casos de uso más habituales para docker compose son:

  • Entornos de desarrollo
  • Entornos de testeo automáticos (integración contínua)
  • Despliegue en host individuales (no clusters)

Compose tiene comandos para manejar todo el ciclo de vida de nuestra aplicación:

  • Iniciar, detener y rehacer servicios.
  • Ver el estado de los servicios.
  • Visualizar los logs.
  • Ejecutar un comando en un servicio.

Creación de contenedores automatizada

En el mismo directorio donde estábamos en el paso anterior (~/Sites/wordpress), vamos a crear un fichero llamado docker compose.yaml con el siguiente contenido:

docker-compose.yaml
services:
    db:
        image: mariadb:10
        volumes:
            - data:/var/lib/mysql
        environment:
            - MYSQL_ROOT_PASSWORD=secret
            - MYSQL_DATABASE=wordpress
            - MYSQL_USER=manager
            - MYSQL_PASSWORD=secret
    web:
        image: wordpress:6
        depends_on:
            - db
        volumes:
            - ./target:/var/www/html
        environment:
            - WORDPRESS_DB_USER=manager
            - WORDPRESS_DB_PASSWORD=secret
            - WORDPRESS_DB_HOST=db
            - WORDPRESS_DB_NAME=wordpress
        ports:
            - 8080:80

volumes:
    data:

Info

YAML es un lenguaje de serialización de datos diseñado para ser leído y escrito por personas. Se recomienda que sigas algún tutorial para entender su formato: Aprende YAML en Y minutos.

Los ficheros de Compose están divididos en tres secciones: services, volumes y networks; y deben indicar un número de versión. Nos permite realizar practicamente lo mismo que podemos hacer con el cliente de docker, pero de forma automática.

Note

En este taller no entramos en el apartado de networks.

Con este fichero podemos hacer lo mismo que hemos hecho en el capítulo anterior, pero con la ventaja de describir todos nuestros requisitos en un solo archivo.

Iniciar servicios

Vamos a ejecutar esta aplicación y luego procederemos a explicarla:

Example

Arranca la aplicación con Compose:

docker compose up -d

Cuando arrancamos la aplicación, Compose nos informa de los servicios que ha ido levantando:

$ docker compose up -d
Creating network "wordpress_default" with the default driver
Creating volume "wordpress_data" with local driver
Creating wordpress_db_1 ... 
Creating wordpress_db_1 ... done
Creating wordpress_web_1 ... 
Creating wordpress_web_1 ... done

El parámetro -d es similar al que hemos visto en docker run: nos permite levantar los servicios en segundo plano.

Veamos los contenedores activos:

$ docker container ls
CONTAINER ID  IMAGE            COMMAND      CREATED         STATUS         PORTS                  NAMES
a07b5d4d3982  wordpress:6  "docker.s…"  10 seconds ago  Up 8 seconds   0.0.0.0:8080->80/tcp   wordpress_web_1
d9204884cec5  mariadb:10   "docker.s…"  11 seconds ago  Up 10 seconds  3306/tcp               wordpress_db_1

También podemos ver los contenedores con Compose:

$ docker compose ps
    Name                    Command               State          Ports        
-------------------------------------------------------------------------------
wordpress_db_1    docker-entrypoint.sh mysqld      Up      3306/tcp            
wordpress_web_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:8080->80/tcp

Lo que tenemos que tener en cuenta es lo siguiente:

  • docker compose ps solo muestra información de los servicios que se define en docker compose.yaml, mientras que docker muestra todos.
  • Cuando creamos contenedores con docker sin indicar un nombre, por defecto asigna uno aleatorio; mientras que en Compose el prefijo es el nombre del directorio y el sufijo el nombre del servicio: wordpress_db_1. El número indica el número de instancia. Es posible levantar más de una instancia de un mismo servicio.

Si accedemos a la dirección http://localhost:8080/, veremos de nuevo la instalación de WordPress.

Detener servicios

Podemos detener servicios con

docker compose stop

Borrar servicios

Podemos borrar servicios con

docker compose down

Esto borra los contenedores, pero no los volúmenes. Así que si hemos creado bien la aplicación nuestros datos están a salvo.

Si queremos borrar también los volúmenes:

docker compose down -v

Estructura de la configuración

Veamos la configuración por partes:

volumes:
    data:

Ya hemos indicado que es importante guardar los datos volátiles de las aplicaciones en volúmenes. En este caso hemos creado un volumen llamado data. Recordemos que Compose siempre añade como prefijo el nombre del directorio, con lo que el nombre real del volumen es wordpress_data. Podemos comprobarlo con el cliente de docker como hicimos en el capítulo de volúmenes:

$ docker volume ls
DRIVER              VOLUME NAME
local               wordpress_data

Nos saltamos la sección de redes (networks) y vamos a la sección de servicios, que son los contenedores que precisa o componen nuestra aplicación.

Primero la base de datos:

docker-compose.yaml
services:
    db:
        image: mariadb:10
        volumes:
            - data:/var/lib/mysql
        environment:
            - MYSQL_ROOT_PASSWORD=secret
            - MYSQL_DATABASE=wordpress
            - MYSQL_USER=manager
            - MYSQL_PASSWORD=secret

Después de abrir la parte de servicios, el primer nivel indica el nombre del servicio db, que genera el contenedor wordpress_db. Lo que vemos a continuación es lo mismo que hicimos en la sección anterior pero de forma parametrizada. Si recordamos, para levantar nuestra base de datos, indicamos la imagen (línea 3), luego montamos los volúmenes (línea 4), y después indicamos las variables de entorno que configuraban el contenedor (línea 6).

Es decir, lo anterior es equivalente, excepto por el nombre, a:

$ docker run -d --name wordpress-db \
        --mount source=wordpress-db,target=/var/lib/mysql \
        -e MYSQL_ROOT_PASSWORD=secret \
        -e MYSQL_DATABASE=wordpress \
        -e MYSQL_USER=manager \
        -e MYSQL_PASSWORD=secret mariadb:10

Y después nuestro WordPress:

docker-compose.yaml
services:
    web:
        image: wordpress:6
        depends_on:
            - db
        volumes:
            - ./target:/var/www/html
        environment:
            - WORDPRESS_DB_USER=manager
            - WORDPRESS_DB_PASSWORD=secret
            - WORDPRESS_DB_HOST=db
        ports:
            - 8080:80

En este caso la equivalencia es al comando:

$ docker run -d --name wordpress \
    --link wordpress-db:mysql \
    --mount type=bind,source="$(pwd)"/target,target=/var/www/html \
    -e WORDPRESS_DB_USER=manager \
    -e WORDPRESS_DB_PASSWORD=secret \
    -p 8080:80 \
    wordpress:6

La equivalencia de los parámetros es la siguiente:

parámetro Docker parámetro Composer
--link depends_on
--mount volumes
-e environment
-p,--publish ports
image

Note

Si reiniciamos el ordenador, los contenedores estarán detenidos (stop), podremos reiniciarlos con docker start o docker compose start. Este es el comportamiento predeterminado y el que nos interesa en un entorno de desarrollo.

Sin embargo, en otros entornos, o para casos concretos, igual queremos que un contenedor tenga el mismo estado en el que estaba antes de reiniciar la máquina (iniciado o parado).

Para eso usaremos el parámetro restart. En el caso de la base de datos de nuestro ejemplo, la configuración quedaría como:

docker-compose.yaml
services:
    db:
        image: mariadb:10
        restart: unless-stopped
        volumes:
            - data:/var/lib/mysql
        environment:
            - MYSQL_ROOT_PASSWORD=secret
            - MYSQL_DATABASE=wordpress
            - MYSQL_USER=manager
            - MYSQL_PASSWORD=secret

El equivalente en la consola sería:

$ docker run -d --name wordpress-db \
    --restart unless-stopped
    --mount source=wordpress-db,target=/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=secret \
    -e MYSQL_DATABASE=wordpress \
    -e MYSQL_USER=manager \
    -e MYSQL_PASSWORD=secret mariadb:10

Otros valores son: no (por defecto), always y on-failure.