Implementação completa de pipeline CI/CD automatizado utilizando GitOps para uma aplicação FastAPI
Sobre • Arquitetura • Tecnologias • Demonstração • Como Usar
Este projeto foi desenvolvido como parte do Programa de Bolsas - DevSecOps da Compass UOL e demonstra a implementação completa de um pipeline CI/CD moderno, automatizando todo o ciclo de vida de uma aplicação desde o desenvolvimento até o deploy em produção.
- ✅ Automatizar o processo de build, teste e deploy de aplicações
- ✅ Implementar práticas de GitOps com ArgoCD
- ✅ Utilizar GitHub Actions para integração contínua
- ✅ Gerenciar deployments em Kubernetes de forma declarativa
- ✅ Separar responsabilidades entre código da aplicação e manifests de infraestrutura
- Totalmente Automatizado: Um simples
git pushdispara todo o pipeline - GitOps: O repositório Git é a única fonte de verdade
- Rastreabilidade: Cada deploy é versionado e rastreável
- Rollback Simplificado: Reverter para versões anteriores é trivial
graph TD
subgraph "👨💻 Desenvolvedor"
A[Desenvolvedor] -->|1. git push| B(📦 Repositório da Aplicação<br/>compass-python-api-ci-cd)
end
subgraph "🔄 CI: GitHub Actions"
B -->|2. Trigger Workflow| C(🤖 GitHub Actions)
C -->|3. Build & Test| D(🐳 Docker Build)
D -->|4. Push Image| E(📚 Docker Hub<br/>compass-python-api:SHA)
C -->|5. Update Manifest| F(📦 Repositório de Manifestos<br/>compass-kubernetes-deployments)
end
subgraph "🚀 CD: GitOps com ArgoCD"
F -->|6. Detecta Mudança| G(🚢 ArgoCD)
G -->|7. Sync & Deploy| H(☸️ Cluster Kubernetes<br/>Rancher Desktop)
H -->|8. Pull Image| E
end
style B fill:#22272E,stroke:#58A6FF,stroke-width:2px,color:#fff
style F fill:#22272E,stroke:#58A6FF,stroke-width:2px,color:#fff
style C fill:#2088FF,stroke:#fff,stroke-width:2px,color:#fff
style G fill:#EF7B4D,stroke:#fff,stroke-width:2px,color:#fff
style H fill:#326CE5,stroke:#fff,stroke-width:2px,color:#fff
style E fill:#2496ED,stroke:#fff,stroke-width:2px,color:#fff
| Componente | Função | Responsabilidade |
|---|---|---|
| GitHub Actions | CI Pipeline | Build, test e push da imagem Docker |
| Docker Hub | Registry | Armazenamento de imagens containerizadas |
| ArgoCD | CD Engine | Sincronização GitOps e deploy no K8s |
| Kubernetes | Orchestrator | Execução e gerenciamento dos containers |
| Git Repositories | Source of Truth | Versionamento de código e manifestos |
|
GitHub Actions
|
Docker & Docker Hub
|
Kubernetes
|
|
ArgoCD
|
FastAPI
|
Rancher Desktop
|
Este projeto segue a prática de separação de responsabilidades com dois repositórios distintos:
compass-python-api-ci-cd - Código fonte e CI
compass-python-api-ci-cd/
├── .github/
│ └── workflows/
│ └── main.yml # 🎯 Pipeline CI/CD
├── .gitignore
├── Dockerfile # 🐳 Containerização
├── main.py # 🚀 Aplicação FastAPI
├── requirements.txt # 📦 Dependências Python
└── README.md
Responsabilidades:
- Código da aplicação
- Testes unitários
- Build da imagem Docker
- Atualização automática dos manifestos
compass-kubernetes-deployments - Infraestrutura como Código (IaC)
compass-kubernetes-deployments/
├── deployment.yaml # 🎯 Definição dos Pods
└──service.yaml # 🌐 Exposição da aplicação
Responsabilidades:
- Manifestos Kubernetes
- Configuração de recursos
- Fonte de verdade para o ArgoCD
- Versionamento da infraestrutura
Antes de começar, certifique-se de ter as seguintes ferramentas instaladas:
- Git (v2.30+) - Instalar
- Python (v3.9+) - Instalar
- Docker - Instalar
- kubectl - Instalar
- Rancher Desktop - Instalar
- GitHub Account - Com 2 repositórios públicos
- Docker Hub Account - Com Personal Access Token configurado
# Criar namespace
kubectl create namespace argocd
# Instalar ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Aguardar todos os pods ficarem prontos
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s# Clone o repositório da aplicação
git clone https://github.com/seu-usuario/compass-python-api-ci-cd.git
cd compass-python-api-ci-cd
# Clone o repositório de manifestos
git clone https://github.com/seu-usuario/compass-kubernetes-deployments.gitAcesse: Repositório → Settings → Secrets and variables → Actions
Adicione os seguintes secrets:
| Secret | Descrição | Como Obter |
|---|---|---|
DOCKER_USERNAME |
Seu usuário do Docker Hub | |
DOCKER_PASSWORD |
Token de acesso do Docker Hub | Account Settings → Security → New Access Token |
SSH_PRIVATE_KEY |
Chave SSH para atualizar manifestos | ssh-keygen -t ed25519 -C "github-actions" |
O arquivo .github/workflows/main.yml já está pronto! Ele faz:
- ✅ Login no Docker Hub
- ✅ Build da imagem com tag SHA do commit
- ✅ Push da imagem para o Docker Hub
- ✅ Checkout do repositório de manifestos
- ✅ Atualização do
deployment.yamlcom a nova tag - ✅ Commit e push automático das mudanças
# Acesse a UI do ArgoCD
kubectl port-forward svc/argocd-server -n argocd 8081:443
# Obtenha a senha inicial (usuário: admin)
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echoAcesse: https://localhost:8081
Crie uma nova aplicação:
- Application Name:
hello-app - Project:
default - Sync Policy:
Automatic - Repository URL:
https://github.com/seu-usuario/compass-kubernetes-deployments - Path:
. - Cluster:
https://kubernetes.default.svc - Namespace:
default
# Edite a aplicação
echo 'return {"message": "Hello GitOps!"}' > main.py
# Commit e push
git add .
git commit -m "Update message to GitOps"
git push origin main
# Acompanhe o workflow
# GitHub → Actions → Veja o workflow executando
# Verifique o ArgoCD sincronizando
# ArgoCD UI → hello-app → Veja o status
# Acesse a aplicação
kubectl port-forward svc/hello-app-service 8080:80
curl http://localhost:8080O git push no main.py acionou o workflow, que executou com sucesso todas as etapas.
Etapas executadas:
- ✅ Checkout do código
- ✅ Login no Docker Hub
- ✅ Build da imagem Docker
- ✅ Push para Docker Hub com tag SHA
- ✅ Atualização do manifest no repositório de deployments
A imagem compass-python-api foi enviada ao Docker Hub com a tag correspondente ao SHA do commit.
Detalhes da imagem:
- Repository:
thiagodavi2006/compass-python-api - Tag:
d6c7d3b(SHA do commit) - Size: ~50MB (otimizada)
- Última atualização: Timestamp do push
O GitHub Actions realizou um commit automático no repositório compass-kubernetes-deployments, atualizando a tag da imagem no deployment.yaml.
Commit realizado por: github-actions[bot]
Mensagem: Update image tag to d6c7d3b
O ArgoCD detectou automaticamente a mudança no repositório de manifestos e sincronizou o cluster.
Status da aplicação:
- 🟢 Health: Healthy
- 🔄 Sync: Synced
- 📊 Resources: 1 Deployment, 1 Service, 1 Pod
O comando kubectl get pods mostra o novo pod da aplicação em estado Running.
NAME READY STATUS RESTARTS AGE
hello-app-xxxxxxxxx-xxxxx 1/1 Running 0 68mApós executar kubectl port-forward svc/hello-app-service 8080:80, a aplicação responde corretamente no navegador.
**Response:**
```json
{
"message": "Hello GitOps! Acionando o pipeline corrigido!"
}
```
# Verificar status do cluster
kubectl cluster-info
kubectl get nodes
# Gerenciar recursos
kubectl get all -n default
kubectl get pods -w # watch mode
kubectl describe pod <pod-name>
kubectl logs <pod-name> -f # follow logs
# Acessar a aplicação
kubectl port-forward svc/hello-app-service 8080:80
# Debug
kubectl exec -it <pod-name> -- /bin/sh
kubectl get events --sort-by=.metadata.creationTimestamp# Acessar UI
kubectl port-forward svc/argocd-server -n argocd 8081:443
# CLI do ArgoCD
argocd app list
argocd app get hello-app
argocd app sync hello-app
argocd app history hello-app
# Obter senha
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d# Build local
docker build -t compass-python-api:local .
# Run local
docker run -p 8080:80 compass-python-api:local
# Verificar imagens
docker images | grep compass-python-api
# Limpar imagens antigas
docker image prune -aErro: Error: unauthorized: incorrect username or password
Causa: Token do Docker Hub expirado ou incorreto
Solução:
- Acesse Docker Hub → Account Settings → Security
- Gere um novo Personal Access Token (permissões: Read, Write, Delete)
- Atualize o secret
DOCKER_PASSWORDno GitHub - Execute novamente o workflow
Erro: ! [rejected] main -> main (non-fast-forward)
Causa: Repositório local desatualizado em relação ao remoto
Solução:
# Atualizar repositório local
git pull origin main --rebase
# Tentar push novamente
git push origin mainErro: Status "OutOfSync" permanece
Causa: Configuração incorreta do repositório ou permissões
Solução:
- Verifique a URL do repositório no ArgoCD
- Confirme que o repositório é público ou adicione credenciais
- Force uma sincronização manual:
argocd app sync hello-app --forceErro: ImagePullBackOff ou CrashLoopBackOff
Solução:
# Verificar logs detalhados
kubectl describe pod <pod-name>
kubectl logs <pod-name> --previous
# Verificar se a imagem existe no Docker Hub
# Verificar se o deployment.yaml tem a tag correta
kubectl get deployment hello-app -o yaml | grep image:- GitHub Actions Documentation
- ArgoCD Documentation
- Kubernetes Documentation
- FastAPI Documentation
- Docker Documentation
Contribuições são bem-vindas! Sinta-se à vontade para:
- 🍴 Fazer um fork do projeto
- 🔀 Criar uma branch para sua feature (
git checkout -b feature/AmazingFeature) - ✅ Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - 📤 Push para a branch (
git push origin feature/AmazingFeature) - 🎉 Abrir um Pull Request
Compass UOL pelo programa de bolsas e oportunidade de aprendizado
Comunidade Cloud Native pelas ferramentas open-source incríveis
Feito com ❤️ e ☕ por Thiago Cardoso Davi
╔═══════════════════════════════════════════════════╗
║ ║
║ "Automatizando o futuro, um commit por vez" ║
║ ║
╚═══════════════════════════════════════════════════╝
