Como usar o Docker Compose

Docker Compose é uma ferramenta que foi desenvolvida para ajudar a definir e compartilhar aplicativos de vários contêineres. Com o Compose, você pode criar um arquivo YAML para definir os serviços e, com um único comando, pode girar tudo ou destruir tudo.

A grande vantagem de usar o Compose é que você pode definir sua pilha de aplicativos em um arquivo, mantê-la na raiz do seu repo do projeto (agora ele é controlado por versão) e permitir facilmente que outra pessoa contribua com seu projeto. Alguém só precisaria clonar seu repo e iniciar o aplicativo de composição. Na verdade, você pode ver alguns projetos no GitHub/GitLab fazendo exatamente isso agora.

Então, como você começa?

Instalar o Docker Compose

Se você instalou o Docker Desktop para Windows ou Mac, você já tem Docker Compose! As instâncias do Play-with-Docker já Docker Compose instaladas também. Se você estiver em um computador Linux, precisará instalar o Docker Compose usando as instruções aqui.

Após a instalação, você deverá ser capaz de executar o seguinte e ver as informações de versão.

docker-compose version

Criar o arquivo de composição

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

  2. No arquivo de composição, vamos começar definindo a versão do esquema. Na maioria dos casos, é melhor usar a versão mais recente com suporte. Você pode ver a referência do arquivo Compose para as versões de esquema atuais e a matriz de compatibilidade.

    version: "3.7"
    
  3. Em seguida, defina a lista de serviços (ou contêineres) que você deseja executar como parte do seu aplicativo.

    version: "3.7"
    
    services:
    

E agora, você começará a migrar um serviço por vez para o arquivo de composição.

Definir o Serviço de Aplicativo

Para se lembrar, esse foi o comando usado para definir o contêiner do aplicativo (substitua os caracteres \ ` por em Windows PowerShell).

docker run -dp 3000:3000 \
  -w /app -v ${PWD}:/app \
  --network todo-app \
  -e MYSQL_HOST=mysql \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=secret \
  -e MYSQL_DB=todos \
  node:12-alpine \
  sh -c "yarn install && yarn run dev"
  1. Primeiro, defina a entrada de serviço e a imagem para o contêiner. Você pode escolher qualquer nome para o serviço. O nome se tornará automaticamente um alias de rede, o que será útil ao definir o serviço MySQL.

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
    
  2. Normalmente, você verá o comando próximo à definição, embora image não haja nenhum requisito de ordenação. Portanto, vá em frente e mova-o para o arquivo.

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
    
  3. Migre -p 3000:3000 a parte do comando definindo o ports para o serviço. Você usará a sintaxe curta aqui, mas também há uma sintaxe longa mais detalhada disponível.

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  4. Em seguida, migre o diretório de trabalho ( ) e -w /app o mapeamento de volume ( ) usando as -v ${PWD}:/app working_dir volumes definições e . Os volumes também têm uma sintaxe curta e longa.

    Uma vantagem de Docker Compose definições de volume é que você pode usar caminhos relativos do diretório atual.

    version: "3.7"
    
    services:
      app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
    
  5. Por fim, migre as definições de variável de ambiente usando a environment chave .

    version: "3.7"
    
    services:
      app:
        image: node:12-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: secret
          MYSQL_DB: todos
    

Definir o serviço MySQL

Agora, é hora de definir o serviço MySQL. O comando usado para esse contêiner era o seguinte (substitua os \ caracteres ` por em Windows PowerShell):

docker run -d \
  --network todo-app --network-alias mysql \
  -v todo-mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=todos \
  mysql:5.7
  1. Primeiro, defina o novo serviço e nomee-o mysql para que ele automaticamente obtém o alias de rede. Especifique a imagem a ser usada também.

    version: "3.7"
    
    services:
      app:
        # The app service definition
      mysql:
        image: mysql:5.7
    
  2. Em seguida, defina o mapeamento de volume. Quando você criou o contêiner com docker run , o volume nomeado foi criado automaticamente. No entanto, isso não acontece ao executar com o Compose. Você precisa definir o volume na seção de nível superior e especificar volumes: o ponto de montagem na configuração de serviço. Ao simplesmente fornecer apenas o nome do volume, as opções padrão são usadas. No entanto, há muitas outras opções disponíveis.

    version: "3.7"
    
    services:
      app:
        # The app service definition
      mysql:
        image: mysql:5.7
        volumes:
          - todo-mysql-data:/var/lib/mysql
    
    volumes:
      todo-mysql-data:
    
  3. Por fim, você só precisa especificar as variáveis de ambiente.

    version: "3.7"
    
    services:
      app:
        # The app service definition
      mysql:
        image: mysql:5.7
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: secret
          MYSQL_DATABASE: todos
    
    volumes:
      todo-mysql-data:
    

Neste ponto, o completo docker-compose.yml deve ter esta aparência:

version: "3.7"

services:
  app:
    image: node:12-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: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

Executar a pilha de aplicativos

Agora que você tem o docker-compose.yml arquivo, você pode in-locar!

  1. Primeiro, certifique-se de que nenhuma outra cópia do aplicativo e do banco de dados está em execução ( docker ps e docker rm -f <ids> ).

  2. Inicie a pilha de aplicativos usando o docker-compose up comando . Adicione o -d sinalizador para executar tudo em segundo plano. Como alternativa, você pode clicar com o botão direito do mouse no arquivo Compose e selecionar a opção Compor Up para a barra lateral VS Code lado.

    docker-compose up -d
    

    Ao executar isso, você deverá ver uma saída como esta:

    Creating network "app_default" with the default driver
    Creating volume "app_todo-mysql-data" with default driver
    Creating app_app_1   ... done
    Creating app_mysql_1 ... done
    

    Você observará que o volume foi criado, bem como uma rede! Por padrão, Docker Compose cria automaticamente uma rede especificamente para a pilha de aplicativos (por isso você não definiu uma no arquivo de composição).

  3. Veja os logs usando o docker-compose logs -f comando . Você verá os logs de cada um dos serviços intercalados em um único fluxo. Isso é incrivelmente útil quando você deseja observar problemas relacionados ao tempo. O -f sinalizador "segue" o log, portanto, lhe dará a saída ao vivo conforme ele é gerado.

    Caso ainda não tenha feito isso, você verá uma saída parecida com esta:

    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
    

    O nome do serviço é exibido no início da linha (geralmente colorido) para ajudar a distinguir mensagens. Se você quiser exibir os logs de um serviço específico, poderá adicionar o nome do serviço ao final do comando logs (por exemplo, docker-compose logs -f app ).

    Dica

    Aguardando o BD antes de iniciar o aplicativo Quando o aplicativo está iniciando, na verdade, ele fica e aguarda que o MySQL esteja pronto antes de tentar se conectar a ele. O Docker não tem suporte integrado para aguardar que outro contêiner esteja totalmente em funcionamento, em execução e pronto antes de iniciar outro contêiner. Para projetos baseados em Nó, você pode usar a dependência de porta de espera. Existem projetos semelhantes para outras linguagens/estruturas.

  4. Neste ponto, você deve ser capaz de abrir seu aplicativo e vê-lo em execução. E olá! Você está em um único comando!

Consulte a pilha de aplicativos na extensão do Docker

Se você olhar para a extensão do Docker, poderá alterar as opções de agrupamento usando a 'engrenagem' e 'agrupar por'. Nesta instância, você deseja ver contêineres agrupados por Project nome:

Extensão do VS com Compose

Se você girar a rede, verá os dois contêineres definidos no arquivo de composição.

Extensão do VS com o Compose expandido

Destruir tudo

Quando estiver pronto para destruir tudo, basta executar ou clicar com o botão direito do mouse no aplicativo na lista de contêineres na extensão VS Code do Docker e selecionar docker-compose down Compor. Os contêineres serão parados e a rede será removida.

Aviso

Removendo volumes Por padrão, os volumes nomeados no arquivo de composição NÃO são removidos durante a execução de docker-compose down . Se você quiser remover os volumes, precisará adicionar o --volumes sinalizador .

Depois de dividido, você pode alternar para outro projeto, executar docker-compose up e estar pronto para contribuir com esse projeto! Na verdade, não fica muito mais simples do que isso!

Recapitulação

Nesta seção, você aprendeu sobre a Docker Compose e como ela ajuda a simplificar drasticamente a definição e o compartilhamento de aplicativos de vários serviços. Você criou um arquivo Compose traduzindo os comandos que estava usando no formato de composição apropriado.

Neste ponto, você está começando a concluir o tutorial. No entanto, há algumas práticas recomendadas sobre a criação de imagens a abranger, pois há um grande problema com o Dockerfile que você está usando. Portanto, vamos dar uma olhada!

Próximas etapas

Continue com o tutorial!