Repositórios de Aplicação como Golden Paths: Dockerfile, CI e .k8s em Cada Repo
Nossa plataforma gerencia onde e como os serviços são implantados através de repositórios GitOps. Mas e a aplicação em si — o código, o build, o contêiner? Até agora, cada equipe configurava seu próprio Dockerfile, escrevia seu próprio pipeline de CI e elaborava sua própria estratégia de tagueamento de imagens. O resultado era previsível: 10 times, 10 workflows de CI diferentes, 10 abordagens diferentes de build de contêiner e zero consistência.
A convenção de Repositórios de Aplicação muda isso. Quando um novo serviço é scaffoldado via Backstage, ele entrega um repositório completo e opinativo com código fonte, Dockerfile, pipeline de CI e uma pasta .k8s — dando à equipe da aplicação autonomia sobre a configuração de sua carga de trabalho enquanto mantém a plataforma no controle do modelo de implantação.
A arquitetura: dois repos, uma implantação
Nosso modelo GitOps usa uma separação clara entre configuração de implantação e configuração da aplicação:
{domain}-gitops/k8s/{env}/{service}/ ← Manifestos base gerenciados pela plataforma
{app}-repo/.k8s/values.yaml ← Sobrescrições gerenciadas pelo desenvolvedor
O repositório GitOps do domínio contém a configuração fundacional do Kubernetes — Deployments, Services, NetworkPolicies, HPA, PDB — gerada pelo template create-service e mantida pelas convenções de plataforma do time do domínio.
O repositório da aplicação contém uma pasta .k8s onde o time de desenvolvimento gerencia valores que mudam frequentemente com os releases da aplicação.
O padrão de Múltiplas Fontes (Multiple Sources) do ArgoCD mescla ambas as fontes no momento da sincronização. Os manifestos base do repo GitOps fornecem estrutura e segurança. As sobrescrições da aplicação fornecem flexibilidade e velocidade.
O que os desenvolvedores podem sobrescrever
O .k8s/values.yaml no repositório da aplicação dá aos desenvolvedores controle sobre:
- Tag da imagem: Atualizada automaticamente pelo CI em cada build bem-sucedido
- Réplicas: Sobrescrever limites min/max do HPA para necessidades específicas da carga de trabalho
- CPU e memória: Ajustar requests e limits conforme o perfil da aplicação evolui
- Variáveis de ambiente: Configuração específica da aplicação que muda com os releases
Esses são os valores que mudam com mais frequência e estão mais diretamente ligados ao código da aplicação. Mantendo-os no repo da app, desenvolvedores não precisam de um PR no repo GitOps toda vez que fazem push de um release.
O que os desenvolvedores não tocam
Os manifestos base em {domain}-gitops/k8s/ permanecem sob controle da convenção da plataforma:
- Definição do Namespace com todos os 9 labels obrigatórios
- Contexto de segurança:
runAsNonRoot,readOnlyRootFilesystem,capabilities: drop: [ALL] - NetworkPolicy: isolamento por fronteira de projeto
- PodDisruptionBudget: rede de segurança apenas para prod
- ResourceQuota: limites dimensionados por ambiente
Essa separação garante que as garantias de segurança e conformidade nunca sejam acidentalmente sobrescritas por um desenvolvedor que "só precisa mudar o limite de memória."
O pipeline de CI: do commit ao deploy
Todo repositório de aplicação scaffoldado pelo create-service inclui um workflow pré-configurado do GitHub Actions. O pipeline não é algo que o time precisa escrever — ele chega pronto:
Desenvolvedor faz push do código
│
▼
┌─── Pipeline de CI ─────────────────────────────────┐
│ │
│ 1. Test & Lint Executa testes, verificações │
│ 2. Build Constrói contêiner do Dockerfile│
│ 3. Publish Push da imagem para o registry │
│ 4. Atualização de Atualiza .k8s/values.yaml com │
│ Tag nova tag, commit de volta │
│ │
└─────────────────────────────────────────────────────┘
│
▼
ArgoCD detecta mudança no app repo (fonte secundária)
│
▼
Implantação sincroniza com nova tag da imagem
O passo chave é a Atualização de Tag. Após publicar a imagem do contêiner, o pipeline atualiza automaticamente image.tag em .k8s/values.yaml e faz commit da mudança de volta no repositório da aplicação. Esse commit é o que o ArgoCD observa.
Como o ArgoCD está configurado com Multiple Sources — uma apontando para o repo GitOps para manifestos base, outra apontando para o repo da app para sobrescrições — a nova tag aciona uma sincronização automática para o ambiente alvo.
Sem atualizações manuais de tag de imagem. Sem passo separado de "deploy". Faça push do código, obtenha a implantação.
O Dockerfile: seguro por padrão
O Dockerfile scaffoldado segue os padrões de segurança da plataforma:
- Build multi-estágio: Estágios separados de build e runtime para minimizar o tamanho da imagem
- Usuário não-root:
USER 1000— combina com o contexto de segurança do pod (runAsNonRoot: true) - Compatível com filesystem somente leitura: Escritas da aplicação vão para
/tmp(montado comoemptyDir) - Otimização específica por linguagem: Node.js, .NET e Python recebem cada um um Dockerfile adaptado com imagens base e cache de dependências apropriados
O desenvolvedor não precisa saber sobre contextos de segurança de pod ou filesystems somente leitura. O Dockerfile e os manifestos Kubernetes são projetados para funcionar juntos desde o primeiro dia.
O quadro completo
Quando o create-service é executado, o desenvolvedor recebe:
| O quê | Onde | Quem mantém |
|---|---|---|
| Código fonte boilerplate | {app}-repo/src/ | Time da aplicação |
| Dockerfile | {app}-repo/Dockerfile | Time da aplicação |
| Pipeline de CI | {app}-repo/.github/workflows/ci.yaml | Time de plataforma (gerado), time da aplicação (estendido) |
| Sobrescrições da carga de trabalho | {app}-repo/.k8s/values.yaml | Time da aplicação |
| TechDocs | {app}-repo/docs/ | Time da aplicação |
| Manifestos K8s base | {domain}-gitops/k8s/{env}/{service}/ | Time do domínio |
| Roteamento ArgoCD | platform-gitops/argocd/applicationsets/ | Time de plataforma |
Três repositórios, três fronteiras de propriedade, uma implantação que funciona sem coordenação manual.
Por que não tudo no repo da app?
Uma pergunta comum: "Por que não colocar todos os manifestos Kubernetes no repositório da aplicação?"
Porque quebra o modelo de propriedade:
- Contexto de segurança e políticas de rede são preocupações da plataforma, não da aplicação. Desenvolvedores não deveriam precisar (nem poder) modificá-los.
- Múltiplos serviços compartilham o mesmo ApplicationSet e estrutura de domínio. Centralizar isso no repo GitOps evita duplicação e garante consistência.
- Validação de convenção roda no repo GitOps. Verificações de CI para nomenclatura, labels e padrões de segurança acontecem onde essas definições vivem.
A pasta .k8s dá aos desenvolvedores a autonomia que precisam — tags de imagem, escalonamento, recursos — sem dar acesso às coisas que não deveriam mudar.
A convenção de Repositórios de Aplicação está documentada na Convenção da Plataforma — Repositórios de Aplicação. O padrão de Múltiplas Fontes do ArgoCD está na Convenção ArgoCD.