Este guia explica como construir e publicar as imagens Docker do Argus Agent localmente para o Google Artifact Registry.
- Docker instalado e rodando
- Google Cloud SDK (gcloud) instalado
- Autenticação GCP configurada
- Permissões para push no Artifact Registry
# Login no GCP
gcloud auth login
# Configurar projeto
gcloud config set project tcloud-devops# Configurar autenticação (uma vez)
make docker-login
# Ou manualmente:
gcloud auth configure-docker southamerica-east1-docker.pkg.dev# 1. Build das imagens de produção
make docker-build
# 2. Push para o registry
make docker-push
# Ou fazer tudo de uma vez:
make docker-build-push# Build com tag customizada
make docker-build VERSION=v1.2.3
# Push da versão específica
make docker-push VERSION=v1.2.3
# Ou tudo junto:
make docker-build-push VERSION=v1.2.3Para ambientes de desenvolvimento/staging, use tags com timestamp no formato YYYYMMDD-HHMMSS:
# Build e push com timestamp automático
make docker-build-push-timestamp
# Exemplo de tag gerada:
# southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-app:20250921-201146
# southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-mcp-server:20250921-201146Vantagens do timestamp:
- ✅ Rastreabilidade: sabe exatamente quando a imagem foi criada
- ✅ Uniqueness: cada build gera uma tag única
- ✅ Rollback fácil: pode voltar para uma versão específica por data/hora
- ✅ Histórico: mantém histórico de todas as versões no registry
# Criar tag a partir do latest
make docker-tag VERSION=v1.2.3
# Push da nova tag
make docker-push VERSION=v1.2.3O build cria duas imagens especializadas usando Dockerfiles separados para máxima otimização:
southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-app:latest
southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-app:v1.2.3
Características:
- Porta: 8000
- Comando:
uvicorn main:app --host 0.0.0.0 --port 8000 - Contém:
main.py,app/,prompts/,config/ - NÃO contém:
tools/(MCP server) - Distroless Python 3.13
- Non-root user (uid 65532)
- Mais enxuta: apenas código da aplicação
southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-mcp-server:latest
southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-mcp-server:v1.2.3
Características:
- Porta: 8002
- Comando:
uvicorn tools.server:app --host 0.0.0.0 --port 8002 - Contém:
tools/,config/ - NÃO contém:
main.py,app/,prompts/(aplicação principal) - Distroless Python 3.13
- Non-root user (uid 65532)
- Mais enxuta: apenas código do MCP server
✅ Vantagens:
- Menor tamanho: Cada imagem contém apenas o código necessário
- Segurança: Reduz superfície de ataque (menos código = menos vulnerabilidades)
- Performance: Builds mais rápidos (menos arquivos para copiar)
- Manutenção: Mais fácil entender o que cada imagem contém
- Deploy: Pull mais rápido em produção
Temos 2 Dockerfiles especializados, cada um otimizado para seu serviço:
# Stage 1: builder - Instala dependências
FROM python:3.13-slim as builder
WORKDIR /app
RUN apt-get update && apt-get install -y gcc g++ curl
RUN pip install --no-cache-dir uv
COPY requirements.txt .
RUN uv pip install --system --no-cache-dir -r requirements.txt
# Copy APENAS código da app (exclude tools/)
COPY main.py .
COPY app/ ./app/
COPY prompts/ ./prompts/
COPY config/ ./config/
# Stage 2: production - Distroless
FROM gcr.io/distroless/python3-debian12
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
WORKDIR /app
COPY --from=builder /app/main.py ./main.py
COPY --from=builder /app/app ./app
COPY --from=builder /app/prompts ./prompts
COPY --from=builder /app/config ./config
USER nonroot:nonroot
EXPOSE 8000
CMD ["/usr/local/bin/uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]# Stage 1: builder - Instala dependências
FROM python:3.13-slim as builder
WORKDIR /app
RUN apt-get update && apt-get install -y gcc g++ curl
RUN pip install --no-cache-dir uv
COPY requirements.txt .
RUN uv pip install --system --no-cache-dir -r requirements.txt
# Copy APENAS código do MCP server (exclude app/, prompts/)
COPY tools/ ./tools/
COPY config/ ./config/
# Stage 2: production - Distroless
FROM gcr.io/distroless/python3-debian12
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
WORKDIR /app
COPY --from=builder /app/tools ./tools
COPY --from=builder /app/config ./config
USER nonroot:nonroot
EXPOSE 8002
CMD ["/usr/local/bin/uvicorn", "tools.server:app", "--host", "0.0.0.0", "--port", "8002"]Principais diferenças:
Dockerfile.app: Copiamain.py,app/,prompts/(excluitools/)Dockerfile.mcp: Copiatools/(excluimain.py,app/,prompts/)- Ambos compartilham:
config/,requirements.txt, mesma base distroless
O docker-compose.yml já está configurado para usar as imagens do registry:
services:
app:
image: southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-app:latest
mcp-server:
image: southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-mcp-server:latestUso:
# Pull e rodar
docker-compose pull
docker-compose upAs imagens são configuradas nos values files:
# k8s/prod/values.yaml
image:
registry: southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops
tag: "1.0.0"
app:
image:
tag: "1.0.0"
mcpServer:
image:
tag: "1.0.0"Deploy:
# Development
make helm-install-dev
# Production com versão específica
make helm-install-prod VERSION=v1.2.3Para desenvolvimento, use as imagens de desenvolvimento (com debugging tools):
# Build imagens de dev
make docker-build-dev
# Rodar com docker-compose.dev.yml
make dev-debugdocker images | grep argusdocker inspect southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-app:latest# App
docker run -p 8000:8000 \
--env-file .env \
southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-app:latest
# MCP Server
docker run -p 8002:8002 \
--env-file .env \
southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops/argus-mcp-server:latest# Remover imagens não usadas
docker image prune -a
# Remover tudo (cuidado!)
make clean-docker# Re-autenticar
gcloud auth login
make docker-login# Verificar se a imagem existe no registry
gcloud artifacts docker images list \
southamerica-east1-docker.pkg.dev/tcloud-devops/tcloud-devops# Limpar Docker
docker system prune -a --volumes# Usar BuildKit para builds mais rápidos
export DOCKER_BUILDKIT=1
make docker-build- ✅ Sempre use tags específicas em produção (não use
latest) - ✅ Teste a imagem localmente antes do push
- ✅ Use versioning semântico (v1.2.3)
- ✅ Faça push apenas de código revisado
- ✅ Documente mudanças no CHANGELOG
⚠️ Não exponha credenciais nas imagens
Recomendações para diferentes ambientes:
# Usar timestamp para desenvolvimento
make docker-build-push-timestamp
# Resultado: argus-app:20250921-201146# Usar timestamp ou tag específica
make docker-build-push-timestamp
# Ou com tag manual:
make docker-build-push VERSION=staging-$(date +%Y%m%d)# Usar semantic versioning (vX.Y.Z)
git tag v1.2.3
make docker-build-push VERSION=v1.2.3
# Também criar tag latest para produção
make docker-tag VERSION=v1.2.3
docker tag $(DOCKER_REGISTRY)/argus-app:v1.2.3 $(DOCKER_REGISTRY)/argus-app:latest
docker tag $(DOCKER_REGISTRY)/argus-mcp-server:v1.2.3 $(DOCKER_REGISTRY)/argus-mcp-server:latest
make docker-push VERSION=latest| Ambiente | Formato Tag | Exemplo | Comando |
|---|---|---|---|
| Dev | YYYYMMDD-HHMMSS |
20250921-201146 |
make docker-build-push-timestamp |
| Staging | YYYYMMDD-HHMMSS |
20250921-201146 |
make docker-build-push-timestamp |
| Prod | vX.Y.Z |
v1.2.3 |
make docker-build-push VERSION=v1.2.3 |
| Prod Latest | latest |
latest |
Manual (após validação) |
No futuro, usaremos Google Cloud Build para automatizar o processo:
# cloudbuild.yaml (exemplo futuro)
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '--target', 'app', '-t', 'gcr.io/$PROJECT_ID/argus-app:$TAG_NAME', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '--target', 'mcp-server', '-t', 'gcr.io/$PROJECT_ID/argus-mcp-server:$TAG_NAME', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/argus-app:$TAG_NAME']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/argus-mcp-server:$TAG_NAME']Por enquanto, todo build e push é feito localmente usando o Makefile.