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
- Implantação de Imagens do Registry
- Operações de Push e Pull de Imagens
- Configuração de Autenticação do Repositório
- Limpeza de Imagens e Coleta de Lixo
- Abordagens para Integrar Repositórios com CI/CD
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.
# 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
# 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: ⭐)
# 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
{"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 |
5. Enviando e Recebendo Imagens
▶ Exemplo: Enviando para um repositório privado (Dificuldade: ⭐⭐)
# 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
{"name":"web/nginx","tags":["v1"]}
▶ Exemplo: Baixando uma imagem de um repositório privado (Dificuldade: ⭐⭐)
# 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
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: ⭐⭐⭐)
# 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
# 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: ⭐⭐)
# 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
# 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: ⭐⭐⭐)
# 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)
{
"insecure-registries": ["registry.example.com:5000"]
}
10. Exemplo Completo: Implantando um Repositório Privado com Autenticação
# ============================================
# 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
# 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-collectpara 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
registry:2Imagem: Inicie um repositório privado com um único comando; os dados devem ser persistidos usando um volume- Convenção de nomenclatura de imagens:
registry-host/repo:tag; é necessário marcar antes de enviar - O repositório é protegido por autenticação htpasswd; é necessário executar
docker loginantes de poder fazer push ou pull curl /v2/_cataloge/v2/repo/tags/listVisualizar conteúdo do repositório- Coleta de lixo (garbage-collect) libera dados de camada de imagens excluídas
- HTTPS é necessário em ambientes de produção; HTTP é limitado a localhost ou ambientes de teste
📝 Exercícios
- Exercício Básico (Dificuldade: ⭐): Inicie um registry privado usando
docker run, envienginx:alpineparalocalhost:5000/test/nginx:v1e depois baixe de outra máquina (ou após excluir a imagem local) para verificar. - 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.
- 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.