Este guia abrange todas as estratégias e configurações para deploy do Varion em diferentes ambientes de produção.
Ideal para servidores VPS, dedicados ou ambientes containerizados.
Para ambientes empresariais com alta disponibilidade.
Para aplicações com tráfego variável (Vercel + Railway).
AWS, GCP, Azure com serviços gerenciados.
production/
├── docker-compose.prod.yml
├── nginx/
│ ├── nginx.conf
│ └── ssl/
├── .env.prod
└── backup/
└── scripts/
# Atualizar sistema
sudo apt update && sudo apt upgrade -y
# Instalar Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Instalar Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Criar usuário para a aplicação
sudo useradd -m -s /bin/bash varion
sudo usermod -aG docker varion# Criar estrutura de diretórios
sudo mkdir -p /opt/varion/{app,data,logs,backups}
sudo chown -R varion:varion /opt/varion
# Clonar repositório
cd /opt/varion/app
git clone <repository-url> .
# Configurar variáveis de ambiente
cp .env.example .env.prodversion: '3.8'
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
target: production
container_name: varion-frontend-prod
restart: unless-stopped
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=https://api.yourdomain.com
networks:
- varion-network
backend:
build:
context: ./backend
dockerfile: Dockerfile
target: production
container_name: varion-backend-prod
restart: unless-stopped
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/varion_prod
- JWT_SECRET=${JWT_SECRET}
- CORS_ORIGIN=https://yourdomain.com
depends_on:
postgres:
condition: service_healthy
networks:
- varion-network
postgres:
image: postgres:15-alpine
container_name: varion-postgres-prod
restart: unless-stopped
environment:
- POSTGRES_DB=varion_prod
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backend/scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- varion-network
nginx:
image: nginx:alpine
container_name: varion-nginx-prod
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- ./logs/nginx:/var/log/nginx
depends_on:
- frontend
- backend
networks:
- varion-network
volumes:
postgres_data:
driver: local
driver_opts:
type: none
o: bind
device: /opt/varion/data/postgres
networks:
varion-network:
driver: bridge# nginx/nginx.conf
events {
worker_connections 1024;
}
http {
upstream frontend {
server frontend:3000;
}
upstream backend {
server backend:3001;
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
# HTTPS Frontend
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
proxy_pass http://frontend;
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;
}
}
# HTTPS Backend API
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
proxy_pass http://backend;
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;
}
}
}#!/bin/bash
# scripts/deploy.sh
set -e
echo "🚀 Iniciando deploy do Varion..."
# Backup do banco antes do deploy
./scripts/backup-db.sh
# Pull das últimas mudanças
git pull origin main
# Build e deploy
docker-compose -f docker-compose.prod.yml down
docker-compose -f docker-compose.prod.yml up --build -d
# Executar migrations
docker-compose -f docker-compose.prod.yml exec backend pnpm migration:run
# Verificar saúde dos serviços
sleep 10
./scripts/health-check.sh
echo "✅ Deploy concluído com sucesso!"# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: varion
---
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: varion-config
namespace: varion
data:
NODE_ENV: "production"
POSTGRES_DB: "varion_prod"
---
# k8s/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: varion-secrets
namespace: varion
type: Opaque
data:
DB_PASSWORD: <base64-encoded-password>
JWT_SECRET: <base64-encoded-jwt-secret>
---
# k8s/postgres.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: varion
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15-alpine
env:
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: varion-config
key: POSTGRES_DB
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: varion-secrets
key: DB_PASSWORD
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
---
# k8s/backend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: varion
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: varion/backend:latest
env:
- name: NODE_ENV
valueFrom:
configMapKeyRef:
name: varion-config
key: NODE_ENV
- name: DATABASE_URL
value: "postgresql://postgres:$(DB_PASSWORD)@postgres:5432/varion_prod"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: varion-secrets
key: DB_PASSWORD
ports:
- containerPort: 3001
---
# k8s/frontend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: varion
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: varion/frontend:latest
env:
- name: NODE_ENV
valueFrom:
configMapKeyRef:
name: varion-config
key: NODE_ENV
- name: NEXT_PUBLIC_API_URL
value: "https://api.yourdomain.com"
ports:
- containerPort: 3000
---
# k8s/services.yaml
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: varion
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
---
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: varion
spec:
selector:
app: backend
ports:
- port: 3001
targetPort: 3001
---
apiVersion: v1
kind: Service
metadata:
name: frontend
namespace: varion
spec:
selector:
app: frontend
ports:
- port: 3000
targetPort: 3000
---
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: varion-ingress
namespace: varion
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- yourdomain.com
- api.yourdomain.com
secretName: varion-tls
rules:
- host: yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 3000
- host: api.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend
port:
number: 3001# Aplicar manifests
kubectl apply -f k8s/
# Verificar status
kubectl get pods -n varion
kubectl get services -n varion
kubectl get ingress -n varion
# Logs
kubectl logs -f deployment/backend -n varion
kubectl logs -f deployment/frontend -n varion// vercel.json
{
"buildCommand": "pnpm build",
"outputDirectory": ".next",
"framework": "nextjs",
"env": {
"NEXT_PUBLIC_API_URL": "https://api.yourdomain.com"
},
"regions": ["cle1", "gru1"]
}# Deploy
npx vercel --prod
# Configurar domínio customizado
npx vercel domains add yourdomain.com# railway.toml
[build]
builder = "nixpacks"
buildCommand = "pnpm build"
[deploy]
startCommand = "pnpm start"
restartPolicyType = "always"
[[services]]
name = "varion-backend"
[services.env]
NODE_ENV = "production"
PORT = { default = 3001 }# .env.prod
NODE_ENV=production
# Database
DATABASE_URL=postgresql://user:password@host:5432/varion_prod
DB_HOST=postgres
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=strong_password_here
DB_NAME=varion_prod
# Authentication
JWT_SECRET=very_strong_jwt_secret_key_256_bits
JWT_EXPIRES_IN=7d
# CORS
CORS_ORIGIN=https://yourdomain.com
# API
API_PORT=3001
API_PREFIX=/api
# Logs
LOG_LEVEL=info
LOG_FILE=/var/log/varion/app.log
# Frontend
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
NEXT_PUBLIC_APP_NAME=Varion# backend/Dockerfile (multi-stage)
FROM node:18-alpine AS base
RUN corepack enable pnpm
FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod
FROM base AS build
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM base AS production
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nodejs
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./package.json
USER nodejs
EXPOSE 3001
CMD ["node", "dist/server.js"]-- Configurações de produção PostgreSQL
-- postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 128MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 4MB
min_wal_size = 1GB
max_wal_size = 4GB#!/bin/bash
# scripts/health-check.sh
echo "🔍 Verificando saúde dos serviços..."
# Frontend
if curl -f http://localhost:3000 > /dev/null 2>&1; then
echo "✅ Frontend: OK"
else
echo "❌ Frontend: FALHA"
exit 1
fi
# Backend
if curl -f http://localhost:3001/api/health > /dev/null 2>&1; then
echo "✅ Backend: OK"
else
echo "❌ Backend: FALHA"
exit 1
fi
# Database
if docker-compose exec postgres pg_isready -U postgres > /dev/null 2>&1; then
echo "✅ Database: OK"
else
echo "❌ Database: FALHA"
exit 1
fi
echo "🎉 Todos os serviços estão funcionando!"# docker-compose.prod.yml (logging)
x-logging: &default-logging
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
frontend:
# ...existing config...
logging: *default-logging
backend:
# ...existing config...
logging: *default-logging#!/bin/bash
# scripts/backup-db.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/opt/varion/backups"
BACKUP_FILE="$BACKUP_DIR/varion_backup_$DATE.sql"
echo "📁 Criando backup do banco de dados..."
docker-compose exec postgres pg_dump -U postgres varion_prod > $BACKUP_FILE
if [ $? -eq 0 ]; then
echo "✅ Backup criado: $BACKUP_FILE"
# Comprimir backup
gzip $BACKUP_FILE
# Manter apenas os últimos 7 backups
find $BACKUP_DIR -name "varion_backup_*.sql.gz" -mtime +7 -delete
echo "🗂️ Backups antigos removidos"
else
echo "❌ Falha no backup"
exit 1
fi#!/bin/bash
# scripts/rollback.sh
PREVIOUS_VERSION=$1
if [ -z "$PREVIOUS_VERSION" ]; then
echo "❌ Versão anterior não especificada"
echo "Uso: ./rollback.sh <git-commit-hash>"
exit 1
fi
echo "🔄 Iniciando rollback para: $PREVIOUS_VERSION"
# Backup atual
./scripts/backup-db.sh
# Checkout da versão anterior
git checkout $PREVIOUS_VERSION
# Deploy da versão anterior
docker-compose -f docker-compose.prod.yml down
docker-compose -f docker-compose.prod.yml up --build -d
echo "✅ Rollback concluído"- Testes unitários passando
- Testes de integração passando
- Build de produção sem erros
- Variáveis de ambiente configuradas
- SSL/TLS configurado
- Backup do banco atual
- Aplicação em manutenção (se necessário)
- Deploy da nova versão
- Migrations executadas
- Verificação de saúde dos serviços
- Testes de fumaça
- Monitoramento ativo
- Logs sendo coletados
- Métricas normais
- Funcionalidades críticas testadas
- Aplicação fora de manutenção