Pular para o conteúdoPedro Farbo
Lição 22 / 2545 min

Deploy em Produção

Deploy em Produção

Vamos fazer deploy da API em diferentes plataformas.

Preparação

typescript
// src/server.tsimport { app } from './app'; const PORT = process.env.PORT || 3000; const server = app.listen(PORT, () => {  console.log(`🚀 Server running on port ${PORT}`);}); // Graceful shutdownconst gracefulShutdown = async (signal: string) => {  console.log(`\n${signal} received. Shutting down gracefully...`);   server.close(async () => {    console.log('HTTP server closed');     // Fecha conexões    await prisma.$disconnect();    await redis.quit();     console.log('All connections closed');    process.exit(0);  });   // Força encerramento após 30s  setTimeout(() => {    console.error('Forced shutdown');    process.exit(1);  }, 30000);}; process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));process.on('SIGINT', () => gracefulShutdown('SIGINT'));

Deploy na Railway

bash
# Instalar CLInpm install -g @railway/cli # Loginrailway login # Novo projetorailway init # Adicionar PostgreSQLrailway add # Deployrailway up
json
// railway.json{  "$schema": "https://railway.app/railway.schema.json",  "build": {    "builder": "NIXPACKS"  },  "deploy": {    "startCommand": "npm run start:prod",    "healthcheckPath": "/health",    "restartPolicyType": "ON_FAILURE"  }}

Deploy na Render

yaml
# render.yamlservices:  - type: web    name: ecommerce-api    env: node    buildCommand: npm ci && npm run build && npx prisma generate    startCommand: npm run start:prod    healthCheckPath: /health    envVars:      - key: NODE_ENV        value: production      - key: DATABASE_URL        fromDatabase:          name: ecommerce-db          property: connectionString databases:  - name: ecommerce-db    databaseName: ecommerce    user: ecommerce

Deploy na AWS com ECS

yaml
# task-definition.json{  "family": "ecommerce-api",  "networkMode": "awsvpc",  "requiresCompatibilities": ["FARGATE"],  "cpu": "256",  "memory": "512",  "executionRoleArn": "arn:aws:iam::xxx:role/ecsTaskExecutionRole",  "containerDefinitions": [    {      "name": "api",      "image": "xxx.dkr.ecr.us-east-1.amazonaws.com/ecommerce:latest",      "portMappings": [        {          "containerPort": 3000,          "protocol": "tcp"        }      ],      "environment": [        { "name": "NODE_ENV", "value": "production" }      ],      "secrets": [        {          "name": "DATABASE_URL",          "valueFrom": "arn:aws:secretsmanager:xxx:secret:db-url"        }      ],      "healthCheck": {        "command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],        "interval": 30,        "timeout": 5,        "retries": 3      },      "logConfiguration": {        "logDriver": "awslogs",        "options": {          "awslogs-group": "/ecs/ecommerce-api",          "awslogs-region": "us-east-1",          "awslogs-stream-prefix": "ecs"        }      }    }  ]}

GitHub Actions CI/CD

yaml
# .github/workflows/deploy.ymlname: Deploy on:  push:    branches: [main] jobs:  test:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4       - uses: actions/setup-node@v4        with:          node-version: '20'          cache: 'npm'       - run: npm ci      - run: npm run lint      - run: npm run test   deploy:    needs: test    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4       - name: Deploy to Railway        uses: bervProject/railway-deploy@main        with:          railway_token: ${{ secrets.RAILWAY_TOKEN }}          service: ecommerce-api

Variáveis de Ambiente em Produção

bash
# Nunca commitar .env em produção!# Use secrets managers # AWS Secrets Manageraws secretsmanager create-secret \  --name prod/ecommerce/env \  --secret-string file://secrets.json # Railwayrailway variables set DATABASE_URL="..."railway variables set JWT_SECRET="..."

Monitoramento com PM2

javascript
// ecosystem.config.jsmodule.exports = {  apps: [{    name: 'ecommerce-api',    script: 'dist/server.js',    instances: 'max',    exec_mode: 'cluster',    env_production: {      NODE_ENV: 'production',    },    max_memory_restart: '500M',    error_file: './logs/error.log',    out_file: './logs/out.log',    merge_logs: true,  }],};
bash
# Startpm2 start ecosystem.config.js --env production # Statuspm2 status # Logspm2 logs # Monitoramentopm2 monit

Checklist de Deploy

  • ✅ Testes passando
  • ✅ Build sem erros
  • ✅ Variáveis de ambiente configuradas
  • ✅ Migrations executadas
  • ✅ Health check funcionando
  • ✅ HTTPS configurado
  • ✅ Logs configurados
  • ✅ Monitoramento ativo

Resumo

  • ✅ Graceful shutdown implementado
  • ✅ Deploy em Railway, Render e AWS
  • ✅ CI/CD com GitHub Actions
  • ✅ Gerenciamento de secrets
  • ✅ PM2 para produção

Próxima aula: Projeto E-commerce - Parte 1! 🛒

Gostou do conteúdo? Sua contribuição ajuda a manter tudo online e gratuito!

PIX:0737160d-e98f-4a65-8392-5dba70e7ff3e