Harbor na Prática — Parte 2 Projetos e Repositórios
Nesta parte, vamos entender como o Harbor organiza as imagens em projetos e repositórios, e como criá-los de três formas diferentes: pela interface web, via API REST e via Terraform.
Como o Harbor organiza as imagens
Antes de criar qualquer coisa, é importante entender a hierarquia do Harbor:
Harbor
└── Projeto (ex: backend)
├── Repositório (ex: backend/api)
│ ├── Tag: v1.0.0
│ ├── Tag: v1.1.0
│ └── Tag: latest
└── Repositório (ex: backend/worker)
└── Tag: v1.0.0
- Projeto — é o agrupamento principal, equivale a uma organização ou equipa. Define as políticas de acesso, quotas e configurações de segurança.
- Repositório — criado automaticamente no primeiro
docker push. Representa uma imagem específica com suas versões. - Tag — identifica uma versão específica de uma imagem dentro de um repositório.
O endereço completo de uma imagem no Harbor segue o padrão:
harbor.empresa.com/<projeto>/<repositorio>:<tag>
Tipos de projeto
Privado — apenas membros com acesso explícito podem fazer pull das imagens. Ideal para imagens de aplicações internas.
Público — qualquer usuário autenticado (ou anônimo, se configurado) pode fazer pull. Útil para imagens base padronizadas que várias equipes usam no dockerfile.
Criando projetos via Interface Web
Passo 1 — Acessar a criação de projeto
No menu lateral, clique em Projects → New Project.
Passo 2 — Preencher os dados
| Campo | Descrição | Exemplo |
|---|---|---|
| Project Name | Nome único do projeto | backend |
| Access Level | Público ou Privado | Private |
| Storage Limit | Quota de storage (em GB) | -1 para ilimitado |
| Proxy Cache | Se é um projeto de proxy cache | Deixar desmarcado por agora |
Passo 3 — Confirmar
Clique em OK. O projeto aparecerá na lista e já está pronto para receber imagens.
Os repositórios dentro do projeto não precisam ser criados manualmente. Eles são criados automaticamente quando você faz o primeiro
docker pushcom aquele caminho.
Criando projetos via API REST
O Harbor expõe uma API REST completa. Isso é útil para automação e integração com pipelines.
Autenticação
Todas as chamadas à API usam autenticação HTTP Basic:
# Variáveis para facilitar os exemplos
HARBOR_URL="https://harbor.empresa.com"
HARBOR_USER="admin"
HARBOR_PASS="suasenha"
Criar um projeto
curl -X POST "${HARBOR_URL}/api/v2.0/projects" \
-H "Content-Type: application/json" \
-u "${HARBOR_USER}:${HARBOR_PASS}" \
-d '{
"project_name": "backend",
"metadata": {
"public": "false"
},
"storage_limit": -1
}'
Listar projetos existentes
curl -s "${HARBOR_URL}/api/v2.0/projects" \
-u "${HARBOR_USER}:${HARBOR_PASS}" | jq '.[].name'
Listar repositórios de um projeto
curl -s "${HARBOR_URL}/api/v2.0/projects/backend/repositories" \
-u "${HARBOR_USER}:${HARBOR_PASS}" | jq '.[].name'
Listar tags de um repositório
curl -s "${HARBOR_URL}/api/v2.0/projects/backend/repositories/api/artifacts" \
-u "${HARBOR_USER}:${HARBOR_PASS}" | jq '.[].tags[].name'
Apagar um repositório
curl -X DELETE "${HARBOR_URL}/api/v2.0/projects/backend/repositories/api" \
-u "${HARBOR_USER}:${HARBOR_PASS}"
Criando projetos via Terraform
Para ambientes onde a infraestrutura é gerida como código, o Terraform é a melhor opção. O provider oficial do Harbor é o goharbor/harbor.
Configurando o provider
# providers.tf
terraform {
required_providers {
harbor = {
source = "goharbor/harbor"
version = "~> 3.10"
}
}
}
provider "harbor" {
url = "https://harbor.empresa.com"
username = var.harbor_username
password = var.harbor_password
insecure = false
}
Variáveis
# variables.tf
variable "harbor_username" {
type = string
sensitive = true
}
variable "harbor_password" {
type = string
sensitive = true
}
Criando projetos e configurações
# main.tf
# Projeto privado para o time de backend
resource "harbor_project" "backend" {
name = "backend"
public = false
vulnerability_scanning = true # scan automático no push
force_destroy = false # protege contra delete acidental
}
# Projeto público para imagens base
resource "harbor_project" "base_images" {
name = "base"
public = true
vulnerability_scanning = true
storage_quota = 20 # limite de 20 GB
}
# Regra de imutabilidade de tags — impede sobrescrever tags de release
resource "harbor_immutable_tag_rule" "backend_releases" {
project_id = harbor_project.backend.id
repo_matching = "**"
tag_matching = "v*.*.*" # qualquer tag semântica
}
Outputs úteis
# outputs.tf
output "backend_project_id" {
value = harbor_project.backend.id
}
output "backend_registry_url" {
value = "harbor.empresa.com/${harbor_project.backend.name}"
}
Aplicar
terraform init
terraform plan
terraform apply
Boas práticas de organização
Organize por equipa ou domínio de negócio
harbor.empresa.com/backend/api:v1.0.0
harbor.empresa.com/frontend/web:v2.3.1
harbor.empresa.com/data/pipeline:latest
harbor.empresa.com/base/python:3.12-slim
Use tags semânticas em vez de latest em produção
A tag latest é mutável e pode causar comportamentos inesperados. Prefira tags com versão explícita:
harbor.empresa.com/backend/api:1.4.2
harbor.empresa.com/backend/api:main-a3f9c12
Separe projetos por ambiente apenas se necessário
Em vez de criar backend-dev, backend-staging, backend-prod, prefira um único projeto backend e use tags para diferenciar os ambientes. Isso simplifica a gestão de permissões e evita duplicação de imagens.
Próximo artigo
Na Parte 3, vamos configurar a gestão de usuários no Harbor — criando usuários locais, integrando com LDAP/Active Directory e criando Robot Accounts para pipelines CI/CD.