Skip to main content

Guia de Deployment

Este guia explica como fazer deploy do APAH Assistant em diferentes ambientes.

Pré-requisitos

  • Node.js 20+
  • PostgreSQL 15+
  • Docker (opcional)
  • Conta Azure (para OpenAI e Communication Services)

Build de Produção

Build Padrão

pnpm build

Isto cria uma build otimizada em .next/.

Build Standalone

Para deployment em containers:

pnpm build:solo

Cria uma build standalone em .next/standalone/ com todos os ficheiros necessários.

Opções de Deployment

1. Docker

Dockerfile

FROM node:20-alpine AS base

# Instalar dependências
FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile

# Build
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable pnpm && pnpm build:solo

# Runner
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public

USER nextjs

EXPOSE 3000
ENV PORT=3000

CMD ["node", "server.js"]

Docker Compose

version: "3.8"

services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/apah
- AUTH_SECRET=${AUTH_SECRET}
- AZURE_OPENAI_API_KEY=${AZURE_OPENAI_API_KEY}
- AZURE_OPENAI_ENDPOINT=${AZURE_OPENAI_ENDPOINT}
depends_on:
- db
restart: unless-stopped

db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=apah
restart: unless-stopped

volumes:
postgres_data:

Comandos

# Build e iniciar
docker-compose up -d --build

# Ver logs
docker-compose logs -f app

# Parar
docker-compose down

2. Vercel

A opção mais simples para Next.js.

Configuração

  1. Conecte o repositório ao Vercel
  2. Configure as variáveis de ambiente
  3. Deploy automático em cada push

vercel.json

{
"buildCommand": "pnpm build",
"installCommand": "pnpm install",
"framework": "nextjs"
}

Base de Dados

Use um serviço PostgreSQL externo:

  • Neon
  • Supabase
  • PlanetScale
  • Azure Database for PostgreSQL

3. Azure App Service

Configuração

  1. Criar App Service (Linux, Node.js 20)
  2. Configurar deployment via GitHub Actions
  3. Configurar variáveis de ambiente

GitHub Actions

# .github/workflows/azure-deploy.yml
name: Deploy to Azure

on:
push:
branches: [main]

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 9

- name: Install dependencies
run: pnpm install

- name: Build
run: pnpm build
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}

- name: Deploy to Azure
uses: azure/webapps-deploy@v2
with:
app-name: "apah-assistant"
publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
package: .

4. VPS / Servidor Dedicado

Com PM2

# Instalar PM2
npm install -g pm2

# Build
pnpm build

# Iniciar com PM2
pm2 start npm --name "apah" -- start

# Guardar configuração
pm2 save
pm2 startup

ecosystem.config.js

module.exports = {
apps: [
{
name: "apah-assistant",
script: "node_modules/.bin/next",
args: "start",
instances: "max",
exec_mode: "cluster",
env: {
NODE_ENV: "production",
PORT: 3000,
},
},
],
};

Nginx Reverse Proxy

server {
listen 80;
server_name apah.example.com;

location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

Variáveis de Ambiente de Produção

# Obrigatórias
NODE_ENV=production
DATABASE_URL=postgresql://user:pass@host:5432/apah
AUTH_SECRET=<secret-seguro-32-chars>
NEXT_PUBLIC_APP_URL=https://apah.example.com

# Azure OpenAI
AZURE_OPENAI_API_KEY=...
AZURE_OPENAI_ENDPOINT=...
AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o

# Cohere
COHERE_API_KEY=...

# Email (opcional)
AZURE_COMMUNICATION_CONNECTION_STRING=...
EMAIL_FROM=noreply@example.com

Migrações em Produção

# Aplicar migrações
pnpm db:migrate

# Ou via container
docker exec -it apah-app pnpm db:migrate

Checklist de Produção

Segurança

  • HTTPS configurado
  • AUTH_SECRET é único e seguro
  • Variáveis sensíveis não estão no código
  • Rate limiting configurado
  • CORS configurado corretamente

Performance

  • Build de produção (NODE_ENV=production)
  • Caching configurado
  • CDN para assets estáticos
  • Compressão gzip/brotli

Monitorização

  • Logs centralizados
  • Alertas configurados
  • Health checks
  • Métricas de performance

Base de Dados

  • Backups automáticos
  • Connection pooling
  • Índices otimizados
  • SSL habilitado

Health Check

// src/app/api/health/route.ts
export async function GET() {
try {
// Verificar BD
await db.execute(sql`SELECT 1`);

return Response.json({
status: "healthy",
timestamp: new Date().toISOString(),
});
} catch (error) {
return Response.json(
{ status: "unhealthy", error: error.message },
{ status: 500 }
);
}
}

Rollback

# Docker
docker-compose down
docker-compose up -d --build previous-version

# PM2
pm2 deploy production revert 1

# Vercel
# Use o dashboard para reverter para deploy anterior