Docker: Repositório Privado de Imagens

Última atualização: 2026-08-26

Não quer enviar o código da sua empresa para o Docker Hub público? Configure um repositório privado de imagens em 5 minutos.

1. O Que Você Vai Aprender



2. Uma História Real de uma Pessoa Líder de Equipe

(1) Ponto de Dor: O código não pode ser enviado para um repositório público

Alice não quer enviar o código da empresa para o Docker Hub público — as imagens podem conter informações sensíveis, como arquivos de configuração e valores padrão de variáveis de ambiente. No entanto, a equipe precisa de um repositório de imagens para compartilhar artefatos de build; transferir manualmente com docker save/load é muito ineficiente — cinco pessoas desenvolvedoras levam 30 minutos cada vez que uma imagem precisa ser repassada.

(2) Soluções para Registries Privados

Configurei um repositório privado com autenticação usando apenas três linhas de configuração.

BASH
# Iniciar um registry privado com autenticação
docker run -d -p 5000:5000 \
  -v registry-data:/var/lib/registry \
  --restart=always \
  --name registry registry:2

(3) Benefícios: Compartilhamento de imagens em 5 minutos

As equipes podem começar a usar repositórios privados em 5 minutos. docker push uma vez, e todas as pessoas fazem docker pull. O tempo de entrega de imagens foi reduzido de 30 minutos para 30 segundos.



3. Comparação de Soluções de Repositório de Imagens

(1) Comparação das Três Opções

Dimensão Docker Hub (Público) Registry Privado Harbor
Custo Gratuito com limites; plano pago $5/mês Completamente gratuito Gratuito e open source
Autenticação Conta Docker htpasswd/TLS LDAP/OIDC/DB
Interface Web
Escaneamento de Imagens ✅ (Pago) ✅ (Integração Trivy)
Dificuldade de Implantação Nenhuma (Já no ar) Baixa (1 comando) Média (Docker Compose)
Escala Adequada Individual/Pequenas Equipes Equipes Pequenas a Médias Empresarial

(2) Convenções de Nomenclatura de Imagens

TEXT 📖 Somente leitura
# Imagens oficiais no Docker Hub
docker.io/library/nginx:1.25

# Imagens de usuário no Docker Hub
docker.io/myorg/myapp:v2.0

# Imagens de registry privado
localhost:5000/myapp:v2.0
registry.example.com/team/app:v1.0


4. Implantando um Registry Privado

▶ Exemplo: Iniciando o Contêiner do Registry (Dificuldade: ⭐)

BASH
# Iniciar um registry privado básico
docker run -d \
  -p 5000:5000 \
  --name registry \
  --restart=always \
  -v registry-data:/var/lib/registry \
  registry:2

# Verificar se está em execução
curl http://localhost:5000/v2/_catalog
💻 Saída:

TEXT 📖 Somente leitura
{"repositories":[]}

(1) Persistência de Dados

Método Comando Descrição
Volume Nomeado -v registry-data:/var/lib/registry Armazenamento persistente gerenciado pelo Docker
Bind Mount -v /data/registry:/var/lib/registry Especificar diretório do host
Padrão (sem -v) Sem persistência Dados da imagem são perdidos quando o contêiner é excluído
⚠️ Nota: Em um ambiente de produção, você deve usar um volume ou bind mount para persistir dados. Caso contrário, todas as imagens enviadas serão perdidas quando o contêiner do Registry for excluído.



5. Enviando e Recebendo Imagens

▶ Exemplo: Enviando para um repositório privado (Dificuldade: ⭐⭐)

BASH
# 1. Marcar uma imagem para o registry privado
docker tag nginx:1.25-alpine localhost:5000/web/nginx:v1

# 2. Enviar a imagem
docker push localhost:5000/web/nginx:v1

# 3. Verificar se está no registry
curl http://localhost:5000/v2/web/nginx/tags/list
💻 Saída:

TEXT 📖 Somente leitura
{"name":"web/nginx","tags":["v1"]}

▶ Exemplo: Baixando uma imagem de um repositório privado (Dificuldade: ⭐⭐)

BASH
# 1. Remover a cópia local
docker rmi localhost:5000/web/nginx:v1

# 2. Baixar do registry privado
docker pull localhost:5000/web/nginx:v1

# 3. Executar a imagem baixada
docker run --rm localhost:5000/web/nginx:v1 nginx -v
💻 Saída:

TEXT 📖 Somente leitura
nginx version: nginx/1.25.3


6. Configuração de Autenticação do Repositório

Por padrão, o registry não é autenticado, então qualquer pessoa pode fazer push ou pull. A autenticação deve ser configurada para ambientes de produção.

▶ Exemplo: Gerando um arquivo de senha htpasswd (Dificuldade: ⭐⭐⭐)

BASH
# Criar um diretório para dados de autenticação
mkdir -p auth

# Gerar arquivo htpasswd (requer httpd-tools / apache2-utils)
htpasswd -Bbn admin secret123 > auth/htpasswd

# Iniciar registry com autenticação
docker run -d \
  -p 5000:5000 \
  --name registry-auth \
  --restart=always \
  -v registry-data:/var/lib/registry \
  -v $(pwd)/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
  registry:2

(1) Operações Pós-Autenticação

BASH
# Fazer login no registry privado
docker login localhost:5000
# Usuário: admin
# Senha: secret123

# Push (requer login)
docker push localhost:5000/myapp:v1

# Pull (requer login)
docker pull localhost:5000/myapp:v1

# Logout
docker logout localhost:5000


7. Visualizar o diretório do repositório

▶ Exemplo: Use curl para visualizar o catálogo e as tags (Dificuldade: ⭐⭐)

BASH
# Listar todos os repositórios
curl -s http://localhost:5000/v2/_catalog | python3 -m json.tool

# Listar tags de um repositório específico
curl -s http://localhost:5000/v2/web/nginx/tags/list | python3 -m json.tool

# Visualizar manifesto da imagem (metadados detalhados)
curl -s -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  http://localhost:5000/v2/web/nginx/manifests/v1 | python3 -m json.tool
💻 Saída:

TEXT 📖 Somente leitura
# catalog
{
  "repositories": [
    "web/nginx",
    "team/api"
  ]
}

# tags/list
{
  "name": "web/nginx",
  "tags": ["v1", "v2"]
}


8. Coleta de Lixo

Após uma imagem no Registry ser excluída (sem tag), os dados da camada não são automaticamente limpos. Você deve realizar manualmente a coleta de lixo.

▶ Exemplo: Coleta de Lixo (Dificuldade: ⭐⭐⭐)

BASH
# Excluir uma tag (marcar para exclusão)
curl -X DELETE -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  http://localhost:5000/v2/web/nginx/manifests/<digest>

# Executar coleta de lixo dentro do contêiner do registry
docker exec registry bin/registry garbage-collect \
  /etc/docker/registry/config.yml

# Ou com dry-run primeiro (apenas visualização)
docker exec registry bin/registry garbage-collect --dry-run \
  /etc/docker/registry/config.yml


9. Repositórios HTTP vs. HTTPS

(1) Políticas de Segurança do Docker

Por padrão, o Docker só permite conexões HTTPS para o registry (exceto para localhost). Registries remotos devem ser configurados com HTTPS, ou a opção insecure-registries deve ser adicionada no lado do cliente.

Cenário Nível de Segurança Configuração
localhost:5000 HTTP permitido por padrão Nenhuma configuração adicional necessária
Repositório HTTP Remoto Inseguro, requer permissão explícita insecure-registries
Repositório HTTPS Remoto ✅ Recomendado Certificado TLS

(2) Configurar insecure-registries (apenas para ambientes de teste)

JSON
{
  "insecure-registries": ["registry.example.com:5000"]
}
🔒 Segurança: Ambientes de produção devem usar HTTPS + um certificado TLS confiável. "insecure-registries" é destinado apenas para testes internos; o tráfego é vulnerável a ataques man-in-the-middle.



10. Exemplo Completo: Implantando um Repositório Privado com Autenticação

BASH
# ============================================
# Passo a passo completo: Registry privado com autenticação
# Abrange: implantar, autenticar, push, pull, catálogo, GC
# ============================================

# 1. Criar diretórios para dados persistentes
mkdir -p auth registry-data

# 2. Gerar arquivo de autenticação htpasswd
htpasswd -Bbn admin secret123 > auth/htpasswd

# 3. Iniciar o registry com autenticação e persistência
docker run -d \
  -p 5000:5000 \
  --name my-registry \
  --restart=always \
  -v $(pwd)/registry-data:/var/lib/registry \
  -v $(pwd)/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
  registry:2

# 4. Fazer login no registry
docker login localhost:5000 -u admin -p secret123

# 5. Marcar e enviar uma imagem
docker tag nginx:1.25-alpine localhost:5000/web/nginx:v1.0
docker push localhost:5000/web/nginx:v1.0

# 6. Verificar o envio
curl -s -u admin:secret123 http://localhost:5000/v2/_catalog
curl -s -u admin:secret123 http://localhost:5000/v2/web/nginx/tags/list

# 7. Baixar de outra máquina (após login)
docker pull localhost:5000/web/nginx:v1.0

# 8. Limpar
docker logout localhost:5000
💻 Saída (trecho):

TEXT 📖 Somente leitura
# curl catalog
{"repositories":["web/nginx"]}

# curl tags
{"name":"web/nginx","tags":["v1.0"]}

❓ Perguntas Frequentes

P: Quanto espaço de armazenamento um repositório privado requer? R: Depende do número e tamanho das imagens. Uma única imagem varia de 50 a 500 MB, e 10 imagens ocupam aproximadamente 1 a 5 GB. Recomendamos alocar 50 GB inicialmente e limpar regularmente versões antigas. Para uso empresarial, recomendamos usar armazenamento de objetos (S3/OSS) como backend do registry, com armazenamento que escala sob demanda.

P: Como configurar HTTPS para um repositório? R: Existem duas maneiras: ① Usar Nginx ou Caddy como proxy reverso e configurar um certificado TLS (recomendado); ② Configurar TLS diretamente no Registry. Recomendamos a abordagem de proxy reverso — o Nginx gerencia a terminação TLS, enquanto o Registry foca no armazenamento. Let's Encrypt fornece certificados gratuitos.

P: Como limpar quando há muitas imagens? R: Duas etapas: ① Use a API DELETE para remover tags/manifestos desnecessários; ② Execute registry garbage-collect para liberar dados de camada não referenciados. Recomendamos escrever um script para limpar periodicamente versões antigas com mais de N dias. O Harbor possui políticas de limpeza integradas.

P: Outras pessoas podem visualizar as imagens no repositório? R: Sem autenticação, qualquer pessoa pode fazer pull (acesso anônimo). Após configurar a autenticação htpasswd, é necessário fazer login para push ou pull. Recomendado para ambientes de produção: permissões somente leitura para pull e permissões de escrita para push (Registry 2.8+ suporta RBAC).

P: Qual é melhor usar, Harbor ou Registry? R: Registry é um repositório minimalista (adequado para equipes pequenas e CI), enquanto Harbor é um repositório de nível empresarial (interface web + escaneamento de imagens + RBAC + logs de auditoria). Equipes com menos de 10 membros devem usar Registry, enquanto aquelas com mais de 10 membros ou com requisitos de conformidade devem usar Harbor. O próprio Harbor é implantado usando Docker Compose e pode ser configurado em 5 minutos.


📖 Resumo


📝 Exercícios

  1. Exercício Básico (Dificuldade: ⭐): Inicie um registry privado usando docker run, envie nginx:alpine para localhost:5000/test/nginx:v1 e depois baixe de outra máquina (ou após excluir a imagem local) para verificar.
  2. Exercício Avançado (Dificuldade: ⭐⭐): Configure autenticação htpasswd para que pushes sejam rejeitados quando não autenticado, mas bem-sucedidos após o login.
  3. Desafio (Dificuldade: ⭐⭐⭐): Use um proxy reverso Nginx para configurar HTTPS para o Registry (um certificado autoassinado pode ser usado), e acesse o repositório via https://registry.local/v2/_catalog.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%