Como subir um novo app
Como subir um novo app
Guia passo a passo para adicionar um app ao cluster. O fluxo completo e: criar manifests → criar Application ArgoCD → criar rota Traefik → push.
Leia docs/infraestrutura.md primeiro para entender a arquitetura.
Pre-requisitos
- Acesso de escrita ao repositorio Git
- Conhecer: nome do app, imagem Docker, porta(s), dominio desejado
- Para Helm charts: URL do repositorio do chart e versao
Passo 1 — Manifests do app
Criar apps/<nome>/ com os manifests ou values Helm.
Se Helm (mais comum):
apps/<nome>/values.yamlSe manifests puros (sem Helm):
apps/<nome>/deployment.yamlapps/<nome>/service.yamlO Service deve expor uma porta acessivel. Anotar a porta — vai precisar no passo 3.
Se Kustomize (manifests gerados por ferramenta externa, ex: Tutor/Open edX):
apps/<nome>/ kustomization.yml # com configMapGenerator, namespace, labels k8s/ # deployments, services, volumes, jobs apps/ # configs que viram ConfigMaps automaticamenteQuando o diretorio contem kustomization.yml, o ArgoCD detecta e usa Kustomize automaticamente.
ConfigMaps sao gerados via configMapGenerator — nao precisa criar manualmente.
Diferencas do padrao:
- Upgrades: re-gerar manifests com a ferramenta, copiar para o repo, revisar diff
- Namespace: definido no
kustomization.yml(nao no deployment) - Labels: aplicados globalmente via
labelsecommonAnnotations
Exemplo completo: apps/tutor-openedx/ — ver docs/tutor-openedx.md.
Dica: copiar de um app existente e ajustar. Bons exemplos:
- Helm com chart externo:
apps/airflow/,apps/authentik/- Manifests puros:
apps/dashboard/,apps/invenio/- Kustomize (gerado):
apps/tutor-openedx/
Passo 2 — Application ArgoCD
Criar apps/argocd/<nome>.yaml.
Para Helm chart externo (chart vem de outro repo):
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: <nome> namespace: argocdspec: project: default sources: - repoURL: <URL_DO_CHART_REPO> chart: <nome-do-chart> targetRevision: "<versao>" helm: valueFiles: - $values/apps/<nome>/values.yaml - repoURL: https://github.com/colabhd/devops.git targetRevision: HEAD ref: values destination: server: https://kubernetes.default.svc namespace: <nome> syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=truePara manifests puros (tudo no nosso repo):
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: <nome> namespace: argocdspec: project: default source: repoURL: https://github.com/colabhd/devops.git targetRevision: main path: apps/<nome> destination: server: https://kubernetes.default.svc namespace: <nome> syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=trueIMPORTANTE: prune: true e selfHeal: true sao obrigatorios. Isso garante que:
- Recurso removido do Git → removido do cluster
- Edicao manual no cluster → revertida automaticamente
Passo 3 — Rota no Traefik
Criar config/traefik/routes/<nome>.yaml.
Para apps HTTP/HTTPS (maioria dos casos):
apiVersion: v1kind: Servicemetadata: name: <nome>-backend namespace: traefikspec: ports: - port: <PORTA> targetPort: <NODEPORT>---apiVersion: v1kind: Endpointsmetadata: name: <nome>-backend namespace: traefiksubsets: - addresses: - ip: 192.168.0.51 # vm-cpps-02 ports: - port: <NODEPORT>---apiVersion: traefik.io/v1alpha1kind: IngressRoutemetadata: name: <nome> namespace: traefikspec: entryPoints: [websecure] routes: - match: Host(`<nome>.cppsunesp.org`) kind: Rule services: - name: <nome>-backend port: <PORTA> tls: certResolver: letsencryptSubstituir:
<nome>: nome do app<PORTA>: porta do service (ex: 8080)<NODEPORT>: NodePort exposto pelo K3s (ex: 32000)
Dica: copiar
config/traefik/routes/airflow.yamle ajustar host + porta.
DNS Cloudflare: criar CNAME apontando para traefik-afq-franca.cppsunesp.org:
source .envcurl -X POST -H "Authorization: Bearer $CF_DNS_API_TOKEN" \ -H "Content-Type: application/json" \ "https://api.cloudflare.com/client/v4/zones/70cd39241c7861ecdf4644477069bf3c/dns_records" \ -d '{"type":"CNAME","name":"<nome>.cppsunesp.org","content":"traefik-afq-franca.cppsunesp.org","ttl":1,"proxied":false}'O Zone ID 70cd39241c7861ecdf4644477069bf3c e do dominio colabh.org. Para cppsunesp.org, usar o Zone ID correspondente (verificar com curl -H "Authorization: Bearer $CF_DNS_API_TOKEN" "https://api.cloudflare.com/client/v4/zones?name=cppsunesp.org").
Futuro: considerar ExternalDNS para criar registros DNS automaticamente a partir das IngressRoutes. Hoje nao compensa (poucos dominios).
Para apps com HTTPS no backend (ex: ArgoCD, Rancher):
Adicionar ServersTransport com insecureSkipVerify: true e referenciar no service.
Ver config/traefik/routes/argocd.yaml como exemplo.
Para apps TCP (ex: banco de dados externo):
Usar IngressRouteTCP em vez de IngressRoute. Ver config/traefik/routes/mongodb.yaml como exemplo.
Neste caso, tambem precisa de regra NAT no VyOS (passo 4).
Passo 4 — VyOS (so se necessario)
Necessario APENAS quando:
- O app usa protocolo nao-HTTP (TCP/UDP direto, ex: MongoDB, PostgreSQL)
- O app precisa de porta externa especifica (ex: MQTT 1883)
Para apps web normais (HTTP/HTTPS): NAO precisa mexer no VyOS. As portas 80 e 443 ja redirecionam para o Traefik.
Se necessario, adicionar NAT destination rule no playbook VyOS:
config/vyos/playbook.yaml → nova regra DNATVer docs/rede.md para as regras NAT existentes.
Passo 5 — Segredos (se houver)
As credenciais ficam diretamente nos values/manifests do app. Isso e necessario porque
o ArgoCD com selfHeal: true aplica exatamente o que esta no Git — se estivesse
CHANGEME, o app quebraria.
-
Colocar a credencial real no values/manifests:
password: "minha-senha-forte" -
Adicionar o arquivo ao allowlist do gitleaks (
.gitleaks.toml, secaopaths):paths = [# ...'''apps/<nome>/values.yaml''',] -
Manter o
.env.exampleatualizado com placeholder para documentacao:Terminal window # <NOME> — apps/<nome>/values.yaml<NOME>_DB_PASSWORD=CHANGEME
Situacao atual: credenciais em plaintext no Git com gitleaks allowlist temporario. Fase 1 do roadmap: migrar para SOPS/age — encripta os values no repo, ArgoCD decripta no deploy. Quando implementado, as credenciais ficam encriptadas e o allowlist do gitleaks e removido.
Passo 6 — Commit e push
git add apps/<nome>/ apps/argocd/<nome>.yaml config/traefik/routes/<nome>.yamlgit commit -m "feat: adicionar <nome>"git pushArgoCD sincroniza automaticamente (~3 min):
- App no K3s de vm-cpps-02
- Rota no Traefik da debian-proxy
Passo 7 — Verificar
- ArgoCD UI (https://argocd.colabh.org): app aparece como Synced + Healthy
- Browser:
https://<nome>.cppsunesp.orgresponde - Se nao funciona: ArgoCD UI mostra o erro (sync failed, pod crashloop, etc.)
Troubleshooting rapido:
- Pod nao sobe → ver logs no Rancher ou
kubectl logs -n <nome> - Rota nao funciona → verificar NodePort correto, IngressRoute com Host certo
- TLS nao funciona → Traefik gera certificado automaticamente (pode levar ~1 min)
Checklist rapido
[ ] apps/<nome>/ — manifests, values ou kustomization.yml[ ] apps/argocd/<nome>.yaml — selfHeal: true, prune: true[ ] config/traefik/routes/<nome>.yaml — IngressRoute + Service + Endpoints[ ] config/vyos/ (so se protocolo nao-HTTP) — NAT rule[ ] .env / .env.example (se tem segredos) — CHANGEME nos manifests[ ] Testado no browserRemover um app
- Deletar
apps/argocd/<nome>.yaml— ArgoCD remove o app do cluster - Deletar
apps/<nome>/— manifests - Deletar
config/traefik/routes/<nome>.yaml— ArgoCD remove a rota - Remover variaveis do
.enve.env.example git push— pronto, ArgoCD limpa tudo (prune: true)
Atualizar um app
- Mudar versao: editar
targetRevisionnoapps/argocd/<nome>.yamlou tag no values - Mudar config: editar
apps/<nome>/values.yaml - Mudar dominio: editar
Host(...)noconfig/traefik/routes/<nome>.yaml
Em todos os casos: editar, commit, push. ArgoCD aplica automaticamente.