Pular para conteúdo

Deploy da API (.NET 10)

A API é publicada como arquivos (dotnet publish), copiada para /opt/braggo/api e executada como um serviço do systemd, que a reinicia sozinha se ela cair e a sobe junto com a VM.

Pré-requisito: Servidor base e Banco de dados concluídos.

1. Instalar o runtime na VM

A VM não precisa do SDK, só do runtime do ASP.NET Core (ele já inclui o runtime do .NET):

sudo apt install -y aspnetcore-runtime-10.0
dotnet --list-runtimes

O segundo comando deve listar Microsoft.AspNetCore.App 10.0.x.

Se o apt disser que o pacote não existe (acontece em versões do Ubuntu que ainda não o trazem no repositório), use o script oficial da Microsoft:

curl -sSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
chmod +x dotnet-install.sh
sudo ./dotnet-install.sh --channel 10.0 --runtime aspnetcore --install-dir /usr/share/dotnet
sudo ln -sf /usr/share/dotnet/dotnet /usr/bin/dotnet
rm dotnet-install.sh

O script baixa o runtime para /usr/share/dotnet e o link em /usr/bin/dotnet deixa o comando disponível para todos, inclusive para o serviço. Neste caso as atualizações do runtime deixam de vir pelo apt e você precisa rodar o script de novo de vez em quando.

Descubra onde o dotnet ficou, porque esse caminho vai no serviço:

which dotnet

2. Variáveis de ambiente (segredos)

Nesta instalação

O arquivo real é /etc/braggo-api.env (não /etc/braggo/api.env), com chmod 600, carregado pelo serviço por EnvironmentFile. Variáveis em uso e como trocá-las: Configuração e segredos.

Senhas e chaves não vão no appsettings.json nem no repositório. Ficam em um arquivo que só o root e o grupo braggo leem:

sudo nano /etc/braggo/api.env
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=http://127.0.0.1:5000
ConnectionStrings__DefaultConnection=Host=localhost;Port=5432;Database=braggo_db;Username=braggo_user;Password=SENHA_GERADA
sudo chown root:braggo /etc/braggo/api.env
sudo chmod 640 /etc/braggo/api.env

Explicando:

  • ASPNETCORE_ENVIRONMENT=Production faz a API usar o modo de produção (sem páginas de erro detalhadas, por exemplo).
  • ASPNETCORE_URLS define em qual endereço e porta a API escuta. O 127.0.0.1 garante que só o Nginx, na mesma VM, consegue chamá-la.
  • ConnectionStrings__DefaultConnection sobrescreve ConnectionStrings:DefaultConnection do appsettings. O ASP.NET Core troca : por __ (dois underscores) em variáveis de ambiente. Use o mesmo nome que o seu código lê em GetConnectionString("...").
  • Qualquer outra configuração secreta (chave do JWT, por exemplo) entra aqui do mesmo jeito: Jwt__Key=....

3. Criar o serviço systemd

sudo nano /etc/systemd/system/braggo-api.service
[Unit]
Description=Braggo API (.NET)
After=network.target postgresql.service

[Service]
WorkingDirectory=/opt/braggo/api
ExecStart=/usr/bin/dotnet /opt/braggo/api/Braggo.Api.dll
EnvironmentFile=/etc/braggo/api.env
User=braggo
Group=braggo
Restart=always
RestartSec=5
KillSignal=SIGINT
SyslogIdentifier=braggo-api
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target

O que cada linha importante faz:

Linha Função
After=...postgresql.service só inicia a API depois que a rede e o banco subiram
ExecStart o comando que roda a API. Troque Braggo.Api.dll pelo nome real e /usr/bin/dotnet pelo resultado do which dotnet
EnvironmentFile carrega as variáveis do passo anterior
User / Group roda como o usuário sem poderes braggo
Restart=always reinicia a API automaticamente se ela travar ou cair
RestartSec=5 espera 5 segundos entre as tentativas
KillSignal=SIGINT encerramento gracioso, como o Ctrl+C
WantedBy=multi-user.target faz o serviço iniciar junto com a VM

Registre o serviço:

sudo systemctl daemon-reload
sudo systemctl enable braggo-api

daemon-reload faz o systemd reler os arquivos de serviço. enable marca para iniciar no boot (ainda não inicia agora, porque ainda não há arquivos em /opt/braggo/api).

4. Publicar e enviar (no seu PC)

Na pasta do repositório da API:

dotnet publish .\src\Braggo.Api -c Release -o .\publish
  • -c Release compila otimizado, sem símbolos de depuração.
  • -o .\publish gera os arquivos finais na pasta publish.
  • Troque .\src\Braggo.Api pelo caminho do .csproj do projeto de entrada da API.

O nome do arquivo .dll principal aparece dentro de publish: é ele que vai no ExecStart.

Empacote e envie:

tar -czf publish.tar.gz -C publish .
scp publish.tar.gz servidor:/tmp/braggo-api.tar.gz

Na VM, extraia para a pasta da API:

tar -xzf /tmp/braggo-api.tar.gz -C /opt/braggo/api
chmod -R u=rwX,go=rX /opt/braggo/api
rm /tmp/braggo-api.tar.gz

chmod u=rwX,go=rX garante que o usuário braggo consiga ler tudo. Para os deploys seguintes, use o script de atualização, que também guarda a versão anterior para rollback.

5. Iniciar e conferir

sudo systemctl start braggo-api
sudo systemctl status braggo-api

O status deve mostrar active (running). Acompanhe os logs ao vivo:

sudo journalctl -u braggo-api -f

(-u filtra pelo serviço, -f segue novas linhas, como um tail -f. Saia com Ctrl+C.)

Teste a API localmente, de dentro da VM:

curl -i http://127.0.0.1:5000/api/ROTA_QUALQUER

Troque por uma rota real da sua API. Receber 200, 401 ou até 404 já prova que ela está respondendo. Um Connection refused indica que ela não subiu: veja o log.

6. Comandos do dia a dia

Comando O que faz
sudo systemctl restart braggo-api reinicia a API
sudo systemctl stop braggo-api para
sudo systemctl start braggo-api inicia
sudo systemctl status braggo-api situação atual
sudo journalctl -u braggo-api -n 100 --no-pager últimas 100 linhas de log
sudo journalctl -u braggo-api --since "1 hour ago" log da última hora
sudo journalctl -u braggo-api -p err só os erros

7. Ajustes no código para rodar atrás do Nginx

A API recebe as requisições do Nginx, que fala HTTP simples, mesmo que o visitante use HTTPS no navegador. Para a API saber o protocolo e o IP reais do visitante, ela precisa ler os cabeçalhos X-Forwarded-*. No Program.cs, antes dos outros middlewares:

using Microsoft.AspNetCore.HttpOverrides;

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

Isso evita, por exemplo, loops de redirecionamento se você usa UseHttpsRedirection(), e faz os links gerados pela API saírem com https. Como o Nginx está em 127.0.0.1, ele já é um proxy confiável por padrão.

Sobre CORS: como o Angular e a API são servidos pelo mesmo domínio, o navegador não faz chamadas entre origens e você não precisa configurá-lo para produção. Só será necessário se o front chamar a API usando uma URL absoluta, como https://api.braggo.com.br.

Checklist ao final desta etapa

  • [ ] systemctl status braggo-api mostra active (running)
  • [ ] curl em 127.0.0.1:5000 responde
  • [ ] systemctl is-enabled braggo-api mostra enabled
  • [ ] Logs sem erros de conexão com o banco