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
- Implantação na Vercel: Zero Configuração + Nitro Preset + Variáveis de Ambiente
- Implantação com Docker: Dockerfile + Build Multistage + docker-compose
- Implantação Node.js: preset standalone + PM2
- Hospedagem estática: Cloudflare Pages / Netlify / S3
- Guia Prático de Implantação do MegaShop em Produção: Vercel + Docker Compose
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:
# 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
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
# Instalar Vercel CLI
npm i -g vercel
# Implantar (auto-detecta Nuxt 3)
vercel
# Implantação de produção
vercel --prod
Saída:
# Comando executado com sucesso
(2) ▶ Exemplo: Configuração Vercel no nuxt.config.ts
// 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:
// 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
# 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:
// Execução bem-sucedida
(2) ▶ Exemplo: Orquestração Docker Compose
# 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:
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.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:
// Execução bem-sucedida
5. Node.js Standalone + PM2
(1) ▶ Exemplo: Construindo um Preset Standalone
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'node-server',
compressPublicAssets: true
}
})
Saída:
// Execução bem-sucedida
# 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
// 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:
// Execução bem-sucedida
# 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
# ============================================
# 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
node-server gera saída standalone (.output/server/index.mjs), não requer node_modules, e pode ser executado diretamente.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).📖 Resumo
- Vercel: Implantação zero-configuração, ideal para equipes pequenas e médias, com solução unificada de API e frontend
- Use builds multi-stage do Docker para gerar imagens otimizadas, e Docker Compose para orquestrar todo o conjunto de serviços
- O modo cluster do PM2 permite operação multi-processo e recarga sem downtime
- Proxy Reverso Nginx + SSL + Cache de Recursos Estáticos
- MegaShop Recomenda Docker Compose: Nuxt + PostgreSQL + Redis + Nginx
📝 Exercícios
- 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.
- Exercício Avançado (Dificuldade: ⭐⭐): Escreva um Dockerfile e docker-compose.yml para iniciar o ambiente completo (Nuxt + PostgreSQL + Redis) localmente.
- 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.
---|



