CI/CD e Deploy em Multi-Repo: API .NET, Dashboard e Widget
Como organizei a entrega em três repositórios com VPS e Cloudflare
Meu projeto tem três frentes: uma API de backend em .NET 8, um dashboard administrativo em React e um widget embeddável distribuído para lojas parceiras. Avaliei se valia a pena juntar tudo em um monorepo ou manter separado, e como fazer o deploy na VPS de forma simples.
Monorepo vs Repositórios Separados
Cada parte do projeto tem um ritmo e requisitos de deploy diferentes:
- Backend: Web API em .NET 8, banco PostgreSQL, EF Core, integrações com Stripe e Nuvemshop. Precisa de build de release e migrations.
- Frontend Dashboard: SPA focado no lojista, com deploys rápidos na Cloudflare Pages.
- Widget: Um script leve empacotado que precisa de cache agressivo em CDN para não pesar nas lojas dos clientes.
Optei por manter repositórios isolados. Isso deixa o workspace do backend enxuto e evita que alterações no frontend disparem builds desnecessários na API.
O Prefixo /api e o Roteamento
Ao apontar o Cloudflare para a VPS com NGINX, avaliei duas opções:
- Alterar todos os controllers do .NET para remover o prefixo
/apie reescrever no proxy. - Manter
[Route("api/[controller]")]no .NET e deixar o NGINX apenas repassar as requisições.
Fiquei com a segunda opção. Mudar rotas no código apenas por causa do proxy cria acoplamento desnecessário e quebra testes de integração.
Configuração do NGINX na VPS:
server {
listen 80;
server_name api.meudominio.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Pipeline de CI/CD com GitHub Actions
Para a entrega contínua da API, montei um workflow simples no GitHub Actions: roda os testes, gera o publish e reinicia o serviço no systemd via SSH.
name: Deploy Backend API
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Run Tests
run: dotnet test --configuration Release --verbosity normal
- name: Publish API
run: dotnet publish ChatAgent.Api -c Release -o ./publish
- name: Deploy to VPS via SSH
uses: appleboy/scp-action@master
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
source: "./publish/*"
target: "/var/www/chatagent-api"
- name: Restart Service
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: sudo systemctl restart chatagent.service
Conclusão
- Rodar a API direto no
systemdcom NGINX em uma VPS comum oferece ótimo desempenho e depuração simples comjournalctl. - Executar os testes antes do publish no GitHub Actions evita que builds quebrados cheguem ao servidor de produção.