Criar registry Docker privado com autenticação e espelhamento (mirror) em VPS: tutorial passo a passo

Docker & Containers · Por · Publicado em · Atualizado em · 8 min de leitura

Guindastes de porto para movimentação de contêineres sobre o cais e céu claro
Guindastes portuários em um cais sob céu claro. Foto: Wolfgang Weiser / Pexels

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ário

Veja também