Partilhar via


Tutorial: Criar aplicativos de vários contêineres com MySQL e Docker Compose

Este artigo descreve como criar aplicativos de vários contêineres com o MySQL e Docker Compose. Um aplicativo com vários contêineres permite que você dedique contêineres para tarefas especializadas, para que cada contêiner possa se concentrar em uma única tarefa. Há muitas vantagens em usar aplicativos de vários contêineres:

  • Contêineres separados permitem que você gerencie APIs e recursos front-end de forma diferente dos bancos de dados.
  • Vários contêineres permitem que você faça versões e atualizem versões isoladamente.
  • Os bancos de dados locais podem ser mantidos em contêineres e serviços gerenciados usados para bancos de dados em produção.
  • Os aplicativos de vários contêineres são mais eficientes do que executar vários processos com um gerenciador de processos, o que adiciona complexidade à inicialização/desligamento do contêiner.

Neste tutorial, você:

  • Iniciar o MySQL
  • Execute seu aplicativo de vários contêineres com o MySQL
  • Criar um arquivo Docker Compose para seu aplicativo
  • Execute a stack de aplicações com o Docker Compose

Pré-requisitos


Código do Visual Studio

Esta série de tutoriais descreve procedimentos para Visual Studio Code (VS Code). Analise as seguintes considerações para trabalhar neste ambiente:

  • Use o menu esquerdo para alternar entre o CONTAINER EXPLORER ou o modo de exibição EXPLORER (arquivo e pasta):

    Captura de tela que mostra o Container Explorer e o modo de exibição de arquivo/pasta Explorer no Visual Studio Code.

  • Abra uma janela de linha de comando no VS Code selecionando Terminal>Novo Terminal. Você também pode usar o atalho de teclado Ctrl+Shift+` (acento grave).

  • A menos que especificado de outra forma, execute comandos em uma janela Bash. A maioria dos comandos rotulados para Bash se executam numa janela Bash ou na janela de linha de comandos do VS Code.

Iniciar o sistema de gerenciamento de banco de dados MySQL

Por padrão, os contêineres são executados isoladamente. Um contêiner não está ciente de outros processos ou outros contêineres no mesmo computador.

Para permitir a comunicação entre contêineres, eles precisam se conectar à mesma rede. Vários contêineres na mesma rede podem compartilhar dados e processar informações uns com os outros.

Há duas maneiras de anexar um contêiner a uma rede. Você pode anexar um contêiner a uma rede durante a criação ou anexar um contêiner existente a uma rede posteriormente.

Neste exemplo, você cria a rede e anexa o contêiner MySQL na inicialização.

  1. Crie uma rede chamada todo-app:

    docker network create todo-app
    
  2. Inicie um contêiner MySQL chamado todo-mysql-data e anexe-o à rede todo-app. O comando cria um alias de rede mysql para o banco de dados MySQL todos.

    Quando você executar o comando, digite sua senha de root do MySQL para o espaço reservado <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 também define as variáveis de ambiente MYSQL_ROOT_PASSWORD e MYSQL_DATABASE. Para obter mais informações, consulte listagem do MySQL Docker Hub.

    Advertência

    Este tutorial ilustra credenciais de senha para autenticar com um banco de dados MySQL, que não é o método mais seguro. Consulte o de documentação do MySQL para saber mais sobre métodos mais seguros de autenticação.

  3. Obtenha seu ID de contêiner para uso na próxima etapa.

    docker ps
    
  4. Confirme se você pode se conectar ao contêiner na rede mysql.

    Ao executar o comando, insira o ID do contêiner para o espaço reservado <mysql-container-id>.

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

    No prompt, digite a senha que você forneceu quando criou o contêiner todo-mysql-data.

  5. No shell do MySQL, liste os bancos de dados e verifique se você vê o banco de dados todos.

    SHOW DATABASES;
    

    Você deve ver a seguinte saída:

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    
  6. Para encerrar a conexão e retornar ao prompt de linha de comando, digite exit.

Execute seu aplicativo com o MySQL

O aplicativo todo suporta a configuração de determinadas variáveis de ambiente para especificar suas configurações de conexão MySQL. A tabela a seguir lista as variáveis suportadas e os valores usados no exemplo apresentado nesta seção.

Nome da variável Valor de exemplo Descrição
MYSQL_HOST mysql O nome do host para o servidor MySQL.
MYSQL_USER root O nome de usuário a ser usado para a conexão.
MYSQL_PASSWORD <your-password> A senha a ser usada para a conexão. Neste exemplo, substitua a sua senha de root pelo marcador de posição <your-password>.
MYSQL_DATABASE todos O nome do banco de dados a ser usado após a conexão ser estabelecida.

Advertência

O uso de variáveis de ambiente para definir configurações de conexão é aceitável para desenvolvimento, mas essa prática não é recomendada para executar aplicativos em produção. Para obter mais informações, consulte Por que você não deve usar variáveis de ambiente para dados secretos.

Um mecanismo mais seguro é usar o suporte secreto fornecido pela sua estrutura de orquestração de contêineres. Na maioria dos casos, esses segredos são montados como arquivos no contêiner em execução.

No exemplo a seguir, você inicia seu aplicativo e conecta seu contêiner de aplicativo ao seu contêiner MySQL.

  1. Execute o seguinte comando docker. Observe como o comando especifica as variáveis de ambiente descritas anteriormente.

    Quando você executar o comando, lembre-se de digitar sua senha de root do MySQL para o espaço reservado <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. No editor do VS Code, abra o Gerenciador de Contêineres, clique com o botão direito do mouse no contêiner do aplicativo e selecione Exibir Logs.

    Você também pode exibir os logs da linha de comando usando o comando docker logs.

  3. Revise a saída do log. Observe a linha que indica que o aplicativo está conectado ao banco de dados 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. No seu navegador de internet, vá para o seu aplicativo em execução: http://localhost:3000.

  5. Em seu aplicativo em execução, adicione alguns itens à sua lista de tarefas.

  6. Conecte-se ao banco de dados de contêiner MySQL na rede mysql para que você possa verificar o banco de dados.

    Ao executar o comando, insira o ID do contêiner para o espaço reservado <mysql-container-id>.

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

    No prompt, digite a senha que você forneceu quando criou o contêiner todo-mysql-data.

  7. No shell do MySQL, verifique se os todo_items adicionados estão gravados no banco de dados todos.

    use todos;
    select * from todo_items;
    

    Você deve ver uma saída semelhante ao exemplo a seguir:

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

Agora você tem um aplicativo que armazena dados em um banco de dados externo em execução em um contêiner separado. Este procedimento demonstra como você pode habilitar a comunicação entre contêineres usando a rede.

Criar arquivo de composição do Docker

O Docker Compose ajuda você a definir e compartilhar aplicativos de vários contêineres. Um arquivo Docker Compose pode especificar todos os serviços necessários, para que você possa iniciar ou terminar todos os processos relacionados com um único comando. Você pode definir sua pilha de aplicativos em um arquivo Docker Compose na raiz do repositório do projeto e manter sua configuração sob controle de versão. Essa abordagem permite que outras pessoas contribuam para o seu projeto quando clonarem seu repositório.

No exemplo a seguir, você configura um arquivo Docker Compose para seu aplicativo de vários contêineres todo.

  1. Na raiz do seu projeto de aplicativo todo, crie um arquivo Docker Compose chamado docker-compose.yml.

    Observação

    Por padrão, a versão do esquema YAML é definida como a versão mais recente. Ao executar seu aplicativo, se a versão do esquema estiver obsoleta, você receberá uma mensagem de aviso. Para revisar as versões atuais do esquema e uma matriz de compatibilidade, consulte Visão geral do (arquivo de composição).

  2. No arquivo docker-compose.yml, adicione os seguintes elementos. Especifique a sua aplicação name e inicie a lista de services (ou contentores) que pretende executar como parte da sua aplicação.

    name: todo
    
    services:
    

    A lista de serviços é exclusiva para seu aplicativo. Exemplos incluem app, web, db, proxye assim por diante. Você estende a definição para o elemento services em uma etapa posterior.

    Dica

    O recuo é significativo em .yml arquivos. Se estiver editando no VS Code, o Intellisense indica quaisquer erros no formato ou na sintaxe.

  3. Retorne à definição de services no arquivo docker-compose.yml. Estenda a definição adicionando uma entrada para definir o elemento de serviço app, que inclui a imagem para o contêiner.

    services:
      app:
        image: node:lts-alpine
    

    Você pode escolher qualquer nome para o serviço. O nome torna-se automaticamente um alias de rede, o que é útil quando você define o serviço MySQL.

  4. Estenda a definição do elemento app para especificar um command a ser executado.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
    
  5. Defina o ports a ser usado com o serviço app. Observe que essas portas correspondem ao argumento -p 3000:3000 para o comando usado para executar o aplicativo com o MySQL.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  6. Identifique o diretório de trabalho working_dir para o serviço app e também o volumesmapeado.

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

    Ao definir volumes de composição do Docker, você pode usar caminhos relativos com base no diretório atual.

  7. Especificar definições de variáveis environment para usar ao executar comandos para o serviço 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
    

    Lembre-se de digitar sua senha de root do MySQL para o espaço reservado <your-password>.

  8. Adicione a definição para o serviço MySQL mysql após a definição de serviço app. Especifique os nomes e valores dos elementos conforme mostrado e com o mesmo recuo.

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

    A definição de serviço mysql corresponde ao comando que você usou anteriormente para iniciar o MySQL. Quando você define o serviço, ele recebe automaticamente o alias de rede.

  9. Identifique o volumes mapeado para o serviço mysql.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
    
  10. Especificar definições de variáveis environment para usar ao executar comandos para o serviço mysql.

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

    Lembre-se de digitar sua senha de root do MySQL para o espaço reservado <your-password>.

  11. Defina o mapeamento de volume para todo o aplicativo. Adicione uma seção volumes: após a seção services: e com o mesmo recuo.

    services:
       ...
    
    volumes:
      todo-mysql-data:
    
  12. Confirme se o arquivo docker-compose.yml concluído se parece com o exemplo a seguir. Você deve ver a sua senha de root do MySQL para o placeholder <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:
    

Execute a stack de aplicações com o Docker Compose

Agora você pode tentar executar seu arquivo docker-compose.yml.

  1. Pare todas as instâncias em execução do seu aplicativo e banco de dados.

    Siga estes passos no VS Code:

    1. Abra o CONTAINER EXPLORER (extensão Container Tools).

    2. Para cada contêiner em execução, clique com o botão direito do mouse no contêiner e selecione Remover.

  2. Inicie seu aplicativo de vários contêineres e todos os serviços.

    Siga estes passos no VS Code:

    1. Abra a vista EXPLORER (ficheiros e pastas).

    2. Clique com o botão direito do mouse no arquivo docker-compose.yml e selecione Compor.

    Você deve ver uma saída semelhante ao exemplo a seguir:

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

    Esta operação cria o volume mapeado para o aplicativo e a rede. Por padrão, o Docker Compose cria uma rede especificamente para a pilha de aplicativos.

  3. Revise os logs do contêiner em execução.

    Siga estes passos no VS Code:

    1. Abra o CONTAINER EXPLORER (extensão Container Tools).

    2. Clique com o botão direito do mouse no contêiner do aplicativo e selecione Exibir logs .

    Você deve ver uma saída semelhante ao exemplo a seguir:

    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
    

    Os logs mostram o nome do serviço e o número da instância, como app_1 no início de cada linha. Esse formato ajuda a distinguir mensagens por serviço e instância. Os logs de cada serviço são intercalados em um único fluxo. Essa abordagem permite que você fique atento a problemas relacionados ao tempo.

  4. Agora você pode ir para o seu aplicativo em execução no seu navegador de internet: http://localhost:3000.

Parar a composição do Docker e a execução de contêineres

Quando terminar de usar o aplicativo e os contêineres, você poderá removê-los.

Siga estes passos no VS Code:

  1. Abra a vista EXPLORER (ficheiros e pastas).

  2. Clique com o botão direito do rato no ficheiro docker-compose.yml e selecione Redigir.

Esta operação interrompe todos os contentores em execução e remove a rede.

Por padrão, os volumes nomeados no arquivo de composição não são removidos. Se quiser remover esses volumes, você pode usar o comando docker-compose down --volumes.

Limpar recursos

Se você aplicou os Pré-requisitos componentes desta série de tutoriais à sua instalação, poderá reutilizar a configuração para desenvolvimento futuro do Docker. Não é essencial excluir ou desinstalar qualquer componente.