Criar registry Docker privado com autenticação e espelhamento (mirror) em VPS: tutorial passo a passo
Docker & Containers · Por Kevin Marcondes · Publicado em · Atualizado em · 8 min de leitura
Neste tutorial — criar registry Docker privado com autenticação e espelhamento (mirror) em VPS — você vai subir um Docker Registry com htpasswd, habilitar pull‑through cache do Docker Hub e protegê‑lo com HTTPS via reverse proxy. No final, seus clientes Docker usarão o mirror e farão push de imagens privadas com segurança.
1. Pré‑requisitos e arquitetura do que vamos montar
Você precisa de uma VPS Linux atualizada, domínio (ex.: registry.example.com) apontando para o servidor e portas 80/443 liberadas. Será necessário acesso root ou sudo.
Vamos usar Docker + Compose para subir: (1) registry privado com autenticação htpasswd; (2) pull‑through cache do Docker Hub; (3) reverse proxy com HTTPS automático.
Se ainda não instalou, siga o guia como instalar Docker e Docker Compose no Linux. Faça o hardening com o checklist de segurança para VPS Linux e libere as portas no firewall; veja como configurar UFW.
- VPS com CPU/RAM/disco compatíveis com seu volume de imagens.
- DNS A/AAAA para registry.example.com apontando para a VPS.
- Docker e Docker Compose instalados.
- Portas 80/443 e 5000 abertas no firewall.
2. Criar diretórios e arquivo de senhas (htpasswd)
Crie a estrutura de dados e gere o htpasswd. Usaremos a imagem httpd apenas para gerar o arquivo de senhas. Troque o usuário e a senha por valores fortes e guarde-os com segurança.
sudo mkdir -p /opt/registry/{data,auth}
# Gere um usuário e senha para acessar o registry
# Substitua registryuser e a senha por valores fortes
docker run --rm --entrypoint htpasswd httpd:2 -Bbn registryuser 'S3nh@F0rte' \
> /opt/registry/auth/htpasswd
# Revise permissões conforme sua política de segurança
sudo chmod 640 /opt/registry/auth/htpasswd
sudo chown root:root /opt/registry/auth/htpasswd
3. Subir o Docker Registry com autenticação (porta 5000)
Vamos iniciar o registry com autenticação htpasswd. Nesta etapa rodaremos sem TLS, pois o HTTPS será tratado pelo reverse proxy mais adiante. Restrinja o acesso na firewall até configurar HTTPS.
# docker-compose.yml
version: "3.9"
services:
registry:
image: registry:2
container_name: registry
restart: unless-stopped
ports:
- "5000:5000"
environment:
- REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry
- REGISTRY_AUTH=htpasswd
- REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm
- REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
- REGISTRY_STORAGE_DELETE_ENABLED=true
volumes:
- /opt/registry/data:/var/lib/registry
- /opt/registry/auth:/auth
# Suba o serviço (na mesma pasta do docker-compose.yml)
# Compose v2:
docker compose up -d registry
4. Ativar pull-through cache (mirror) do Docker Hub
Para reduzir latência e economizar banda, ative o espelhamento. O registry fará cache de imagens públicas do Docker Hub conforme forem puxadas pelos clientes. Não é um mirror completo; só faz cache do que for solicitado.
- Mantém camadas em disco local, acelerando pulls repetidos.
- Respeita rate limit do Docker Hub; opcional usar credenciais próprias.
# Edite docker-compose.yml e adicione a variável de proxy
services:
registry:
environment:
- REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io
# Opcional: para limites do Hub, defina usuário/senha do Hub
# - REGISTRY_PROXY_USERNAME=seu_usuario
# - REGISTRY_PROXY_PASSWORD=sua_senha
# Recrie o serviço
docker compose up -d registry
# Verifique logs
docker logs -f registry
5. HTTPS com reverse proxy (Caddy) e domínio próprio
Vamos colocar o registry atrás do Caddy para HTTPS automático. Garanta DNS resolvendo para a VPS e portas 80/443 abertas, pois o ACME precisa validar o domínio.
Se preferir Traefik ou Nginx, compare opções em Traefik vs Caddy para HTTPS em Docker e escolha o que encaixa no seu stack.
- TLS automático e renovação transparente.
- Proxy reverso simples de configurar com Caddy.
# Adicione o Caddy ao docker-compose.yml
services:
caddy:
image: caddy:2
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- registry
volumes:
caddy_data:
caddy_config:
---
# Crie o arquivo Caddyfile na mesma pasta
# Substitua registry.example.com pelo seu domínio
registry.example.com {
encode gzip
reverse_proxy registry:5000
}
# Suba/recrie tudo
docker compose up -d
6. Configurar clientes Docker para usar o mirror e o registry
Nos clientes (máquinas de dev, servidores de CI), aponte o mirror e reinicie o daemon. Reiniciar o Docker pode interromper containers em execução. Em seguida, faça login para operações de push no seu domínio.
- Mirror acelera pulls de imagens públicas do Docker Hub.
- Push/pull de imagens privadas usa seu domínio com login.
# Linux (systemd): configure o mirror e reinicie o Docker
sudo tee /etc/docker/daemon.json >/dev/null <<'JSON'
{
"registry-mirrors": ["https://registry.example.com"],
"insecure-registries": [],
"log-driver": "json-file",
"log-opts": {"max-size": "10m", "max-file": "3"}
}
JSON
sudo systemctl restart docker
# Verifique
docker info | grep -A2 'Registry Mirrors'
7. Publicar e consumir imagens privadas; testar o mirror
Depois de configurar o cliente, autentique-se e envie uma imagem para seu registry. Também validaremos o mirror puxando uma imagem pública comum após setar o registry‑mirror.
# Faça login no seu registry
docker login registry.example.com
# Marque e envie sua imagem
# Exemplo: container local "myapp:1.0"
docker tag myapp:1.0 registry.example.com/minhaorg/myapp:1.0
docker push registry.example.com/minhaorg/myapp:1.0
# Teste pull privado
docker pull registry.example.com/minhaorg/myapp:1.0
# Teste o mirror (imagem pública do Hub)
docker pull nginx:alpine # deve ser servido via mirror após primeiro pull
8. Verificação e solução de problemas comuns
Confirme o acesso e observe logs. Em falhas de HTTPS, cheque DNS e firewall. Para economizar espaço, avalie limpeza de tags e coleta de lixo do registry. Rodar garbage‑collect remove camadas órfãs; faça backup antes.
- Teste API do registry: catálogo e tags.
- Veja logs do container registry e do proxy.
- Erros de certificado: confirme domínio e portas.
- Rate limit no Hub: considere credenciais no proxy.
# Testes rápidos (ajuste domínio/credenciais)
curl -u registryuser:S3nh@F0rte -fsSL https://registry.example.com/v2/_catalog | jq .
# Listar tags de um repositório
curl -u registryuser:S3nh@F0rte -fsSL https://registry.example.com/v2/minhaorg/myapp/tags/list | jq .
# Logs
docker logs --tail=100 registry
# (Opcional) Garbage collect — pare o serviço antes
# docker compose stop registry
# docker run --rm -v /opt/registry/data:/var/lib/registry \
# -v /opt/registry/auth:/auth registry:2 \
# garbage-collect /etc/docker/registry/config.yml
Perguntas frequentes
Qual a diferença entre registry privado e mirror (pull‑through cache)?
O registry privado armazena suas imagens sob o seu domínio e controle. O mirror atua como cache para imagens públicas do Docker Hub: ele baixa sob demanda, guarda em disco e acelera pulls futuros. Você pode usar o mesmo serviço para ambos, com autenticação.
Preciso de autenticação para usar o mirror?
Para pulls de imagens públicas, o mirror pode ser acessado sem autenticação se você expor assim no proxy. Contudo, é recomendável exigir autenticação para todo acesso. Para pushes de imagens privadas, autenticação é obrigatória com docker login.
Onde ficam armazenadas as camadas em cache?
As camadas ficam no diretório configurado do registry, no volume montado em /var/lib/registry. Garanta espaço em disco suficiente e coloque o volume em disco rápido. Faça backup periódico se as imagens forem críticas para o seu processo.
Como limpar espaço em disco no registry?
Remova tags não utilizadas e rode a coleta de lixo (garbage‑collect) do registry com o serviço parado. Ela remove camadas órfãs. Faça backup antes, pois a operação é destrutiva para blobs não referenciados. Planeje manutenção para evitar indisponibilidade.
Posso usar um certificado TLS próprio em vez de ACME?
Sim. No Caddy ou no seu proxy, desabilite o gerenciamento automático e aponte para seus arquivos de certificado e chave. Distribua a cadeia completa aos clientes. Caso use CA interna, adicione o certificado raiz ao trust store dos hosts clientes.
O mirror acelera imagens privadas de outros registries?
Não. O pull‑through cache descrito aqui é para o Docker Hub público. Pulls de registries privados de terceiros não passam pelo mirror. Para esses casos, autentique-se e puxe diretamente do registry de origem configurado.
Precisa de ajuda para adaptar o setup ao seu ambiente?
Se quiser revisar topologia, políticas de acesso, automação de TLS ou integração com CI/CD, podemos conversar sobre caminhos e riscos comuns.
Falar sobre o seu cenárioVeja também
- tutorial: implementar Canary releases com Traefik em Docker Compose usando headers e weight routing para deploys graduais de aplicações PHP
- Tutorial: configurar HAProxy com Let's Encrypt e healthchecks para balanceamento de tráfego entre containers Docker em VPS (passo a passo)
- Tutorial prático: implementar mTLS entre Nginx e microserviços usando smallstep CA em Docker Compose
- Tutorial: configurar cgroup v2 e systemd ResourceControl para limitar CPU, memória e I/O de containers Docker no Debian