17 min de leitura · Guia técnico
Docker Compose é uma ferramenta oficial do ecossistema Docker que permite definir e orquestrar múltiplos containers usando um único arquivo YAML chamado docker-compose.yml. Para subir múltiplos serviços no VPS com Docker Compose, siga estes passos:
- Instale o Docker Engine e o plugin Docker Compose no servidor
- Crie o diretório do projeto e o arquivo
docker-compose.ymlcom os serviços desejados - Declare serviços, redes e volumes no arquivo YAML
- Execute
docker compose up -dpara subir toda a stack em segundo plano - Verifique o status dos containers com
docker compose ps - Configure volumes nomeados para garantir persistência de dados entre reinicializações
Pré-requisitos para usar Docker Compose no VPS
- VPS com Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, Debian 12 ou AlmaLinux 9 (mínimo 1 GB de RAM)
- Acesso SSH com privilégios de root ou usuário com sudo — veja como acessar em Acessando servidores VPS Linux da AviraHost
- Docker Engine versão 24 ou superior instalado
- Plugin
docker compose(v2) — substitui o binário legadodocker-compose(v1) - Portas necessárias liberadas no firewall (UFW, nftables ou CSF)
- Conhecimento básico de YAML e linha de comando Linux
Docker Compose: instalação e configuração inicial no VPS
O Docker Compose é distribuído como plugin do Docker Engine desde a versão 2. Em distribuições baseadas em Debian e Ubuntu, a instalação mais confiável é feita via repositório oficial do Docker, que já inclui o plugin automaticamente.
Atualize os pacotes e instale as dependências:
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release
Adicione a chave GPG e o repositório oficial do Docker:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Instale o Docker Engine com o plugin Compose:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Verifique as versões instaladas:
docker --version
docker compose version
Docker version 26.1.4, build 5650f9b
Docker Compose version v2.27.1
Para rodar Docker sem sudo, adicione seu usuário ao grupo docker:
sudo usermod -aG docker $USER
newgrp docker
Estrutura do arquivo docker-compose.yml explicada
O arquivo docker-compose.yml é o coração da orquestração de containers com Compose. Cada bloco do YAML corresponde a um aspecto da infraestrutura: serviços, redes e volumes.
Crie o diretório do projeto e o arquivo de configuração:
mkdir -p /opt/minha-stack && cd /opt/minha-stack
nano docker-compose.yml
Exemplo completo de stack com Nginx, PHP-FPM e MariaDB:
services:
web:
image: nginx:1.26-alpine
container_name: nginx_web
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./html:/var/www/html:ro
- certbot_data:/etc/letsencrypt
networks:
- frontend
- backend
depends_on:
- php
restart: unless-stopped
php:
image: php:8.3-fpm-alpine
container_name: php_fpm
volumes:
- ./html:/var/www/html
networks:
- backend
restart: unless-stopped
mem_limit: 256m
db:
image: mariadb:11.4
container_name: mariadb_db
environment:
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MARIADB_DATABASE: ${DB_NAME}
MARIADB_USER: ${DB_USER}
MARIADB_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/mysql
networks:
- backend
restart: unless-stopped
mem_limit: 512m
networks:
frontend:
backend:
internal: true
volumes:
db_data:
certbot_data:
Pontos importantes desta estrutura:
- depends_on: garante que o Nginx só sobe após o PHP-FPM estar iniciado
- networks internal: true: a rede backend não tem acesso externo direto, isolando o banco de dados
- mem_limit: limita o consumo de RAM por container, essencial em VPS com pouca memória
- restart: unless-stopped: reinicia automaticamente após falhas ou reboot do servidor
- volumes nomeados:
db_dataecertbot_datapersistem mesmo apósdocker compose down
Usando variáveis de ambiente com arquivo .env
Armazenar credenciais diretamente no docker-compose.yml é uma má prática de segurança. O Compose lê automaticamente um arquivo .env no mesmo diretório do projeto para substituir variáveis declaradas com a sintaxe ${VARIAVEL}.
Crie o arquivo .env:
nano /opt/minha-stack/.env
DB_ROOT_PASSWORD=SenhaRootForte@2024
DB_NAME=minha_aplicacao
DB_USER=app_user
DB_PASSWORD=SenhaAppForte@2024
Atenção: adicione o arquivo .env ao .gitignore imediatamente para evitar expor credenciais em repositórios públicos.
echo ".env" >> .gitignore
Verifique se o Compose está lendo as variáveis corretamente antes de subir os serviços:
docker compose config
O comando exibe o arquivo YAML com todas as variáveis substituídas pelos valores reais. Se alguma variável aparecer em branco, revise o arquivo .env.
Como subir, parar e gerenciar múltiplos serviços com Docker Compose
Com o arquivo docker-compose.yml e o .env configurados, você pode gerenciar toda a stack com comandos simples. Esta é a principal vantagem do Compose em relação a executar docker run manualmente para cada container.
Suba todos os serviços em modo detached (segundo plano):
cd /opt/minha-stack
docker compose up -d
[+] Running 4/4
✔ Network minha-stack_frontend Created
✔ Network minha-stack_backend Created
✔ Container mariadb_db Started
✔ Container php_fpm Started
✔ Container nginx_web Started
Verifique o status de todos os containers da stack:
docker compose ps
NAME IMAGE COMMAND SERVICE STATUS PORTS
mariadb_db mariadb:11.4 "docker-entrypoint.s…" db running 3306/tcp
nginx_web nginx:1.26-alpine "/docker-entrypoint.…" web running 0.0.0.0:80->80/tcp
php_fpm php:8.3-fpm-alpine "docker-php-entrypoi…" php running 9000/tcp
Acompanhe os logs de todos os serviços em tempo real:
docker compose logs -f
Para ver logs de um serviço específico:
docker compose logs -f db
Reinicie apenas um serviço sem derrubar os demais:
docker compose restart web
Pare todos os containers sem remover volumes (dados preservados):
docker compose stop
Para e remove containers e redes, mas mantém volumes:
docker compose down
Atenção: o comando docker compose down --volumes remove também os volumes nomeados, apagando permanentemente os dados do banco de dados. Use apenas em ambientes de desenvolvimento ou quando tiver backup confirmado.
Para atualizar as imagens e recriar os containers após uma mudança no docker-compose.yml:
docker compose pull
docker compose up -d --force-recreate
Exemplo prático: stack WordPress com MariaDB no VPS
Um dos casos de uso mais comuns do Docker Compose em VPS é subir uma instalação completa do WordPress com banco de dados MariaDB e cache, sem precisar instalar nada diretamente no sistema operacional. Veja como configurar esta stack de forma isolada e segura.
Crie um novo diretório para o projeto:
mkdir -p /opt/wordpress-stack && cd /opt/wordpress-stack
Crie o arquivo .env:
WP_DB_NAME=wordpress
WP_DB_USER=wp_user
WP_DB_PASSWORD=SenhaWP@2024
WP_DB_ROOT_PASSWORD=RootSenha@2024
Crie o docker-compose.yml:
services:
wordpress:
image: wordpress:6.5-php8.3-fpm-alpine
container_name: wordpress_app
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${WP_DB_NAME}
WORDPRESS_DB_USER: ${WP_DB_USER}
WORDPRESS_DB_PASSWORD: ${WP_DB_PASSWORD}
volumes:
- wp_data:/var/www/html
networks:
- wp_net
depends_on:
- db
restart: unless-stopped
mem_limit: 256m
db:
image: mariadb:11.4
container_name: wordpress_db
environment:
MARIADB_ROOT_PASSWORD: ${WP_DB_ROOT_PASSWORD}
MARIADB_DATABASE: ${WP_DB_NAME}
MARIADB_USER: ${WP_DB_USER}
MARIADB_PASSWORD: ${WP_DB_PASSWORD}
volumes:
- db_data:/var/lib/mysql
networks:
- wp_net
restart: unless-stopped
mem_limit: 512m
nginx:
image: nginx:1.26-alpine
container_name: wordpress_nginx
ports:
- "80:80"
volumes:
- wp_data:/var/www/html:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- wp_net
depends_on:
- wordpress
restart: unless-stopped
networks:
wp_net:
internal: false
volumes:
wp_data:
db_data:
Suba a stack:
docker compose up -d
Após alguns segundos, acesse o IP do seu VPS na porta 80 para ver o assistente de instalação do WordPress. Para mais detalhes sobre como configurar o servidor Linux antes de subir containers, consulte o artigo Configurando um Servidor Linux para Hospedagem de Sites.
Configurando reinicialização automática e integração com systemd
Em ambiente de produção, é fundamental garantir que a stack Docker Compose suba automaticamente após um reboot do VPS. A diretiva restart: unless-stopped no Compose cuida dos containers individualmente, mas o Docker daemon precisa estar habilitado no systemd para iniciar junto com o sistema.
Habilite o Docker para iniciar com o sistema:
sudo systemctl enable docker
sudo systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running)
Com o Docker habilitado no systemd e restart: unless-stopped configurado nos serviços, toda a stack será restaurada automaticamente após reinicializações do servidor. Para stacks críticas, você pode criar um serviço systemd dedicado que execute docker compose up -d na inicialização:
sudo nano /etc/systemd/system/minha-stack.service
[Unit]
Description=Minha Stack Docker Compose
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/minha-stack
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable minha-stack.service
Problemas comuns e como resolver
Sintoma: container sai imediatamente após subir (status Exited)
Causa: o processo principal do container terminou com erro, geralmente por configuração incorreta de variáveis de ambiente, arquivo de configuração inválido ou porta já em uso no host.
Solução: verifique os logs do container com docker compose logs nome_do_servico. Procure por mensagens de erro na inicialização. Se a porta estiver em uso, identifique o processo com sudo ss -tlnp | grep :80 e encerre-o ou altere a porta mapeada no Compose.
Sintoma: erro "permission denied" ao acessar volume montado
Causa: o usuário dentro do container não tem permissão para ler ou escrever no diretório montado do host. Isso ocorre frequentemente quando o diretório pertence ao root e o processo dentro do container roda como outro usuário.
Solução: ajuste as permissões do diretório no host para corresponder ao UID do processo dentro do container. Para Nginx Alpine, o processo roda como UID 101. Execute sudo chown -R 101:101 ./html ou use volumes nomeados em vez de bind mounts para evitar conflitos de permissão.
Sintoma: containers não conseguem se comunicar entre si
Causa: os serviços estão em redes diferentes ou o nome do serviço usado como hostname está incorreto. No Compose, cada serviço é acessível pelo nome declarado na chave services, não pelo container_name.
Solução: verifique se os serviços que precisam se comunicar estão na mesma rede. Use o nome do serviço (ex: db, não wordpress_db) como hostname nas variáveis de ambiente. Teste a conectividade com docker compose exec web ping db.
Sintoma: docker compose up falha com "port is already allocated"
Causa: outra aplicação ou container já está usando a porta mapeada no host (ex: Nginx ou Apache instalado diretamente no sistema).
Solução: identifique o processo com sudo ss -tlnp | grep :80 e pare-o (sudo systemctl stop nginx) ou altere o mapeamento de porta no Compose para uma porta livre, como "8080:80", e use um proxy reverso externo para rotear o tráfego.
Sintoma: dados do banco de dados perdidos após docker compose down
Causa: o comando foi executado com a flag --volumes, removendo os volumes nomeados, ou os dados estavam em um volume anônimo que foi removido automaticamente.
Solução: sempre use volumes nomeados explícitos (declarados na seção volumes: do Compose) para dados persistentes. Nunca execute docker compose down --volumes em produção sem backup. Para verificar os volumes existentes, use docker volume ls.
Perguntas frequentes sobre Docker Compose
O que é Docker Compose e para que serve?
Docker Compose é uma ferramenta que permite definir e orquestrar múltiplos containers Docker usando um único arquivo YAML chamado docker-compose.yml. Com ele, você descreve serviços, redes e volumes em um só lugar e sobe toda a stack com um único comando, sem precisar executar docker run manualmente para cada container. É especialmente útil para ambientes com múltiplos serviços interdependentes, como aplicações web com banco de dados e cache.
Qual a diferença entre Docker e Docker Compose?
O Docker gerencia containers individuais, enquanto o Docker Compose orquestra múltiplos containers que precisam trabalhar juntos, como uma aplicação web, um banco de dados e um cache. O Compose usa um arquivo YAML para declarar toda a topologia da stack, facilitando a reprodução e manutenção do ambiente. Em termos práticos, o Docker é o motor e o Compose é o painel de controle para múltiplos motores.
Docker Compose funciona em VPS com pouca RAM?
Sim, o Docker Compose em si consome pouquíssima memória. O consumo real depende dos serviços declarados no arquivo YAML. Em um VPS com 1 GB de RAM, é possível rodar stacks leves como WordPress com MariaDB, desde que os limites de memória de cada serviço sejam configurados com mem_limit no Compose. Usar imagens Alpine (versões minimalistas) também reduz significativamente o footprint de memória.
Como parar todos os serviços do Docker Compose sem apagar os dados?
Execute docker compose down sem a flag --volumes. Esse comando para e remove os containers e as redes criadas pelo Compose, mas preserva os volumes nomeados onde os dados persistem. Para apenas pausar sem remover containers, use docker compose stop, que mantém os containers criados e permite reiniciá-los rapidamente com docker compose start.
É possível usar Docker Compose em produção no VPS?
Sim, Docker Compose é amplamente usado em produção para stacks de pequeno e médio porte em VPS. Para ambientes maiores com múltiplos nós, ferramentas como Docker Swarm ou Kubernetes oferecem mais recursos de escalabilidade e alta disponibilidade, mas para um único servidor o Compose é suficiente e mais simples de operar. A chave para produção é configurar corretamente volumes nomeados, políticas de restart e variáveis de ambiente via arquivo .env.
Conclusão
- Comece pelo arquivo .env: nunca coloque credenciais diretamente no
docker-compose.yml; use variáveis de ambiente e adicione o.envao.gitignoreantes de qualquer commit. - Use volumes nomeados para dados persistentes: declare explicitamente os volumes na seção
volumes:do Compose e evite a flag--volumesnodocker compose downem produção. - Isole redes por camada: separe serviços públicos (web) de privados (banco de dados) usando redes distintas com
internal: truepara a camada de dados, reduzindo a superfície de ataque.
Leia também
- configurar rede Docker para isolar serviços no VPS
- Otimizar Docker Compose: portas só para serviços internos
- Entenda o Checklist de Segurança do Docker antes de ir ao ar
Precisa de ajuda com Docker Compose no seu VPS?
Configurar e manter stacks Docker Compose em produção exige atenção a segurança, persistência de dados e disponibilidade. Um VPS com recursos adequados e suporte especializado faz toda a diferença para manter seus serviços no ar.
Conheça os planos de VPS da AviraHost e suba sua stack Docker hoje