Pesquisa de site

Como Instalar e Usar o Docker Compose no Ubuntu


Introdução

O Docker simplifica o processo de gerenciamento de processos de aplicativos em contêineres. Embora os contêineres sejam semelhantes às máquinas virtuais em certos aspectos, eles são mais leves e economizam recursos. Isso permite que os desenvolvedores dividam o ambiente de um aplicativo em múltiplos serviços isolados.

Para aplicações que dependem de vários serviços, orquestrar todos os contêineres para iniciar, se comunicar e desligar juntos pode se tornar rapidamente complicado. O Docker Compose é uma ferramenta que permite executar ambientes de aplicação com múltiplos contêineres com base em definições estabelecidas em um arquivo YAML. Ele utiliza definições de serviços para construir ambientes totalmente personalizáveis com múltiplos contêineres que podem compartilhar redes e volumes de dados.

Este guia irá orientá-lo na instalação do Docker Compose em um servidor Ubuntu e na execução de um container simples. A partir daí, você aprenderá a construir um ambiente com múltiplos serviços usando uma aplicação WordPress e um banco de dados MySQL. Também abordaremos tópicos mais avançados, incluindo escalonamento de serviços, definição de redes personalizadas e uso de diretivas modulares de inclusão. Por fim, este artigo fornece um guia de migração do antigo docker-compose (v1) para o moderno docker compose (v2) e uma seção detalhada sobre resolução de problemas comuns, como conflitos de portas e erros de permissão.

Principais Conclusões:

  • Docker Compose é uma ferramenta para definir e executar aplicações com múltiplos contêineres usando um único arquivo YAML para configurar serviços, redes e volumes.
  • O Docker Compose é instalado no Ubuntu adicionando o repositório oficial do Docker e usando o apt para instalar o pacote docker-compose-plugin.
  • O comando moderno é docker compose (com um espaço). Isso substitui a ferramenta v1 docker-compose (com um hífen), que está obsoleta.
  • Use docker compose up -d para iniciar uma aplicação em modo destacado e docker compose down para parar e remover todos os seus contêineres e redes.
  • A diretiva depends_on ajuda a controlar a ordem de inicialização dos serviços, garantindo, por exemplo, que um contêiner de banco de dados seja iniciado antes de um contêiner de aplicação web.
  • Os problemas mais frequentes são “Permissão Negada” (resolvido adicionando seu usuário ao grupo docker), conflitos de portas (resolvidos alterando a porta do host no arquivo YAML) e erros de sintaxe em YAML (resolvidos corrigindo a indentação).
  • Você pode executar múltiplas instâncias de um serviço usando o comando docker compose up --scale <nome_do_serviço>=<número>.
  • A diretiva include permite dividir um grande arquivo docker-compose.yml em arquivos de configuração menores e mais fáceis de gerenciar.

Pré-requisitos

Para acompanhar este artigo, você precisará de:

  • Acesso a uma máquina local Ubuntu ou servidor de desenvolvimento como um usuário não-root com privilégios de sudo. Se você estiver usando um servidor remoto, é recomendável ter um firewall ativo instalado. Para configurá-los, consulte nosso Guia de Configuração Inicial de Servidor para Ubuntu.
  • Docker instalado no seu servidor ou máquina local, seguindo Passos 1 e 2 de Como Instalar o Docker no Ubuntu – Guia Passo a Passo.

Observação: A partir do Docker Compose v2, o Docker passou a utilizar o comando do plugin CLI compose, deixando de lado o docker-compose original, conforme documentado em nosso Guia Passo a Passo de Como Instalar o Docker Compose no Ubuntu. Embora a instalação seja diferente, em geral, o uso real consiste em remover o hífen das chamadas docker-compose, que passam a ser docker compose. Para obter detalhes completos sobre compatibilidade, consulte a documentação oficial do Docker sobre compatibilidade de comandos entre o novo compose e o antigo docker-compose.

Passo 1 — Instalando o Docker Compose

Existem duas maneiras de instalar o Docker Compose no Ubuntu:

  • Instale usando o repositório
  • Instalar manualmente

Nós discutiremos ambas as maneiras nesta seção.

Instalando o Docker Compose usando o repositório apt

Primeiro, vamos configurar o repositório apt do Docker.

# Add Docker's official GPG key:

sudo apt-get update

sudo apt-get install ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

sudo chmod a+r /etc/apt/keyrings/docker.asc



# Add the repository to Apt sources:

echo \

  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \

  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \

  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

Agora, você pode instalar o Docker Compose usando o seguinte comando:

sudo apt install docker-compose-plugin

O Docker Compose agora está instalado com sucesso no seu sistema. Para verificar se a instalação foi bem-sucedida, você pode executar:

docker compose version

Você verá uma saída semelhante a esta:

Docker Compose version v2.3.3

Instalando o Docker Compose manualmente

Para garantir que você obtenha a versão estável mais atualizada do Docker Compose, você fará o download deste software do seu repositório oficial no Github.

Primeiro, confirme a versão mais recente disponível na página de releases deles. No momento em que este texto foi escrito, a versão estável mais atual é v2.40.2.

Use o seguinte comando para baixar:

mkdir -p ~/.docker/cli-plugins/

curl -SL https://github.com/docker/compose/releases/download/v2.40.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose

Em seguida, defina as permissões corretas para que o comando docker compose seja executável:

chmod +x ~/.docker/cli-plugins/docker-compose

Na próxima seção, você verá como configurar um arquivo docker-compose.yml e colocar um ambiente conteinerizado em funcionamento com esta ferramenta.

Passo 2 — Configurando um arquivo docker-compose.yml

Para demonstrar como configurar um arquivo docker-compose.yml e trabalhar com o Docker Compose, você vai criar um ambiente de servidor web usando a imagem oficial do Nginx do Docker Hub, o registro público do Docker. Esse ambiente em contêiner servirá um único arquivo HTML estático.

Comece criando um novo diretório na sua pasta inicial e, em seguida, entrando nele:

mkdir ~/compose-demo

cd ~/compose-demo

Neste diretório, configure uma pasta de aplicação para servir como a raiz de documentos do seu ambiente Nginx:

mkdir app

Usando seu editor de texto preferido, crie um novo arquivo index.html dentro da pasta app:

nano app/index.html

Coloque o seguinte conteúdo neste arquivo:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Docker Compose Demo</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css">
</head>
<body>

    <h1>This is a Docker Compose Demo Page.</h1>
    <p>This content is being served by an Nginx container.</p>

</body>
</html>

Salve e feche o arquivo quando terminar. Se você estiver usando nano, pode fazer isso digitando CTRL+X, depois Y e ENTER para confirmar.

Em seguida, crie o arquivo docker-compose.yml:

nano docker-compose.yml

Insira o seguinte conteúdo no seu arquivo docker-compose.yml:

services:
  web:
    image: nginx:alpine
    ports:
      - "8000:80"
    volumes:
      - ./app:/usr/share/nginx/html

No Docker Compose moderno, o campo version é opcional e muitas vezes é omitido, pois o Compose pode detectar automaticamente a versão da configuração. O exemplo acima não inclui um campo version, que é a abordagem recomendada para a maioria dos novos projetos. Você só precisa especificar version para compatibilidade com versões antigas.

Você então tem o bloco services, onde você configura os serviços que fazem parte deste ambiente. No seu caso, você tem um único serviço chamado web. Este serviço usa a imagem nginx:alpine e configura um redirecionamento de porta com a diretiva ports. Todas as requisições na porta 8000 da máquina host (o sistema de onde você está executando o Docker Compose) serão redirecionadas para o contêiner web na porta 80, onde o Nginx estará em execução.

A diretiva volumes criará um volume compartilhado entre a máquina host e o contêiner. Isso compartilhará a pasta local app com o contêiner, e o volume estará localizado em /usr/share/nginx/html dentro do contêiner, o que irá sobrescrever o diretório raiz padrão de documentos do Nginx.

Salve e feche o arquivo.

Você configurou uma página de demonstração e um arquivo docker-compose.yml para criar um ambiente de servidor web containerizado que irá servi-la. No próximo passo, você vai inicializar esse ambiente com o Docker Compose.

Etapa 3 — Executando o Docker Compose

Com o arquivo docker-compose.yml no lugar, você agora pode executar o Docker Compose para iniciar seu ambiente. O comando a seguir irá baixar as imagens Docker necessárias, criar um contêiner para o serviço web e executar o ambiente em contêiner em modo de segundo plano:

docker compose up -d

O Docker Compose primeiro procurará pela imagem definida em seu sistema local e, se não conseguir localizar a imagem, ela será baixada do Docker Hub. Você verá uma saída como esta:

Creating network "compose-demo_default" with the default driver
Pulling web (nginx:alpine)...
alpine: Pulling from library/nginx
cbdbe7a5bc2a: Pull complete
10c113fb0c77: Pull complete
9ba64393807b: Pull complete
c829a9c40ab2: Pull complete
61d685417b2f: Pull complete
Digest: sha256:57254039c6313fe8c53f1acbf15657ec9616a813397b74b063e32443427c5502
Status: Downloaded newer image for nginx:alpine
Creating compose-demo_web_1 ... done

Observação: Se você encontrar um erro de “permissão negada” ao executar docker compose up, isso geralmente significa que seu usuário não root não tem permissão para acessar o socket do daemon do Docker.

Por padrão, o daemon do Docker se conecta a um socket Unix (/var/run/docker.sock) que é de propriedade do usuário root. Para resolver isso, você deve adicionar seu usuário não-root ao grupo docker, que é criado durante a instalação do Docker.

Execute o seguinte comando para adicionar seu usuário ao grupo docker:

sudo usermod -aG docker ${USER}

Após executar este comando, você precisará sair e entrar novamente para que as alterações de grupo tenham efeito. Você também pode ativar as alterações na sessão atual do terminal digitando:

newgrp docker

Este comando deve resolver quaisquer erros de permissão relacionados ao socket do Docker. Para um guia completo, consulte Passo 2 de Como Instalar o Docker no Ubuntu – Guia Passo a Passo.

Seu ambiente agora está ativo em segundo plano. Para verificar se o contêiner está ativo, você pode executar:

docker compose ps

Este comando mostrará informações sobre os contêineres em execução e seu estado, assim como quaisquer redirecionamentos de porta atualmente em vigor:

       Name                     Command               State          Ports        
----------------------------------------------------------------------------------
compose-demo_web_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8000->80/tcp

Agora você pode acessar o aplicativo de demonstração apontando seu navegador para localhost:8000 se você estiver executando esta demonstração na sua máquina local, ou seu_domínio_ou_IP_do_servidor:8000 se você estiver executando esta demonstração em um servidor remoto.

Você verá uma página assim:

O volume compartilhado que você configurou no arquivo docker-compose.yml mantém os arquivos da pasta app sincronizados com a raiz de documentos do container. Se você fizer qualquer alteração no arquivo index.html, elas serão automaticamente detectadas pelo container e, assim, refletidas no seu navegador quando você recarregar a página.

No próximo passo, você verá como gerenciar seu ambiente conteinerizado com comandos do Docker Compose.

Passo 4 — Familiarizando-se com os Comandos do Docker Compose

Você viu como configurar um arquivo docker-compose.yml e levantar seu ambiente com docker compose up. Agora você verá como usar os comandos do Docker Compose para gerenciar e interagir com seu ambiente conteinerizado.

Para verificar os logs produzidos pelo seu contêiner Nginx, você pode usar o comando logs:

docker compose logs

Você verá uma saída semelhante a esta:

Attaching to compose-demo_web_1
web_1  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
web_1  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
web_1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
web_1  | 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
web_1  | 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
web_1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
web_1  | /docker-entrypoint.sh: Configuration complete; ready for start up
web_1  | 172.22.0.1 - - [02/Jun/2020:10:47:13 +0000] "GET / HTTP/1.1" 200 353 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" "-"

Se você quiser pausar a execução do ambiente sem alterar o estado atual dos seus contêineres, você pode usar:

docker compose pause
Pausing compose-demo_web_1 ... done

Para retomar a execução após emitir uma pausa:

docker compose unpause
Unpausing compose-demo_web_1 ... done

O comando stop irá encerrar a execução do contêiner, mas não destruirá nenhum dado associado aos seus contêineres:

docker compose stop
Stopping compose-demo_web_1 ... done

Se você quiser remover os containers, redes e volumes associados a este ambiente conteinerizado, use o comando down:

docker compose down
Removing compose-demo_web_1 ... done
Removing network compose-demo_default

Observe que isso não removerá a imagem base usada pelo Docker Compose para iniciar seu ambiente (no seu caso, nginx:alpine). Dessa forma, sempre que você iniciar seu ambiente novamente com um docker compose up, o processo será muito mais rápido, já que a imagem já está no seu sistema.

Caso você também queira remover a imagem base do seu sistema, você pode usar:

docker image rm nginx:alpine
Untagged: nginx:alpine
Untagged: nginx@sha256:b89a6ccbda39576ad23fd079978c967cecc6b170db6e7ff8a769bf2259a71912
Deleted: sha256:7d0cdcc60a96a5124763fddf5d534d058ad7d0d8d4c3b8be2aefedf4267d0270
Deleted: sha256:05a0eaca15d731e0029a7604ef54f0dda3b736d4e987e6ac87b91ac7aac03ab1
Deleted: sha256:c6bbc4bdac396583641cb44cd35126b2c195be8fe1ac5e6c577c14752bbe9157
Deleted: sha256:35789b1e1a362b0da8392ca7d5759ef08b9a6b7141cc1521570f984dc7905eb6
Deleted: sha256:a3efaa65ec344c882fe5d543a392a54c4ceacd1efd91662d06964211b1be4c08
Deleted: sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a

Nota: Por favor, consulte nosso guia sobre Como Instalar o Docker no Ubuntu – Guia Passo a Passo para uma referência mais detalhada sobre os comandos do Docker.

Passo 5 — Construindo uma Aplicação Multi-Serviço

O verdadeiro poder do Docker Compose está em gerenciar múltiplos serviços que trabalham juntos. O exemplo do Nginx era um serviço único. Vamos criar uma aplicação mais prática, com múltiplos serviços: um site WordPress conectado a um banco de dados MySQL.

Esta configuração envolve dois serviços: wordpress (executando a aplicação) e db (executando o banco de dados). Também usaremos volumes do Docker para garantir que os dados do banco de dados persistam mesmo se o contêiner for removido.

Vamos criar um novo diretório para este aplicativo:

mkdir -p ~/compose-demo/wordpressapp

cd ~/compose-demo/wordpressapp

Para este exemplo, não precisamos de arquivos locais, pois as imagens conterão todo o software necessário.

Crie um novo arquivo docker-compose.yml:

nano docker-compose.yml

Cole a seguinte configuração. Este arquivo é mais complexo, então vamos examinar cada parte.

services:
  db:
    image: mysql:8.0
    container_name: mysql_db
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: <^your_root_password_here<^>
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress_user
      MYSQL_PASSWORD: <^your_wordpress_password_here<^>
    restart: unless-stopped

  wordpress:
    image: wordpress:latest
    container_name: wordpress_app
    ports:
      - "8001:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress_user
      WORDPRESS_DB_PASSWORD: <^your_wordpress_password_here<^>
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wp_content:/var/www/html/wp-content
    depends_on:
      - db
    restart: unless-stopped

volumes:
  db_data:

Nota: Nós inserimos os valores da senha aqui diretamente no código apenas para fins de ilustração. Ao usar em um ambiente real, certifique-se de usar variáveis de ambiente no arquivo .env para evitar expor suas credenciais.

Salve e feche o arquivo. Lembre-se de substituir os espaços reservados <^...^> por senhas fortes e seguras.

Vamos detalhar as novas diretrizes neste arquivo:

  • services: Este bloco ainda define nossos contêineres. Agora temos dois: db e wordpress.
  • image: Estamos usando mysql:8.0 para o banco de dados e a imagem wordpress:latest para a aplicação.
  • container_name: Isso define um nome específico e legível para o ser humano para o contêiner, que é mais fácil de referenciar do que os gerados automaticamente.
  • environment: Esta é uma lista de variáveis de ambiente passadas para o contêiner. A imagem mysql usa estas variáveis para definir a senha do usuário root e criar um banco de dados e usuário iniciais. A imagem wordpress as utiliza para saber como se conectar ao seu banco de dados.
  • volumes (nível de serviço):

    • Para o serviço db, db_data:/var/lib/mysql mapeia um volume gerenciado pelo Docker chamado db_data para o diretório de dados do MySQL dentro do contêiner. Isso mantém seus dados seguros.
    • Para o serviço wordpress, ./wp_content:/var/www/html/wp-content mapeia um diretório local (wp_content) para o diretório de conteúdo do WordPress. Isso permite que você edite diretamente temas e plugins a partir da sua máquina host.
  • depends_on: Isso informa ao Compose para iniciar o serviço db antes de iniciar o serviço wordpress. Isso é importante, pois o WordPress falhará se não conseguir encontrar seu banco de dados na inicialização.
  • volumes (nível superior): Este bloco define os volumes nomeados. db_data: cria um volume gerenciado pelo Docker, que é a maneira preferida de lidar com dados persistentes.

Agora, inicie este aplicativo de múltiplos serviços:

docker compose up -d

O Compose irá baixar as imagens mysql e wordpress e, em seguida, criar os contêineres, iniciando o serviço db primeiro.

Creating network "compose-demo_default" with the default driver
Creating volume "compose-demo_db_data" with default driver
Pulling db (mysql:8.0)...
...
Pulling wordpress (wordpress:latest)...
...
Creating mysql_db        ... done
Creating wordpress_app ... done

Agora você pode acessar seu novo site WordPress navegando para localhost:8001 ou <^seu_domínio_ou_IP_do_servidor<^>:8001 no seu navegador. Você deverá ver a tela de instalação do WordPress. Para um exemplo mais detalhado, confira nosso artigo sobre Como Instalar o WordPress com Docker Compose

Passo 6 — Usando Docker Compose para Desenvolvimento de IA/ML

Além das aplicações web, o Docker Compose é uma ferramenta extremamente útil para criar ambientes de ciência de dados e aprendizado de máquina (AI/ML) reproduzíveis. Projetos de AI/ML são conhecidos por suas dependências complexas, incluindo versões específicas do Python, bibliotecas como TensorFlow ou PyTorch, e drivers de nível de sistema como o NVIDIA CUDA Toolkit. O Docker Compose captura todo esse ambiente em arquivos de configuração, resolvendo o problema do “funciona na minha máquina”, o que é crítico para pesquisas reproduzíveis.

Neste exemplo, você irá criar um ambiente de IA/ML com múltiplos serviços, consistindo em:

  • JupyterLab: Um contêiner para desenvolvimento interativo, construído a partir de um Dockerfile personalizado.
  • PostgreSQL: Um contêiner de banco de dados para armazenar resultados de experimentos e metadados.
  • Acesso à GPU: O contêiner do JupyterLab será configurado para acessar a GPU NVIDIA da máquina host, uma exigência comum para o treinamento de modelos.

Pré-requisito: Este exemplo requer uma GPU NVIDIA na sua máquina hospedeira e que o NVIDIA Container Toolkit esteja instalado. Sem isso, o container não será iniciado ao solicitar recursos de GPU.

Estrutura de Arquivos

Primeiro, crie um diretório para o seu projeto. Dentro dele, você criará um arquivo docker-compose.yml, um diretório jupyter, um Dockerfile para o Jupyter e um arquivo requirements.txt. A estrutura deve ficar mais ou menos assim:

ai-project/
├── docker-compose.yml
└── jupyter/
    ├── Dockerfile
    └── requirements.txt

Criando os Arquivos do Componente

1. O arquivo requirements.txt

Este arquivo lista os pacotes Python para o seu ambiente de ciência de dados.

nano jupyter/requirements.txt

Adicione os pacotes necessários. Para este exemplo, incluiremos bibliotecas para manipulação de dados, conexão com banco de dados e um framework de deep learning.

pandas
scikit-learn
tensorflow
jupyterlab
psycopg2-binary

Salve e feche o arquivo.

2. O Dockerfile

Este arquivo define seu serviço personalizado do JupyterLab. Ele usa uma imagem oficial do Jupyter como base e instala os pacotes do requirements.txt.

nano jupyter/Dockerfile

Cole o seguinte conteúdo:

# Start from a base image that includes Jupyter and scientific libraries
FROM jupyter/scipy-notebook:latest

# Copy our local requirements file into the container
COPY requirements.txt /tmp/requirements.txt

# Install the Python packages
RUN pip install --no-cache-dir -r /tmp/requirements.txt

Este arquivo instrui o Docker a usar jupyter/scipy-notebook como ponto de partida, copiar seu requirements.txt para o contêiner e, em seguida, usar o pip para instalar os pacotes.

Definindo o ambiente com docker-compose.yml

Agora, crie o arquivo principal docker-compose.yml. Este arquivo irá orquestrar tanto o serviço db quanto o seu serviço personalizado jupyter.

nano docker-compose.yml

Cole a seguinte configuração, substituindo os espaços reservados <^...^> pelas suas próprias credenciais seguras.

services:
  db:
    image: postgres:15-alpine
    container_name: ai_postgres_db
    environment:
      POSTGRES_USER: <^your_db_user^>
      POSTGRES_PASSWORD: <^your_db_pass^>
      POSTGRES_DB: experiments
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U <^your_db_user^> -d experiments"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - ai_net

  jupyter:
    build: ./jupyter
    container_name: ai_jupyter_lab
    ports:
      - "8888:8888"
    volumes:
      - ./notebooks:/home/jovyan/work
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_USER=<^your_db_user^>
      - POSTGRES_PASSWORD=<^your_db_pass^>
      - POSTGRES_DB=experiments
    restart: unless-stopped
    networks:
      - ai_net
    depends_on:
      db:
        condition: service_healthy
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

volumes:
  postgres_data:
    name: ai_project_data

networks:
  ai_net:
    driver: bridge

Este arquivo de configuração introduz vários conceitos importantes:

  • build: ./jupyter: Isso instrui o Docker Compose a construir uma imagem personalizada para o serviço jupyter. Ele procura por um Dockerfile dentro do diretório especificado ./jupyter.
  • volumes: - ./notebooks:/home/jovyan/work: Isso monta um diretório local chamado notebooks no contêiner. Isso garante que todos os notebooks do Jupyter que você criar sejam salvos diretamente na sua máquina host, persistindo mesmo após a remoção do contêiner.
  • healthcheck: Como visto na seção de solução de problemas, essa verificação valida que o serviço db não está apenas em execução, mas pronto para aceitar conexões antes que outros serviços sejam iniciados.
  • depends_on: ... condition: service_healthy: Isso indica ao serviço jupyter para esperar até que o healthcheck do db seja aprovado antes de iniciar.
  • deploy.resources.reservations.devices: Este é o bloco que solicita acesso à GPU.

    • driver: nvidia: Especifica o driver do host a ser usado.
    • count: 1: Solicita uma GPU.
    • capabilities: [gpu]: Garante que o contêiner tenha as capacidades necessárias para usar a GPU.

Executando o Ambiente de IA/ML

Com seus arquivos no lugar, você está pronto para construir e executar os serviços.

  1. A partir do seu diretório ai-project, execute o comando docker compose up. Você deve adicionar a flag --build na primeira vez para informar ao Compose que deve construir sua imagem personalizada do jupyter.

    docker compose up -d --build
  2. O Compose primeiro irá construir a imagem jupyter (o que pode levar alguns minutos enquanto baixa o TensorFlow), depois irá baixar a imagem postgres e, por fim, iniciar ambos os contêineres.

    [+] Building 5.8s (9/9) FINISHED
     => [internal] load build definition from Dockerfile
    ...
    [+] Running 3/3
     ✔ Network ai-project_ai_net        Created
     ✔ Container ai_postgres_db         Started
     ✔ Container ai_jupyter_lab         Started
  3. Você agora pode acessar a interface do JupyterLab navegando para http://localhost:8888 (ou <^seu_ip_do_servidor^>:8888) no seu navegador. Será solicitado um token, que você pode obter nos logs do contêiner:

    docker compose logs jupyter

    Procure uma linha semelhante a http://127.0.0.1:8888/lab?token=a1b2c3d4e5f6...

  4. Dentro de um notebook Jupyter, você agora pode se conectar ao seu banco de dados usando o nome do host db e as credenciais que você forneceu. Seu ambiente também tem acesso à GPU do host para treinamento de modelos.

Dimensionando Serviços e Usando Redes Personalizadas

O Docker Compose inclui recursos para escalar serviços e gerenciar as redes em que eles se comunicam.

Escalonamento de Serviço com Réplicas

Imagine que o seu servidor web Nginx do Passo 2 está recebendo muito tráfego. Você pode escalar o serviço web para executar múltiplas instâncias de contêiner. O Docker Compose pode gerenciar isso automaticamente.

Existem duas maneiras principais de escalar um serviço.

1. Usando a chave replicas (Preferido na v2)

Você pode definir o número desejado de instâncias diretamente no seu arquivo docker-compose.yml usando as chaves deploy e replicas. Esse recurso era originalmente parte do Docker Swarm, mas agora está disponível para implantações padrão do Compose.

Modifique seu docker-compose.yml do Nginx do Passo 2:

services:
  web:
    image: nginx:alpine
    ports:
      - "8000:80"
    volumes:
      - ./app:/usr/share/nginx/html
    deploy:
      replicas: 3

Quando você executa docker compose up -d, o Compose irá criar três contêineres web. No entanto, você terá um problema: todos os três irão tentar se vincular à porta 8000 do host. Isso causará um erro de “porta já alocada” para o segundo e terceiro contêineres. Para resolver isso em um ambiente de produção, você removeria o mapeamento de ports do serviço web. Desta forma, os contêineres web seriam acessíveis apenas dentro da rede Docker. Um serviço separado de balanceamento de carga seria o único com uma porta pública. Ele então distribuiria o tráfego para as três réplicas da web.

Um exemplo de configuração seria assim (este é um exemplo avançado):

services:
  web:
    image: nginx:alpine
    # No 'ports' mapping here.
    # The service is only accessible inside the 'web-net' network.
    volumes:
      - ./app:/usr/share/nginx/html
    deploy:
      replicas: 3
    networks:
      - web-net

  load_balancer:
    image: nginx:latest
    ports:
      - "80:80" # The load_balancer is the only service with a public port.
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf # A config file that load balances to 'web'.
    networks:
      - web-net
    depends_on:
      - web

networks:
  web-net:

Nesta configuração, o load_balancer escuta na porta 80 e encaminha as solicitações para web_1, web_2 e web_3 internamente.

Esta chave replicas é mais útil quando usada com um proxy reverso (como Traefik ou outra instância do Nginx) que pode balancear a carga das requisições entre as réplicas dentro da rede Docker, sem que cada réplica precise expor uma porta no host.

2. Usando a flag --scale

Um método comum para escalonamento é a opção --scale, que vem do Compose v1. Essa opção é aplicada em tempo de execução e substitui qualquer chave replicas.

No entanto, você deve ter cuidado com as definições de porta. Se o seu serviço definir um mapeamento de porta fixa no host (por exemplo, "8000:80"), executar docker compose up --scale causará um erro para o segundo e terceiro contêiner, pois todos tentarão se conectar à mesma porta do host.

Para usar --scale em serviços que expõem portas, você não deve usar um mapeamento de porta fixa no host.

  • Opção 1: Mapear para Portas Aleatórias do Host (Bom para Desenvolvimento)

    Você pode modificar seu docker-compose.yml para especificar apenas a porta do contêiner. Isso informa ao Docker para mapear a porta 80 de cada contêiner para uma porta aleatória disponível na sua máquina host.

    services:
      web:
        image: nginx:alpine
        ports:
          - "80" # No fixed host port
        volumes:
          - ./app:/usr/share/nginx/html

    Agora, quando você executar o comando scale:

    docker compose up -d --scale web=3

    Execute docker compose ps para ver o resultado. Cada contêiner estará rodando em uma porta do host diferente, atribuída aleatoriamente:

          Name                     Command               State          Ports        
    ----------------------------------------------------------------------------------
    compose-demo_web_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:49154->80/tcp
    compose-demo-web_2   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:49155->80/tcp
    compose-demo-web_3   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:49156->80/tcp
  • docker-compose.yml - Correto para --scale

  • Opção 2: Use um Proxy Reverso (Bom para Produção)

    A outra solução, como mencionado na seção replicas, é remover a diretiva ports do serviço web completamente. Você então usaria um contêiner de balanceador de carga separado (que possui a única porta pública) para gerenciar e distribuir o tráfego para as réplicas dimensionadas dentro da rede Docker.

    Para parar e remover os três contêineres, o comando permanece o mesmo:

    docker compose down

Configuração Personalizada de Rede

Por padrão, o Docker Compose cria uma única rede bridge para sua aplicação. Todos os serviços no arquivo são conectados a ela, e é assim que o contêiner wordpress conseguiu encontrar o contêiner db apenas usando o nome do serviço (db).

No entanto, você pode definir suas próprias redes personalizadas para melhor isolamento e controle.

Vamos modificar o exemplo do WordPress para usar uma rede bridge personalizada.

services:
  db:
    image: mysql:8.0
    ...
    networks:
      - app_net

  wordpress:
    image: wordpress:latest
    ...
    ports:
      - "8001:80"
    depends_on:
      - db
    networks:
      - app_net

volumes:
  db_data:

networks:
  app_net:
    driver: bridge

Aqui está o que adicionamos:

  • networks (nível superior): Isso define uma nova rede chamada app_net e especifica que ela deve usar o driver padrão bridge.
  • networks (nível de serviço): Sob tanto db quanto wordpress, esta chave os conecta à nossa rede app_net.

Se você tivesse um terceiro serviço (como uma ferramenta de análise) que você não conectasse à app_net, ele seria completamente isolado e incapaz de se comunicar com os contêineres db ou wordpress.

Para clusterização de múltiplos hosts com o Docker Swarm, você teria que mudar o driver de bridge para overlay. O driver bridge é usado para comunicação entre contêineres em um único host, o que é o padrão para a maioria dos casos de uso do Docker Compose.

Usando Arquivos de Configuração Modulares

À medida que suas aplicações crescem, seu arquivo docker-compose.yml pode se tornar grande e difícil de gerenciar. O Docker Compose suporta uma diretiva include, permitindo que você divida sua configuração em vários arquivos.

Imagine que você queira separar suas definições do WordPress e do banco de dados, e talvez ter um docker-compose.override.yml comum para configurações específicas de desenvolvimento (como vincular uma porta no banco de dados).

Sua estrutura de diretórios pode se parecer com isto:

compose-demo/
├── docker-compose.yml
├── docker-compose.db.yml
├── docker-compose.web.yml

Este arquivo irá somente definir o serviço db.

services:
  db:
    image: mysql:8.0
    container_name: mysql_db
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: <^your_root_password_here<^>
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress_user
      MYSQL_PASSWORD: <^your_wordpress_password_here<^>
    restart: unless-stopped

volumes:
  db_data:

Este arquivo irá somente definir o serviço wordpress.

services:
  wordpress:
    image: wordpress:latest
    container_name: wordpress_app
    ports:
      - "8001:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress_user
      WORDPRESS_DB_PASSWORD: <^your_wordpress_password_here<^>
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wp_content:/var/www/html/wp-content
    depends_on:
      - db
    restart: unless-stopped

Agora, seu arquivo principal docker-compose.yml se torna muito simples. Ele apenas usa include para incluir os outros arquivos.

include:
  - docker-compose.db.yml
  - docker-compose.web.yml

Quando você executa docker compose up -d, o Compose lerá todos os três arquivos, mesclará as configurações e iniciará os serviços db e wordpress exatamente como se eles estivessem definidos em um único arquivo. Essa abordagem torna sua configuração muito mais modular e reutilizável.

Nota: A diretiva include: requer o Docker Compose v2.20 ou superior. Se o seu sistema usar uma versão mais antiga, você pode combinar arquivos usando docker compose -f docker-compose.db.yml -f docker-compose.web.yml up.

Migrando de docker-compose (v1) para docker compose (v2)

O comando docker compose que você instalou no Passo 1 é o “Compose v2.” Ele é um plugin baseado em Go integrado diretamente ao Docker CLI.

A versão original, “Compose v1”, era uma ferramenta Python separada invocada com docker-compose (com hífen). A partir de julho de 2023, o Compose v1 não é mais suportado e foi descontinuado.

Principais Alterações e Compatibilidade com Versões Anteriores

  • O Comando: A mudança mais óbvia é o comando. O hífen (docker-compose) agora é um espaço (docker compose).
  • Instalação: a v1 foi instalada com pip. A v2 está incluída no Docker Desktop ou instalada como um plugin de CLI, como você fez no Passo 1.
  • Arquivos YAML: Seus arquivos docker-compose.yml são quase 100% compatíveis com versões anteriores. O Compose v2 oferece suporte completo às versões de arquivos 3.x. Você não precisa alterar seus arquivos YAML para a migração, apenas seus comandos.
  • --project-name flag: A flag -p ainda funciona, mas a flag completa agora é --project-name em vez de --project_name.

Guia de Migração de Comandos

A maioria dos comandos é idêntica, apenas com o hífen removido. Aqui está uma tabela comparando os comandos comuns da versão v1 com seus equivalentes na v2.

Comando docker-compose (v1)Comando docker compose (v2)Notas
docker-compose up -d
docker compose up -d
Nenhuma mudança na sintaxe.
docker-compose down
docker compose down
Nenhuma mudança na sintaxe.
docker-compose ps
docker compose ps
Nenhuma mudança na sintaxe.
docker-compose logs
docker compose logs
Nenhuma mudança na sintaxe.
docker-compose stop
docker compose stop
Nenhuma mudança na sintaxe.
docker-compose build
docker compose build
Nenhuma mudança na sintaxe.
docker-compose exec web bash
docker compose exec web bash
Nenhuma mudança na sintaxe.
docker-compose run web bash
docker compose run web bash
run cria um novo contêiner. exec executa em um existente.
docker-compose up --scale web=3
docker compose up --scale web=3
A flag --scale ainda é suportada na v2.

Como você pode ver, para o uso do dia a dia, a única mudança é docker-compose -> docker compose. Se você usa scripts, pode atualizá-los simplesmente removendo o hífen.

Se você ainda tiver o antigo docker-compose v1 instalado, pode removê-lo para evitar confusão:

sudo pip3 uninstall docker-compose

Ou, se foi instalado pelo apt:

sudo apt remove docker-compose

Solução de Problemas Comuns do Docker Compose

Quando você trabalha com o Docker Compose, pode encontrar problemas relacionados à sintaxe de arquivos, permissões ou conflitos de execução de contêineres. A maioria dos problemas pode ser diagnosticada e resolvida verificando meticulosamente sua configuração, permissões e logs dos contêineres.

Vamos ver alguns dos erros mais comuns e suas soluções.

Permissão Negada (Socket do Docker)

Este é um dos erros mais comuns para novos usuários do Docker. Você executa docker compose up e vê uma mensagem de erro sobre o socket do daemon do Docker.

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
  • Problema: Seu usuário sem privilégios de root não tem permissão para se comunicar com o daemon do Docker, que é executado como root.

  • Solução: Você deve adicionar seu usuário ao grupo docker, que foi criado durante a instalação do Docker.

    1. Adicione seu usuário ao grupo docker:

      sudo usermod -aG docker ${USER}
    2. Para que a nova associação ao grupo entre em vigor, você deve sair e entrar novamente.

    3. Alternativamente, você pode ativar as alterações de grupo para sua sessão de terminal atual digitando:

      newgrp docker

    Isso deve resolver quaisquer erros de permissão relacionados ao socket do Docker.

Erros de Sintaxe e Indentação em YAML

O Docker Compose não consegue executar e informa que seu arquivo docker-compose.yml é inválido.

ERROR: The Compose file './docker-compose.yml' is invalid because:
services.web.ports contains an invalid type, it should be a list

Ou :

mapping values are not allowed in this context at line 5
  • Problema: O arquivo docker-compose.yml depende de sintaxe YAML estrita. O erro mais comum é a indentação incorreta. O YAML usa espaços, não tabs, para definir a estrutura.
  • Solução: Verifique cuidadosamente a indentação do seu arquivo docker-compose.yml.

    • O padrão é dois espaços para cada nível de indentação.
    • Certifique-se de que todas as chaves no mesmo nível (como version, services, volumes) comecem na mesma coluna.
    • Certifique-se de que todas as subchaves (como image, ports, volumes sob um serviço) estejam indentadas dois espaços a mais que seu serviço pai (por exemplo, web).
    • Use um editor de código com um verificador de sintaxe YAML para destacar automaticamente os erros de sintaxe.

Conflitos de Portos

Você tenta iniciar seu ambiente, mas o comando falha com uma mensagem de erro dizendo que o endereço já está em uso.

Error starting userland proxy: listen tcp 0.0.0.0:8000: bind: address already in use
  • Problema: Outro processo na sua máquina host já está usando a porta que você está tentando mapear (neste caso, a porta 8000). Isso geralmente é outro contêiner Docker ou um servidor de desenvolvimento local.

  • Solução: Você tem duas opções:

    1. Pare o outro processo. Você pode encontrar o processo que está usando a porta com este comando:

      sudo lsof -i :8000

      Se for outro contêiner Docker, pare-o com docker stop <container_id>.

    2. Altere a porta do host no seu arquivo docker-compose.yml. Esta é muitas vezes a solução mais simples. Altere o mapeamento de ports de "8000:80" para uma porta diferente, como "8001:80".

      ...
      ports:
        - "8001:80" # Changed from 8000
      ...
    3. docker-compose.yml

O serviço falha com Conexão Recusada (depends_on)

Em uma aplicação com múltiplos serviços (como o exemplo do WordPress e MySQL), o container wordpress inicia, mas seus logs mostram Connection refused ou MySQL server has gone away ao tentar se conectar ao serviço db.

  • Problema: Você usou depends_on, mas essa diretiva apenas espera que o contêiner db inicie. Ela não espera que a aplicação MySQL dentro do contêiner seja totalmente inicializada e esteja pronta para aceitar conexões.

  • Solução: O aplicativo (neste caso, o WordPress) deve ser configurado para tentar a conexão novamente. A maioria das imagens modernas já possui essa lógica de tentativas incorporada. Para imagens que não possuem, você deve implementar um verificador de integridade.

    Você pode adicionar um healthcheck ao seu serviço db. O depends_on do serviço wordpress pode então ser configurado para esperar que o banco de dados esteja "saudável", e não apenas "iniciado".

Exemplo de Verificação de Saúde para MySQL:

services:
  db:
    image: mysql:8.0
    ...
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p<^your_root_password_here<^>"]
      interval: 10s
      timeout: 5s
      retries: 5

  wordpress:
    image: wordpress:latest
    ...
    depends_on:
      db:
        condition: service_healthy # This now waits for the healthcheck
    ...

Erros com Volumes e Montagens Bind

Você pode encontrar erros de permissão nos logs do seu contêiner ou perceber que o diretório de dados do seu contêiner está vazio.

Permissões de Arquivo/Diretório

  • Problema: O contêiner é executado como um usuário específico (por exemplo, www-data com ID de usuário 33), mas o diretório do host que você montou é de propriedade do seu usuário (por exemplo, ubuntu com ID de usuário 1000). O usuário do contêiner não tem permissão para escrever no diretório do host.

  • Solução: Altere a propriedade do diretório do host para corresponder ao ID do usuário dentro do contêiner. Você pode encontrar o ID do usuário do contêiner executando docker compose exec <nome_do_serviço> id. Por exemplo, se o ID for 33 (comum para www-data):

    sudo chown -R 33:33 ./wp_content

Problemas com Caminho Relativo

  • Problema: Seu docker-compose.yml usa um caminho relativo como ./app, mas seu arquivo index.html não está sendo servido.

  • Solução: O Docker Compose interpreta caminhos relativos a partir do diretório onde você executa o comando docker compose up. Sempre execute os comandos do Compose a partir do mesmo diretório que contém seu arquivo docker-compose.yml.

Rede e Descoberta de Serviços

Os logs do seu contêiner de aplicativo mostram Host não encontrado ou Não foi possível resolver o host: db.

  • Problema: Seu contêiner wordpress não consegue encontrar o contêiner db na rede.
  • Solução: Por padrão, o Docker Compose cria uma rede e conecta todos os serviços a ela. Os serviços podem se encontrar usando seus nomes de serviço.

    1. Verifique os Nomes dos Serviços: Garanta que o nome do host na configuração do seu aplicativo (por exemplo, a variável de ambiente WORDPRESS_DB_HOST) seja exatamente o mesmo que o nome do serviço no seu docker-compose.yml (por exemplo, db).

    2. Inspecione a Rede: Use docker compose ps para encontrar o nome do seu projeto (por exemplo, compose-demo). Em seguida, inspecione a rede padrão:

      docker network inspect compose-demo_default

      A saída JSON listará todos os contêineres conectados a esta rede. Se algum dos seus serviços estiver ausente, verifique seu docker-compose.yml para qualquer configuração personalizada de networks que possa estar isolando-o.

Incompatibilidade de Comando (v1 vs. v2)

Você digita docker-compose up (com hífen) e vê um erro de “comando não encontrado”.

docker-compose: command not found
  • Problema: Você está tentando usar o comando do Compose v1, que é uma ferramenta Python obsoleta. Este guia instala o Compose v2, que é um plugin integrado diretamente ao Docker CLI.
  • Solução: Use o comando correto substituindo o hífen (-) por um espaço.
docker-compose (v1)docker compose (v2)
docker-compose updocker compose up
docker-compose downdocker compose down
docker-compose psdocker compose ps
docker-compose logsdocker compose logs

Sempre use docker compose (espaço) ao seguir este guia.

Perguntas Frequentes

1. Para que serve o Docker Compose?

O Docker Compose é uma ferramenta para definir e executar aplicações Docker com múltiplos contêineres.

Ele usa um único arquivo YAML (por padrão, docker-compose.yml) para configurar todos os componentes da sua aplicação, que são chamados de serviços. Este arquivo também define as redes que permitem que os serviços se comuniquem entre si e os volumes usados para dados persistentes.

Com este único arquivo, você pode gerenciar toda a sua pilha de aplicativos com comandos simples:

  • docker compose up inicia e executa toda a sua aplicação, incluindo todos os containers, redes e volumes especificados.
  • docker compose down para e remove todos os contêineres, redes e volumes criados pela sua aplicação.

É mais útil para gerenciar aplicações que exigem múltiplos componentes, como um site que precisa de um servidor web (como Nginx), um backend de aplicação (como WordPress) e um banco de dados (como MySQL).

2. Como eu instalo o Docker Compose no Ubuntu?

O método recomendado é instalar o Docker Compose como um plugin para o Docker CLI. Isso é feito instalando o pacote docker-compose-plugin a partir do repositório oficial apt do Docker.

  1. Primeiro, verifique se você seguiu a documentação oficial do Docker para configurar o repositório apt do Docker em seu sistema Ubuntu.

  2. Atualize sua lista de pacotes:

    sudo apt update
  3. Instale o plugin do Docker Compose:

    sudo apt install docker-compose-plugin
  4. Verifique a instalação conferindo a versão. O comando usa um espaço, não um hífen.

    docker compose version

3. Como atualizo o Docker Compose para a versão mais recente?

Como o Docker Compose (v2) está instalado como um pacote do sistema usando apt, você pode atualizá-lo usando o processo padrão de atualização de software do Ubuntu.

  1. Atualize o índice de pacotes local:

    sudo apt update
  2. Execute uma atualização em todo o sistema, que incluirá o plugin Compose:

    sudo apt upgrade

    Alternativamente, se você quiser apenas atualizar o próprio plugin, você pode executar:

    sudo apt install --only-upgrade docker-compose-plugin

4. O Docker Compose pode ser usado em ambientes de produção?

Sim, o Docker Compose é frequentemente usado em produção, especialmente para aplicações que rodam em um único host.

Ele fornece uma maneira simples de definir, implantar e gerenciar o ciclo de vida dos serviços, redes e volumes da sua aplicação. Para uma implantação em servidor único, é uma solução muito eficaz e fácil de gerenciar.

Para cenários mais complexos que exigem o gerenciamento de contêineres em vários hosts (um cluster), outras ferramentas são mais comuns. Estas incluem o Docker Swarm (que usa uma sintaxe de arquivo Compose similar) e o Kubernetes (que é o padrão da indústria para orquestração de contêineres em larga escala).

5. Qual é a diferença entre Docker e Docker Compose?

Esta tabela descreve as principais diferenças entre o Docker CLI e o Docker Compose CLI.

Recursodocker (Docker Engine)docker compose (Plugin Compose)
EscopoGerencia objetos individuais do Docker.Gerencia uma aplicação completa com vários contêineres como uma única unidade.
Uso PrimárioConstruindo imagens (docker build), executando contêineres individuais (docker run), gerenciando contêineres (docker ps), imagens, volumes e redes.Orquestrando múltiplos serviços definidos em um arquivo docker-compose.yml.
ComandosComandos de baixo nível focados em um único objeto. Exemplo: docker run -d -p 80:80 -v ./:/app nginxComandos de alto nível para toda a aplicação. Exemplo: docker compose up
AnalogiaUm bloco de construção (um único contêiner).O projeto e o gerente de construção de todo o edifício (o aplicativo).

Em resumo, você usa docker para interagir com um único contêiner. Você usa docker compose para gerenciar toda a sua pilha de aplicativos (por exemplo, web, app, db) de uma só vez.

6. Como faço para executar múltiplos containers com Docker Compose?

Você executa vários contêineres definindo-os como serviços no seu arquivo docker-compose.yml.

  1. Crie um arquivo chamado docker-compose.yml.

  2. Dentro deste arquivo, use a chave services: para definir cada contêiner que você deseja executar.

    Aqui está um exemplo prático que define e executa dois containers: um site WordPress e um banco de dados MySQL.

    services:
      db:
        # This is the first service (container)
        image: mysql:8.0
        environment:
          MYSQL_ROOT_PASSWORD: <^your_password_here<^>
          MYSQL_DATABASE: wordpress
        volumes:
          - db_data:/var/lib/mysql
    
      wordpress:
        # This is the second service (container)
        image: wordpress:latest
        ports:
          - "8001:80"
        environment:
          WORDPRESS_DB_HOST: db
          WORDPRESS_DB_PASSWORD: <^your_password_here<^>
        depends_on:
          - db
    
    volumes:
      db_data:
  3. docker-compose.yml

  4. Salve o arquivo e abra um terminal no mesmo diretório.

  5. Execute um único comando para iniciar ambos os contêineres:

    docker compose up -d

O Docker Compose irá ler o arquivo, criar uma rede compartilhada para os serviços, baixar as imagens mysql e wordpress, e iniciar um contêiner para cada serviço.

7. Por que usar o Docker Compose para desenvolvimento?

O Docker Compose é uma ferramenta padrão para ambientes de desenvolvimento porque resolve vários problemas comuns.

  • Ambientes Consistentes: Isso garante que todos os desenvolvedores de uma equipe executem exatamente os mesmos serviços (banco de dados, cache, servidor web) com exatamente as mesmas versões e configurações. Isso é definido no arquivo docker-compose.yml, que é versionado no controle de versão. Isso elimina o problema do “funciona na minha máquina”.

  • Simplicidade: Substitui scripts de configuração complexos e longos comandos docker run. Um desenvolvedor só precisa executar docker compose up para iniciar toda a pilha de aplicativos e docker compose down para encerrá-la.

  • Isolamento de Serviço: Os desenvolvedores podem trabalhar em vários projetos na mesma máquina sem conflitos de dependências. O Projeto A pode usar PostgreSQL 9.6 e o Projeto B pode usar PostgreSQL 14, já que cada banco de dados é executado em um contêiner isolado gerenciado pelo seu próprio arquivo Compose.

  • Testes de Integração Fáceis: Como o Compose inicia todas as dependências de um aplicativo ao mesmo tempo, ele cria um ambiente local perfeito para executar testes de integração que verificam como os serviços interagem entre si.

Conclusão

Neste guia, você instalou o Docker Compose e configurou uma aplicação completa com múltiplos contêineres. Você começou com um arquivo básico docker-compose.yml para um servidor web Nginx e avançou para uma pilha mais complexa e realista, envolvendo uma aplicação WordPress e um banco de dados MySQL. Você aprendeu a gerenciar todo o ciclo de vida da aplicação, desde a construção e execução dos serviços até sua parada e remoção.

Agora você está familiarizado com os conceitos-chave para gerenciar aplicações de forma eficaz, incluindo escalonamento de serviços, definições de rede personalizadas e divisão da sua configuração em arquivos modulares usando a diretiva include. Seguindo o guia de migração e os passos de resolução de problemas, você também poderá resolver problemas comuns como conflitos de portas, erros de "Permissão negada" e erros de sintaxe YAML. As habilidades abordadas aqui permitirão que você construa ambientes de desenvolvimento consistentes e reproduzíveis e implante aplicações em um único host com confiança.

Para uma referência completa de todos os comandos docker compose disponíveis, consulte a documentação oficial.

Para mais tutoriais relacionados ao Docker, confira os seguintes artigos:

  • Como Instalar o Docker no Ubuntu – Guia Passo a Passo
  • Como Instalar o WordPress com Docker Compose

Obrigado por aprender com a comunidade Linux-Console.net.