Compartir a través de


Tutorial: Creación de aplicaciones de varios contenedores con MySQL y Docker Compose

En este artículo se describe cómo crear aplicaciones de varios contenedores con MySQL y Docker Compose. Una aplicación con varios contenedores permite dedicar contenedores para tareas especializadas, por lo que cada contenedor puede centrarse en una sola tarea. Hay muchas ventajas para usar aplicaciones de varios contenedores:

  • Los contenedores independientes permiten administrar las API y los recursos de front-end de forma diferente a las bases de datos.
  • Varios contenedores permiten la versión y actualización de las versiones de forma aislada.
  • Las bases de datos locales se pueden mantener en contenedores y servicios administrados usados para las bases de datos en producción.
  • Las aplicaciones de varios contenedores son más eficaces que ejecutar varios procesos con un administrador de procesos, lo que agrega complejidad al inicio o apagado del contenedor.

En este tutorial, usted:

  • Iniciar MySQL
  • Ejecuta tu aplicación multicontenedor con MySQL
  • Creación de un archivo de Docker Compose para la aplicación
  • Ejecución de la pila de aplicaciones con Docker Compose

Prerrequisitos

  • Este artículo forma parte de una serie de tutoriales. Los procedimientos se basan en un ejemplo establecido que requiere docker Desktop para contenedores de Linux.

    El enfoque recomendado es completar el primer tutorial, Creación de una aplicación de contenedor, incluido el cumplimiento de los requisitos previos, y también el tutorial , Conservación de datos en la aplicación. Después de realizar estos tutoriales, continúe con los procedimientos descritos en este artículo.

  • En el ejemplo de este artículo se usa Docker Compose.

    Docker Desktop para Windows incluye Docker Compose.

    Ejecute el siguiente comando para comprobar la instalación de Docker:

    docker-compose version
    

Código de Visual Studio

En esta serie de tutoriales se describen los procedimientos de Visual Studio Code (VS Code). Revise las consideraciones siguientes para trabajar en este entorno:

  • Use el menú izquierdo para cambiar entre la vista CONTAINER EXPLORER o EXPLORER (archivo y carpeta):

    Captura de pantalla que muestra el Explorador de contenedores y la vista Explorador de archivos o carpetas en Visual Studio Code.

  • Abra una ventana de línea de comandos en VS Code seleccionando Terminal>Nuevo terminal. También puede usar el método abreviado de teclado Ctrl+Mayús+` (tic atrás).

  • A menos que se especifique lo contrario, ejecute comandos en una ventana de Bash. La mayoría de los comandos etiquetados para Bash se ejecutan en una ventana de Bash o en la ventana de línea de comandos de VS Code.

Inicio del sistema de administración de bases de datos MySQL

De forma predeterminada, los contenedores se ejecutan de forma aislada. Un contenedor no tiene conocimiento de otros procesos ni de otros contenedores en el mismo ordenador.

Para habilitar la comunicación entre contenedores, deben asociarse a la misma red. Varios contenedores de la misma red pueden compartir datos y procesar información entre sí.

Hay dos maneras de conectar un contenedor a una red. Puede conectar un contenedor a una red durante la creación o adjuntar un contenedor existente a una red más adelante.

En este ejemplo, creará la red y asociará el contenedor mySQL al inicio.

  1. Cree una red denominada todo-app:

    docker network create todo-app
    
  2. Inicie un contenedor mySQL denominado todo-mysql-data y adjunte a la red de todo-app. El comando crea un alias de red mysql para la base de datos MySQL todos.

    Al ejecutar el comando, escriba la contraseña raíz de MySQL para el marcador de posición <your-password>.

    docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=<your-password> -e MYSQL_DATABASE=todos mysql:lts
    

    Este comando también define las variables de entorno MYSQL_ROOT_PASSWORD y MYSQL_DATABASE. Para obtener más información, consulte la lista de MySQL en Docker Hub .

    Advertencia

    En este tutorial se muestran las credenciales de contraseña para autenticarse con una base de datos MySQL, que no es el método más seguro. Consulte la documentación de MySQL para obtener más información sobre los métodos de autenticación más seguros.

  3. Obtenga el identificador de contenedor para usarlo en el paso siguiente.

    docker ps
    
  4. Confirme que puede conectarse al contenedor en la red mysql.

    Al ejecutar el comando, escriba el identificador del contenedor para el marcador de posición <mysql-container-id>.

    docker exec -it <mysql-container-id> mysql -p
    

    En el indicador de comando, escriba la contraseña que proporcionó al crear el contenedor de todo-mysql-data.

  5. En el shell de MySQL, enumere las bases de datos y compruebe que ve la base de datos todos.

    SHOW DATABASES;
    

    Debería ver los siguientes resultados:

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    
  6. Para finalizar la conexión y volver al símbolo de la línea de comandos, escriba salir.

Ejecución de la aplicación con MySQL

La aplicación todo admite la configuración de determinadas variables de entorno para especificar la configuración de conexión de MySQL. En la tabla siguiente se enumeran las variables admitidas y los valores usados en el ejemplo presentado en esta sección.

Nombre de variable Valor de ejemplo Descripción
MYSQL_HOST mysql Nombre de host del servidor MySQL.
MYSQL_USER root Nombre de usuario que se va a usar para la conexión.
MYSQL_PASSWORD <your-password> Contraseña que se va a usar para la conexión. En este ejemplo, sustituya su contraseña raíz por el marcador de posición <your-password>.
MYSQL_DATABASE todos Nombre de la base de datos que se va a usar después de establecer la conexión.

Advertencia

El uso de variables de entorno para establecer la configuración de conexión es aceptable para el desarrollo, pero esta práctica no se recomienda para ejecutar aplicaciones en producción. Para obtener más información, consulte ¿Por qué no debe usar variables de entorno para los datos secretos.

Un mecanismo más seguro consiste en usar la compatibilidad con secretos que proporciona el marco de orquestación de contenedores. En la mayoría de los casos, estos secretos se montan como archivos en el contenedor en ejecución.

En el ejemplo siguiente, iniciará la aplicación y conectará el contenedor de aplicaciones al contenedor de MySQL.

  1. Ejecute el siguiente comando docker. Observe cómo el comando especifica las variables de entorno descritas anteriormente.

    Al ejecutar el comando, no olvide escribir la contraseña raíz de MySQL para el marcador de posición <your-password>.

    docker run -dp 3000:3000 -w /app -v ${PWD}:/app --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=<your-password> -e MYSQL_DB=todos node:lts-alpine sh -c "yarn install && yarn run dev"
    
  2. En el editor de VS Code, abra el Explorador de contenedores, haga clic con el botón derecho en el contenedor de la aplicación y seleccione Ver registros.

    También puede ver los registros desde la línea de comandos mediante el comando docker logs.

  3. Revise la salida del registro. Observe la línea que indica que la aplicación está conectada a la base de datos MySQL: Connected to mysql db at host mysql.

    # Previous log messages omitted
    $ nodemon src/index.js
    [nodemon] 1.19.2
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching dir(s): *.*
    [nodemon] starting `node src/index.js`
    Connected to mysql db at host mysql
    Listening on port 3000
    
  4. En el explorador de Internet, vaya a la aplicación en ejecución: http://localhost:3000.

  5. En la aplicación en ejecución, agregue algunos elementos a la lista de tareas pendientes.

  6. Conéctese a la base de datos de contenedor de MySQL en la red mysql para que pueda comprobar la base de datos.

    Al ejecutar el comando, escriba el identificador del contenedor para el marcador de posición <mysql-container-id>.

    docker exec -ti <mysql-container-id> mysql -p todos
    

    En el indicador de comando, escriba la contraseña que proporcionó al crear el contenedor de todo-mysql-data.

  7. En el shell de MySQL, compruebe que los todo_items que agregó están escritos en la base de datos de todos.

    use todos;
    select * from todo_items;
    

    Debería ver una salida similar a la del ejemplo siguiente:

    +--------------------------------------+--------------------+-----------+
    | id                                   | name               | completed |
    +--------------------------------------+--------------------+-----------+
    | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! |         0 |
    | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome!        |         0 |
    +--------------------------------------+--------------------+-----------+
    

Ahora tiene una aplicación que almacena datos en una base de datos externa que se ejecuta en un contenedor independiente. En este procedimiento se muestra cómo se puede habilitar la comunicación entre contenedores mediante redes.

Creación de un archivo de Docker Compose

Docker Compose le ayuda a definir y compartir aplicaciones de varios contenedores. Un archivo de Docker Compose puede especificar todos los servicios necesarios, por lo que puede iniciar o finalizar todos los procesos relacionados con un único comando. Puede definir la pila de aplicaciones en un archivo de Docker Compose en la raíz del repositorio del proyecto y mantener la configuración bajo el control de versiones. Este enfoque permite que otros usuarios contribuyan al proyecto al clonar el repositorio.

En el siguiente ejemplo, configure un archivo Docker Compose para su aplicación multicontenedor todo.

  1. En la raíz del proyecto de aplicación de todo, cree un archivo de Docker Compose denominado docker-compose.yml.

    Nota

    De forma predeterminada, la versión del esquema YAML se establece en la versión más reciente. Al ejecutar la aplicación, si la versión del esquema está obsoleta, recibirá un mensaje de advertencia. Para revisar las versiones de esquema actuales y una matriz de compatibilidad, consulte Información general (archivo Compose).

  2. En el archivo docker-compose.yml, agregue los siguientes elementos. Especifique la aplicación name e inicie la lista de services (o contenedores) que desea ejecutar como parte de la aplicación.

    name: todo
    
    services:
    

    La lista de servicios es única para la aplicación. Entre los ejemplos se incluyen app, web, db, proxy, etc. Amplíe la definición del elemento services en un paso posterior.

    Sugerencia

    La sangría es importante en los archivos .yml. Si está editando en VS Code, IntelliSense indica los errores en el formato o sintaxis.

  3. Vuelva a la definición de services en el archivo docker-compose.yml. Amplíe la definición agregando una entrada para definir el elemento de servicio app, que incluye la imagen del contenedor.

    services:
      app:
        image: node:lts-alpine
    

    Puede elegir cualquier nombre para el servicio. El nombre se convierte automáticamente en un alias de red, que resulta útil al definir el servicio MySQL.

  4. Extienda la definición del elemento app para especificar un command que se va a ejecutar.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
    
  5. Defina el ports para usarlo con el servicio app. Observe que estos puertos corresponden al argumento -p 3000:3000 del comando que se usa para ejecutar la aplicación con MySQL.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  6. Identifique el directorio de trabajo working_dir para el servicio app y también el volumes asignado.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
    

    Al definir volúmenes de Docker Compose, puede usar rutas de acceso relativas basadas en el directorio actual.

  7. Especifique las definiciones de variables environment que se usarán cuando ejecute comandos para el servicio app.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: <your-password>
          MYSQL_DB: todos
    

    No olvide escribir la contraseña raíz de MySQL para el marcador de posición <your-password>.

  8. Agregue la definición del servicio MySQL mysql después de la definición del servicio app. Especifique los nombres y valores de elemento como se muestra y con la misma sangría.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
    

    La definición del servicio mysql corresponde al comando que usó anteriormente para iniciar MySQL. Al definir el servicio, recibe automáticamente el alias de red.

  9. Identifique el volumes asignado para el servicio mysql.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
    
  10. Especifique las definiciones de variables environment que se usarán cuando ejecute comandos para el servicio mysql.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: <your-password>
          MYSQL_DATABASE: todos
    

    No olvide escribir la contraseña raíz de MySQL para el marcador de posición <your-password>.

  11. Defina la asignación de volúmenes para toda la aplicación. Agregue una sección de volumes: después de la sección services: y con la misma sangría.

    services:
       ...
    
    volumes:
      todo-mysql-data:
    
  12. Confirme que el archivo docker-compose.yml completado tiene un aspecto similar al del ejemplo siguiente. Debería consultar la contraseña raíz de MySQL para el marcador de posición <your-password>.

    name: todo
    
    services:
      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: <your-password>
          MYSQL_DB: todos
    
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: <your-password>
          MYSQL_DATABASE: todos
    
    volumes:
      todo-mysql-data:
    

Ejecución de la pila de aplicaciones con Docker Compose

Ahora puede intentar ejecutar el archivo docker-compose.yml.

  1. Detenga las instancias en ejecución de la aplicación y la base de datos.

    Siga estos pasos en VS Code:

    1. Abra CONTAINER EXPLORER (extensión Container Tools).

    2. Para cada contenedor en ejecución, haga clic con el botón derecho en el contenedor y seleccione Quitar.

  2. Inicie la aplicación de varios contenedores y todos los servicios.

    Siga estos pasos en VS Code:

    1. Abra la vista EXPLORER (archivo y carpeta).

    2. Haga clic con el botón derecho en el archivo docker-compose.yml y seleccione Compose Up.

    Debería ver una salida similar a la del ejemplo siguiente:

    [+] Building 0.0s (0/0)
    [+] Running 2/2
    ✔ Container app-app-1    Started  0.9s 
    ✔ Container app-mysql-1  Running
    

    Esta operación crea el volumen asignado para la aplicación y la red. De forma predeterminada, Docker Compose crea una red específicamente para la pila de aplicaciones.

  3. Revise los registros del contenedor en ejecución.

    Siga estos pasos en VS Code:

    1. Abra CONTAINER EXPLORER (extensión Container Tools).

    2. Haga clic con el botón derecho en el contenedor de aplicaciones y seleccione Ver registros.

    Debería ver una salida similar a la del ejemplo siguiente:

    mysql_1  | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections.
    mysql_1  | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
    app_1    | Connected to mysql db at host mysql
    app_1    | Listening on port 3000
    

    Los registros muestran el nombre del servicio y el número de instancia, como app_1 al principio de cada línea. Este formato le ayuda a distinguir mensajes por servicio e instancia. Los registros de cada servicio se intercalan en una sola secuencia. Este enfoque le permite observar los problemas relacionados con el tiempo.

  4. Ahora puede ir a la aplicación en ejecución en su navegador web: http://localhost:3000.

Detener Docker Compose y la ejecución de contenedores

Cuando haya terminado con la aplicación y los contenedores, puede quitarlos.

Siga estos pasos en VS Code:

  1. Abra la vista EXPLORER (archivo y carpeta).

  2. Haga clic con el botón derecho en el archivo docker-compose.yml y seleccione Redactar abajo.

Esta operación detiene todos los contenedores en ejecución y elimina la red.

De forma predeterminada, los volúmenes con nombre en tu archivo compose no se eliminan. Si desea quitar estos volúmenes, puede usar el comando docker-compose down --volumes.

Limpieza de recursos

Si aplicó los componentes de requisitos previos de esta serie de tutoriales a la instalación, puede reutilizar la configuración para el desarrollo futuro de Docker. No es esencial eliminar ni desinstalar ningún componente.