404 Not Found

404 Not Found


nginx

Implantação Vercel + Docker

Com o desenvolvimento do MegaShop completo, Charlie precisa implantá-lo no ambiente de produção. A Vercel oferece um processo de implantação simples, mas tem opções de personalização limitadas, enquanto o Docker oferece controle total, mas envolve configuração complexa. Bob precisa de uma solução de implantação que seja flexível e confiável—usando Vercel para o frontend e API, e Docker para o banco de dados e Redis.

1. O Que Você Vai Aprender


2. Uma História Real de um Arquiteto

(1) Dor: Conseguir rodar ambientes de produção localmente

O MegaShop do Charlie funcionava perfeitamente localmente, mas após a implantação no servidor—variáveis de ambiente estavam faltando, o banco de dados não podia ser conectado, o Redis não estava rodando, e havia conflitos de porta. Foram necessárias cinco tentativas de Bob para implantar com sucesso, e ele encontrou um problema diferente a cada vez.

(2) A Solução Docker + Vercel

O Docker empacota todo o ambiente de runtime, e a Vercel implanta o frontend com zero configuração:

BASH
# Vercel: implantação zero-config
vercel --prod

# Docker: construa uma vez, rode em qualquer lugar
docker compose up -d

(3) Benefícios: Implantação com um clique + Ambientes consistentes

Charlie usa git push para acionar a implantação na Vercel para o frontend e Docker Compose para gerenciar o banco de dados, Redis e serviços Nuxt, garantindo um ambiente completamente consistente.


3. Implantando na Vercel

(1) Árvore de Decisão de Implantação Multiplataforma

100%
flowchart TB
    A[Implantar App Nuxt 3] --> B{Precisa de SSR?}
    B -->|Não| C[Hospedagem Estática<br/>Cloudflare/Netlify/S3]
    B -->|Sim| D{Tamanho da equipe?}
    D -->|Pequena/Média| E[Vercel<br/>Implantação zero-config]
    D -->|Grande/Enterprise| F[Docker + Node.js<br/>Controle total]
    E --> G[API + Frontend na Vercel]
    F --> H[Docker Compose<br/>Nuxt + PostgreSQL + Redis]

(1) ▶ Exemplo: Implantação Zero-Configuração na Vercel

BASH
# Instalar Vercel CLI
npm i -g vercel

# Implantar (auto-detecta Nuxt 3)
vercel

# Implantação de produção
vercel --prod

Saída:

TEXT
# Comando executado com sucesso

(2) ▶ Exemplo: Configuração Vercel no nuxt.config.ts

TYPESCRIPT
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: 'vercel' // Auto-configurado pela Vercel
  },
  // Variáveis de ambiente configuradas no dashboard da Vercel
  runtimeConfig: {
    databaseUrl: process.env.DATABASE_URL,
    redisUrl: process.env.REDIS_URL,
    public: {
      apiBase: process.env.API_BASE
    }
  }
})

Saída:

TEXT
// Execução bem-sucedida

(2) Prós e Contras da Implantação na Vercel

Dimensão Vercel Docker
Complexidade de Configuração 🟢 Zero configuração 🔴 Requer escrever um Dockerfile
Velocidade de Implantação ⚡ 30s 🟡 Build de 3-5 min
Personalização 🔴 Restrito 🟢 Controle Total
Banco de Dados 🔴 Requer serviço externo (Vercel Postgres) 🟢 Implantação local
Custo ⚠️ Cobrança por requisição 🟢 Taxa fixa de servidor
Escalabilidade 🟢 Automática 🟡 Manual/K8s

4. Implantação com Docker

(1) ▶ Exemplo: Dockerfile Multi-stage

DOCKERFILE
# Dockerfile

# Estágio 1: Instalar dependências
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# Estágio 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npx prisma generate
RUN npm run build

# Estágio 3: Produção
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production

# Copiar assets construídos
COPY --from=builder /app/.output ./.output
COPY --from=builder /app/prisma ./prisma

EXPOSE 3000

CMD ["node", ".output/server/index.mjs"]

Saída:

TEXT
// Execução bem-sucedida

(2) ▶ Exemplo: Orquestração Docker Compose

YAML
# docker-compose.yml
version: '3.8'

services:
  # Aplicação Nuxt
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://megashop:megashop_pass@db:5432/megashop
      - REDIS_URL=redis://redis:6379
      - JWT_ACCESS_SECRET=${JWT_ACCESS_SECRET}
      - JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET}
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    restart: unless-stopped

  # Banco de dados PostgreSQL
  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=megashop
      - POSTGRES_PASSWORD=megashop_pass
      - POSTGRES_DB=megashop
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U megashop"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  # Cache Redis
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped

  # Proxy reverso Nginx
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - web
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

Saída:

TEXT
CONTAINER ID   IMAGE          STATUS         PORTS
abc123         nginx:latest   Up 2 hours     0.0.0.0:80->80/tcp

(3) ▶ Exemplo: Configuração de Proxy Reverso Nginx

NGINX
# nginx.conf
events {
    worker_connections 1024;
}

http {
    upstream nuxt {
        server web:3000;
    }

    server {
        listen 80;
        server_name megashop.com;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        server_name megashop.com;

        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/key.pem;

        location / {
            proxy_pass http://nuxt;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        # Cache de assets estáticos
        location /_nuxt/ {
            proxy_pass http://nuxt;
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
}

Saída:

TEXT
// Execução bem-sucedida

5. Node.js Standalone + PM2

(1) ▶ Exemplo: Construindo um Preset Standalone

TYPESCRIPT
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: 'node-server',
    compressPublicAssets: true
  }
})

Saída:

TEXT
// Execução bem-sucedida
BASH
# Construir servidor standalone
npm run build

# Saída: .output/server/index.mjs
# Executar diretamente
node .output/server/index.mjs

(2) ▶ Exemplo: Gerenciamento de Processos com PM2

JAVASCRIPT
// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'megashop',
    script: '.output/server/index.mjs',
    instances: 'max',       // Usar todos os núcleos da CPU
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000,
      DATABASE_URL: 'postgresql://megashop:pass@localhost:5432/megashop',
      REDIS_URL: 'redis://localhost:6379'
    },
    max_memory_restart: '1G',
    error_file: './logs/error.log',
    out_file: './logs/out.log',
    merge_logs: true,
    autorestart: true
  }]
}

Saída:

TEXT
// Execução bem-sucedida
BASH
# Iniciar com PM2
pm2 start ecosystem.config.js

# Monitorar
pm2 monit

# Recarregar (zero downtime)
pm2 reload megashop

# Logs
pm2 logs megashop

(1) Comparação de Opções de Implantação

Solução Complexidade Gerenciabilidade Escalabilidade Aplicabilidade
Vercel 🟢 Baixa 🔴 Baixa 🟢 Automática Equipes Pequenas/Médias
Docker Compose 🟡 Média 🟢 Alta 🟡 Manual Equipes Médias/Grandes
PM2 + Nginx 🟡 Média 🟢 Alta 🟡 Manual Implantação VPS
K8s 🔴 Alta 🟢 Máxima 🟢 Automática Larga escala

6. Exemplo Completo: Implantação de Produção do MegaShop

BASH
# ============================================
# Implantação de Produção do MegaShop
# Docker Compose + Nginx + PostgreSQL + Redis
# ============================================

# 1. Clonar e configurar
git clone https://github.com/megashop/megashop.git
cd megashop
cp .env.example .env
# Editar .env com os segredos de produção

# 2. Construir e iniciar
docker compose up -d --build

# 3. Executar migrações do banco de dados
docker compose exec web npx prisma migrate deploy

# 4. Popular dados iniciais (apenas na primeira vez)
docker compose exec web npx prisma db seed

# 5. Verificar
curl https://megashop.com/api/products?limit=5

# 6. Monitorar
docker compose logs -f web

❓ Perguntas Frequentes

P O plano gratuito da Vercel é suficiente?
R O plano gratuito inclui 100 GB de banda por mês e 1.000 horas de uso serverless. Os cache hits ISR do MegaShop para um milhão de páginas não contam como chamadas de função, então o plano gratuito é suficiente para tráfego moderado.
P Quais são os benefícios dos builds multi-stage do Docker?
R A imagem final contém apenas os arquivos necessários para runtime e exclui código-fonte e devDependencies. O tamanho da imagem é reduzido de mais de 1 GB para aproximadamente 150 MB, tornando-a mais segura e rápida.
P Qual é a diferença entre Nuxt standalone e o preset Node?
R Não há diferença. O preset node-server gera saída standalone (.output/server/index.mjs), não requer node_modules, e pode ser executado diretamente.
P O modo cluster do PM2 suporta SSR?
R Sim. Cada worker é um processo independente que renderiza SSR por conta própria. O cache ISR é compartilhado via Redis e acessível a todos os workers.
P Como executar migrações Prisma no Docker?
R docker compose exec web npx prisma migrate deploy. Ou adicione etapas de migração ao seu Dockerfile. Para produção, use migrate deploy (que não cria novas migrações, apenas aplica as existentes).
P Como obter um certificado SSL?
R Para ambientes de produção, use Let's Encrypt + Certbot para renovação automática. Para implantações Docker, use nginx-proxy + acme-companion para obter automaticamente. A Vercel já inclui SSL por padrão.

📖 Resumo


📝 Exercícios

  1. Exercício Básico (Dificuldade: ⭐): Implante o MegaShop na Vercel, configure as variáveis de ambiente e verifique que as páginas SSR estão funcionando corretamente.
  2. Exercício Avançado (Dificuldade: ⭐⭐): Escreva um Dockerfile e docker-compose.yml para iniciar o ambiente completo (Nuxt + PostgreSQL + Redis) localmente.
  3. Desafio (Dificuldade: ⭐⭐⭐): Implemente uma implantação de produção completa usando Docker Compose, Nginx e SSL, e configure health checks e reinícios automáticos.

---|

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%