Skip to main content

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óriocriado 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 ProjectsNew Project.

Passo 2 — Preencher os dados

CampoDescriçãoExemplo
Project NameNome único do projetobackend
Access LevelPúblico ou PrivadoPrivate
Storage LimitQuota de storage (em GB)-1 para ilimitado
Proxy CacheSe é um projeto de proxy cacheDeixar 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 push com 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.