Docker Images - Build & Publish
📋 Visão Geral
Sistema automatizado de build e publicação de imagens Docker para todos os serviços Audissey, com versionamento semântico e deploy para Azure Container Registry (ACR).
🐳 Imagens Docker
Serviços Disponíveis
1. **API Service** (`audissey-api`)
- Base: Node.js 24 Alpine
- Path:
/Dockerfile - Port: 3000
- Registry:
audissey.azurecr.io/audissey-api
2. **Worker Service** (`audissey-worker`)
- Base: Node.js 24 Alpine
- Path:
/Dockerfile.worker - Port: 3001
- Registry:
audissey.azurecr.io/audissey-worker
3. **ML Service** (`audissey-ml`)
- Base: Python 3.11 Slim
- Path:
/apps/ml-service/Dockerfile - Port: 8000
- Registry:
audissey.azurecr.io/audissey-ml
📦 Versionamento
Sistema de Versões
O projeto usa Semantic Versioning (SemVer):
- MAJOR: Mudanças incompatíveis (breaking changes)
- MINOR: Novas funcionalidades (backwards-compatible)
- PATCH: Bug fixes (backwards-compatible)
Arquivo `version.json`
{
"version": "1.0.0",
"services": {
"api": "1.0.0",
"worker": "1.0.0",
"ml-service": "0.1.0"
},
"lastUpdated": "2025-12-27T00:00:00Z"
}
Script de Bump
# Fazer bump de um serviço específico
./scripts/bump-version.sh api patch # 1.0.0 -> 1.0.1
./scripts/bump-version.sh worker minor # 1.0.0 -> 1.1.0
./scripts/bump-version.sh ml-service major # 0.1.0 -> 1.0.0
# Fazer bump de todos os serviços
./scripts/bump-version.sh all patch
Após bump:
# Commit e tag
git add version.json
git commit -m "chore: bump version to v1.0.1"
git tag v1.0.1
git push origin main --tags
🔄 Pipeline CI/CD
Arquivo: `azure-pipelines-docker.yml`
Triggers
- Branch:
mainapenas - Tags:
v*(ex: v1.0.0, v1.2.3)
Stages
1. Get Version Info
- Lê
version.json - Extrai versões de cada serviço
- Disponibiliza como variáveis
2. Build & Push API
- Build da imagem API
- Tags:
vX.Y.Z,build-id - Push para ACR
3. Build & Push Worker
- Build da imagem Worker
- Tags:
vX.Y.Z,build-id - Push para ACR
4. Build & Push ML
- Build da imagem ML Service
- Tags:
vX.Y.Z,build-id - Push para ACR
5. Summary
- Resumo de todas as imagens publicadas
- URLs completas no ACR
Autenticação das pipelines BuildKit
As pipelines de build usam login direto no audissey.azurecr.io com os
secrets ACR_USERNAME e ACR_PASSWORD do Variable Group audissey-dev.
Este fluxo mantém as credenciais no ~/.docker/config.json, que também é
utilizado pelo driver docker-container do BuildKit. O login Docker@2 não
deve ser reintroduzido nestas builds: ele usa um DOCKER_CONFIG temporário e
pode causar 401 Unauthorized no endpoint OAuth do ACR durante --push ou--cache-to.
Tags Geradas
Cada imagem recebe tags determinísticas (sem latest):
audissey.azurecr.io/audissey-api:1.0.0
audissey.azurecr.io/audissey-api:123456 (build ID)
🚀 Setup do Azure Container Registry
1. Criar Container Registry
# Variáveis
RESOURCE_GROUP="audissey-shared-rg"
REGISTRY_NAME="audissey"
LOCATION="westeurope"
# Criar ACR
az acr create \
--resource-group $RESOURCE_GROUP \
--name $REGISTRY_NAME \
--sku Basic \
--admin-enabled true \
--location $LOCATION
# Verificar
az acr show --name $REGISTRY_NAME --query loginServer
# Output: audissey.azurecr.io
2. Configurar Service Connection no Azure DevOps
Via Portal:
- Azure DevOps → Project Settings
- Service connections → New service connection
- Docker Registry
- Registry type: Azure Container Registry
- Subscription: Selecionar subscription
- Registry:
audissey - Service connection name:
audissey-acr-connection-shared - Security: Grant access to all pipelines: ❌ NÃO marcar (princípio do menor privilégio)
- Save
Autorizar pipelines específicos:
- Na primeira execução do pipeline, Azure DevOps pedirá autorização
- Ou configure manualmente: Pipeline → Edit → More actions (⋮) → Security → Pipeline permissions
Via CLI:
# Get ACR credentials
ACR_USER=$(az acr credential show --name $REGISTRY_NAME --query username -o tsv)
ACR_PASSWORD=$(az acr credential show --name $REGISTRY_NAME --query passwords[0].value -o tsv)
echo "Username: $ACR_USER"
echo "Password: $ACR_PASSWORD"
# Usar no Azure DevOps
3. Criar Pipeline
- Azure DevOps → Pipelines → New Pipeline
- Selecionar repositório
- Existing Azure Pipelines YAML file
- Path:
/azure-pipelines-docker.yml - Save and Run
🔧 Build Local
API
# Build
docker build -t audissey-api:dev \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg VERSION=dev \
--build-arg VCS_REF=$(git rev-parse --short HEAD) \
-f Dockerfile .
# Run
docker run -p 3000:3000 \
-e MONGO_URI="mongodb://host.docker.internal:27017/audissey" \
-e REDIS_URL="redis://host.docker.internal:6379" \
audissey-api:dev
Worker
# Build
docker build -t audissey-worker:dev \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg VERSION=dev \
-f Dockerfile.worker .
# Run
docker run -p 3001:3001 \
-e MONGO_URI="mongodb://host.docker.internal:27017/audissey" \
-e REDIS_URL="redis://host.docker.internal:6379" \
audissey-worker:dev
ML Service
# Build
cd apps/ml-service
docker build -t audissey-ml:dev \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg VERSION=dev \
.
# Run
docker run -p 8000:8000 \
-e MONGO_URI="mongodb://host.docker.internal:27017/audissey" \
audissey-ml:dev
📊 Metadata & Labels
Todas as imagens incluem OCI labels para rastreabilidade:
LABEL org.opencontainers.image.title="Audissey API"
LABEL org.opencontainers.image.description="Audissey REST API Service"
LABEL org.opencontainers.image.vendor="Audissey"
LABEL org.opencontainers.image.created="2025-12-27T10:30:00Z"
LABEL org.opencontainers.image.version="1.0.0"
LABEL org.opencontainers.image.revision="abc1234"
ARG BUILD_DATE, VERSION e VCS_REF ficam no fim do stage, depois do último RUN: mudam a cada build, e um RUN abaixo deles falha a cache e volta a enviar as layers para o ACR. scripts/node-version-alignment.test.js falha se voltarem para cima. Ver "Storage do ACR" em ENVIRONMENTS.md.
Inspecionar metadata:
docker image inspect audissey.azurecr.io/audissey-api:1.0.0 \
--format='{{json .Config.Labels}}' | jq
🔍 Gerenciar Imagens no ACR
Listar Imagens
# Listar repositórios
az acr repository list --name audissey --output table
# Listar tags de uma imagem
az acr repository show-tags --name audissey \
--repository audissey-api \
--orderby time_desc \
--output table
Pull de Imagem
# Login no ACR
az acr login --name audissey
# Pull
docker pull audissey.azurecr.io/audissey-api:1.0.0
docker pull audissey.azurecr.io/audissey-worker:1.0.0
docker pull audissey.azurecr.io/audissey-ml:0.1.0
Deletar Imagens Antigas
O que apagar, e o que nunca apagar, está em "Storage do ACR" em ENVIRONMENTS.md. Os dados apagados não se recuperam: correr sempre primeiro com --dry-run.
# Só manifests sem tag com mais de 7 dias. Não toca em nenhuma tag.
az acr run --registry audissey --timeout 3600 \
--cmd "acr purge --untagged-only --ago 7d --dry-run" /dev/null
Não usar show-tags | xargs az acr repository delete: cada build tem duas tags, a ordenação inclui buildcache e nada protege as imagens em uso.
🚀 Deploy com Docker Images
Azure App Service
# Configurar App Service para usar imagem do ACR
# Nota: no setup atual recomenda-se pull via Managed Identity + role AcrPull (sem ACR admin user).
az webapp config container set \
--name audissey-api \
--resource-group audissey-rg \
--docker-custom-image-name audissey.azurecr.io/audissey-api:1.0.0 \
--docker-registry-server-url https://audissey.azurecr.io
Azure Container Apps (Worker)
# Update da imagem do Worker (Container App)
# O Worker não precisa de ingress; secrets tipicamente vêm de Key Vault refs (secretref).
az containerapp update \
--resource-group audissey-dev-rg \
--name audissey-worker-dev \
--image audissey.azurecr.io/audissey-worker:1.0.0
Docker Compose (Local)
version: '3.8'
services:
api:
image: audissey.azurecr.io/audissey-api:1.0.0
ports:
- '3000:3000'
environment:
- MONGO_URI=mongodb://mongo:27017/audissey
- REDIS_URL=redis://redis:6379
worker:
image: audissey.azurecr.io/audissey-worker:1.0.0
environment:
- MONGO_URI=mongodb://mongo:27017/audissey
- REDIS_URL=redis://redis:6379
ml:
image: audissey.azurecr.io/audissey-ml:0.1.0
ports:
- '8000:8000'
environment:
- MONGO_URI=mongodb://mongo:27017/audissey
🔐 Segurança
Scan de Vulnerabilidades
# Scan com Microsoft Defender for Cloud (integrado no ACR)
az acr task create \
--name vulnerabilityScan \
--registry audissey \
--context /dev/null \
--cmd "mcr.microsoft.com/azure-cli" \
--schedule "0 0 * * *"
Políticas de Retenção
# Manter apenas últimas 10 imagens
az acr config retention update \
--registry audissey \
--status enabled \
--days 30 \
--type UntaggedManifests
📝 Workflow Completo
1. Desenvolvimento
# Fazer mudanças
git checkout -b feature/new-endpoint
# ... desenvolver ...
git commit -m "feat: adicionar novo endpoint"
2. Versionamento
# Bump version
./scripts/bump-version.sh api patch
# Commit version
git add version.json
git commit -m "chore: bump API version to 1.0.1"
3. Merge para Main
# Criar PR e merge para main
git push origin feature/new-endpoint
# Abrir PR no Azure DevOps
# Aguardar aprovação e merge
4. Pipeline Automático
- Pipeline
azure-pipelines-docker.ymlexecuta automaticamente - Build de todas as imagens
- Push para ACR com tags corretas
- Deploy automático (via CD pipeline separado)
5. Tag Release
# Após merge bem-sucedido
git checkout main
git pull
git tag v1.0.1
git push origin v1.0.1
📚 Recursos
Última atualização: 27 de dezembro de 2025