Em ambientes de produção modernos, a consistência entre o ambiente de desenvolvimento e o de homologação é crítica. O Docker resolve essa disparidade encapsulando aplicações e suas dependências em containers padronizados. Para administradores de sistemas e desenvolvedores que gerenciam VPS (Virtual Private Servers), dominar a instalação do Docker Engine e do Docker Compose não é apenas uma vantagem, mas uma necessidade operacional. Este guia técnico detalha o processo de configuração completa, incluindo segurança básica, gerenciamento de imagens e automação de atualizações.
Pré-requisitos e Preparação do Sistema
Antes de instalar qualquer ferramenta de containerização, é fundamental garantir que o sistema operacional esteja atualizado. Isso evita conflitos de bibliotecas compartilhadas (dependências) durante a instalação dos pacotes Docker. Vamos utilizar uma distribuição Linux baseada em Debian/Ubuntu como exemplo, pois é a mais comum em VPS de baixo custo e alto desempenho.
Execute os comandos abaixo para remover versões antigas do Docker que possam estar instaladas por padrão ou via repositórios desatualizados do sistema:
sudo apt-get remove docker docker-engine docker.io containerd runc
Em seguida, atualize o índice dos pacotes e instale as dependências necessárias para que o apt possa utilizar repositórios via HTTPS:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
Adicione a chave GPG oficial do Docker para garantir a integridade dos pacotes baixados. Isso é crucial para segurança, pois impede que versões modificadas ou maliciosas sejam instaladas:
sudo mkdir -p /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
Agora, adicione o repositório oficial do Docker. Note que o comando abaixo detecta automaticamente sua versão do Ubuntu (como jammy, focal, etc.):
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
Instalação do Docker Engine
Com o repositório configurado, a instalação em si é direta. O apt instalará o motor do Docker, o cliente e os utilitários de linha de comando:
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
A instalação completa não termina aqui. Por padrão, o Docker requer privilégios de root para ser executado. Para evitar digitar sudo antes de cada comando e melhorar a segurança ao integrar com ferramentas externas, adicione seu usuário ao grupo docker:
sudo usermod -aG docker $USER
Para que essa alteração de grupo tenha efeito imediatamente, execute:
newgrp docker
Verifique a instalação executando o contêiner "hello-world". Se o sistema baixar a imagem e exibir uma mensagem de sucesso, o Docker Engine está funcionando corretamente:
docker run hello-world
Configuração do Docker Compose
O Docker Compose é a ferramenta oficial para definir e executar aplicações multi-container. Ele utiliza um arquivo YAML (docker-compose.yml) para configurar os serviços da sua aplicação. A versão 3.x e superior suporta recursos avançados de rede e volumes.
Crie um diretório para seu projeto:
mkdir ~/meu-projeto
cd ~/meu-projeto
Crie o arquivo docker-compose.yml. Este exemplo configura dois serviços: uma aplicação web simples e um banco de dados. Note o uso de volumes nomeados para persistência de dados:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: senha_segura_aqui
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Para iniciar os serviços em segundo plano (modo detached), utilize:
docker compose up -d
Para verificar se os containers estão rodando, use:
docker ps
Segurança e Acesso sem Sudo
Já adicionamos o usuário ao grupo docker, mas é importante entender as implicações de segurança. Membros do grupo docker podem, efetivamente, controlar o daemon do Docker e, por extensão, executar comandos com privilégios de root no host. Para ambientes de produção com múltiplos usuários, considere usar permissões mais granulares ou ferramentas como Docker Content Trust.
Se você precisar adicionar novos usuários ao grupo em sistemas que não recarregam o grupo dinamicamente (como alguns ambientes systemd), um reboot pode ser necessário, ou o usuário deve fazer logout e login novamente.
Gerenciamento de Imagens e Registry Privado
No ciclo de vida do desenvolvimento, você precisará enviar suas imagens para um repositório. Embora existam registries públicos (Docker Hub), em VPS corporativas ou projetos sensíveis, é comum utilizar um registry privado.
Para criar um registry privado localmente (apenas para testes ou rede interna), execute:
docker run -d -p 5000:5000 --name registry registry:2
Agora, marque sua imagem e envie para o registry:
docker tag nginx:latest localhost:5000/minha-aplicacao:v1
docker push localhost:5000/minha-aplicacao:v1
Lembre-se de que registries locais exigem configuração de segurança (HTTPS ou permissão para HTTP não seguro em /etc/docker/daemon.json) para produção.
Automação com Watchtower
Manter containers atualizados manualmente é propenso a erros. O Watchtower é um container que monitoriza outros containers e os atualiza automaticamente quando novas versões são detectadas no registry.
Instale o Watchtower:
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Por padrão, ele verifica a cada 5 minutos. Você pode ajustar o intervalo e excluir containers antigos após a atualização:
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower \
--interval 3600 \
--cleanup
Isso garante que sua VPS esteja sempre rodando as versões mais seguras e com correções de bugs, sem intervenção manual.
Proteção com Traefik e SSL Automático
Acessar containers diretamente via porta (ex: :8080) não é escalável nem seguro. Um reverse proxy é essencial para rotear tráfego, gerenciar certificados SSL/TLS e expor apenas as portas necessárias.
O Traefik é um proxy reverso moderno que se integra nativamente ao Docker. Ele lê as labels dos seus containers e configura rotas automaticamente.
Crie o arquivo de configuração traefik.yml:
api:
dashboard: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /etc/traefik/acme.json
httpChallenge:
entryPoint: web
No docker-compose.yml da sua aplicação, adicione as labels para o Traefik:
services:
web:
image: nginx:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`meusite.com`)"
- "traefik.http.routers.web.entrypoints=websecure"
- "traefik.http.routers.web.tls.certresolver=letsencrypt"
volumes:
- ./html:/usr/share/nginx/html
E configure o serviço do Traefik para expor a porta 80/443 e montar os arquivos de configuração:
services:
traefik:
image: traefik:v2.10
command:
- "--providers.file.filename=/etc/traefik/traefik.yml"
- "--api.dashboard=true"
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard (recomendado restringir IP)
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/etc/traefik/traefik.yml
- ./acme.json:/etc/traefik/acme.json
Inicie os serviços. O Traefik solicitará certificados Let's Encrypt automaticamente para o domínio especificado.
Persistência de Dados e Backups
Dados em containers são efêmeros. Se um container for removido, todos os dados escritos nele (dentro do sistema de arquivos do container) são perdidos. Para evitar isso, utilize volumes.
No exemplo anterior, usamos db_data:/var/lib/postgresql/data. Isso cria um volume gerenciado pelo Docker em /var/lib/docker/volumes/. Para backups ou migrações, você pode copiar esses dados:
docker run --rm -v db_data:/source -v $(pwd):/backup alpine tar czf /backup/db_backup.tar.gz -C /source .
Para restaurar:
docker run --rm -v db_data:/target -v $(pwd):/backup alpine tar xzf /backup/db_backup.tar.gz -C /target
Troubleshooting Comum
Mesmo com configurações robustas, problemas ocorrem. Abaixo estão as causas mais frequentes e como resolvê-las.
Container reiniciando infinitamente
Se o status do container for "Restarting", verifique os logs:
docker logs -f nome_do_container
A causa mais comum é erro na configuração da aplicação ou falta de permissões em volumes montados.
Problemas de Rede
Se um container não consegue acessar outro, verifique se estão na mesma rede Docker. Containers na rede padrão bridge podem ter dificuldades de comunicação direta por nome.
docker network ls
docker network create minha-rede-local
Espaço em Disco Cheio
O Docker consome muito disco com imagens e logs antigos. Limpe recursos não utilizados:
docker system prune -a --volumes
Cuidado: isso remove todas as imagens não utilizadas e volumes órfãos. Execute com cautela em produção.
Docker Compose não encontra comando
Se o comando docker compose (sem hífen) falhar, verifique se o plugin foi instalado corretamente. Em versões antigas, usava-se docker-compose (com hífen). Para verificar a versão:
docker compose version
Conclusão e Melhores Práticas
A instalação do Docker e Compose em uma VPS é o primeiro passo para uma infraestrutura ágil. No entanto, a gestão contínua exige disciplina.
Principais recomendações:
- Nunca exponha portas sensíveis diretamente à internet. Use sempre um reverse proxy como Traefik ou Nginx.
- Mantenha as imagens atualizadas. Utilize o Watchtower para automação, mas teste mudanças em ambiente de staging primeiro.
- Monitore o uso de recursos. Containers podem consumir CPU e memória ilimitadamente se não houver limites. Use
docker run --memory=512m --cpus="0.5". - Separe ambientes. Nunca use a mesma VPS para desenvolvimento e produção sem isolamento rigoroso de rede e usuários.
Com esta base, você está preparado para orquestrar aplicações complexas, garantir alta disponibilidade e manter sua infraestrutura segura e eficiente.