# 🚀 Guía de Deploy - App Canchas de Pádel Guía completa para deployar la aplicación en un servidor de producción (VPS). ## 📋 Índice - [Preparación](#preparación) - [Deploy en VPS](#deploy-en-vps) - [Configuración PM2](#configuración-pm2) - [Configuración Nginx](#configuración-nginx) - [SSL con Let's Encrypt](#ssl-con-lets-encrypt) - [Backup de Base de Datos](#backup-de-base-de-datos) --- ## Preparación ### Checklist Pre-Deploy - [ ] Código actualizado en repositorio - [ ] Variables de entorno configuradas - [ ] Base de datos creada - [ ] Dominio configurado (DNS apuntando al servidor) - [ ] Acceso SSH al servidor ### Servidor Requerido | Especificación | Mínimo | Recomendado | |----------------|--------|-------------| | CPU | 2 vCPU | 4 vCPU | | RAM | 2 GB | 4 GB | | Disco | 20 GB SSD | 50 GB SSD | | OS | Ubuntu 22.04 | Ubuntu 24.04 LTS | --- ## Deploy en VPS ### 1. Configurar Servidor Conectar al servidor: ```bash ssh usuario@tu-servidor.com ``` Actualizar sistema: ```bash sudo apt update && sudo apt upgrade -y ``` Instalar dependencias: ```bash # Node.js 20.x curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs # PostgreSQL sudo apt install postgresql postgresql-contrib -y # Git sudo apt install git -y # Nginx sudo apt install nginx -y # PM2 global sudo npm install -g pm2 ``` ### 2. Configurar PostgreSQL ```bash # Iniciar servicio sudo systemctl start postgresql sudo systemctl enable postgresql # Crear usuario y base de datos sudo -u postgres psql < ecosystem.config.js << 'EOF' module.exports = { apps: [{ name: 'app-padel-api', script: './dist/index.js', instances: 'max', exec_mode: 'cluster', env: { NODE_ENV: 'production', PORT: 3000 }, log_file: './logs/combined.log', out_file: './logs/out.log', error_file: './logs/error.log', log_date_format: 'YYYY-MM-DD HH:mm:ss Z', merge_logs: true, max_memory_restart: '1G', restart_delay: 3000, max_restarts: 5, min_uptime: '10s', watch: false, env_production: { NODE_ENV: 'production' } }] }; EOF ``` Iniciar con PM2: ```bash pm2 start ecosystem.config.js pm2 save pm2 startup ``` Comandos útiles: ```bash pm2 status # Ver estado pm2 logs app-padel-api # Ver logs pm2 restart app-padel-api # Reiniciar pm2 stop app-padel-api # Detener pm2 delete app-padel-api # Eliminar ``` --- ## Configuración Nginx ### 1. Crear Configuración ```bash sudo nano /etc/nginx/sites-available/app-padel ``` Contenido: ```nginx # Upstream para la API upstream app_padel_api { least_conn; server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; } # Rate limiting zone limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; server { listen 80; server_name api.tudominio.com; # Logs access_log /var/log/nginx/app-padel-access.log; error_log /var/log/nginx/app-padel-error.log; # Headers de seguridad add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; # Tamaño máximo de body client_max_body_size 10M; # Gzip gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; # Webhooks de MercadoPago (sin rate limit) location ~ ^/api/v1/(payments|subscriptions)/webhook { proxy_pass http://app_padel_api; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; 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; proxy_cache_bypass $http_upgrade; proxy_read_timeout 86400; } # API con rate limiting location /api/ { limit_req zone=api_limit burst=20 nodelay; proxy_pass http://app_padel_api; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; 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; proxy_cache_bypass $http_upgrade; proxy_read_timeout 300s; } # Health check location /health { proxy_pass http://app_padel_api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; access_log off; } # Root location / { return 200 '{"status":"API App Padel","version":"1.0.0"}'; add_header Content-Type application/json; } } ``` ### 2. Habilitar Sitio ```bash # Crear enlace simbólico sudo ln -s /etc/nginx/sites-available/app-padel /etc/nginx/sites-enabled/ # Verificar configuración sudo nginx -t # Reiniciar Nginx sudo systemctl restart nginx ``` --- ## SSL con Let's Encrypt ### 1. Instalar Certbot ```bash sudo apt install certbot python3-certbot-nginx -y ``` ### 2. Obtener Certificado ```bash sudo certbot --nginx -d api.tudominio.com ``` Sigue las instrucciones interactivas. ### 3. Configuración Auto-Renovación ```bash # Verificar renovación automática sudo certbot renew --dry-run # El cronjob se instala automáticamente # Verificar: /etc/cron.d/certbot ``` ### 4. Configuración Nginx con SSL (Auto-generada) Certbot modificará la configuración automáticamente. Verificar: ```bash sudo nano /etc/nginx/sites-available/app-padel ``` Debería incluir: ```nginx listen 443 ssl; ssl_certificate /etc/letsencrypt/live/api.tudominio.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.tudominio.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; ``` --- ## Backup de Base de Datos ### 1. Script de Backup Automático Crear script: ```bash sudo mkdir -p /opt/backups sudo nano /opt/backups/backup-db.sh ``` Contenido: ```bash #!/bin/bash # Configuración DB_NAME="app_padel" DB_USER="app_padel" BACKUP_DIR="/opt/backups" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="${BACKUP_DIR}/app_padel_${DATE}.sql" RETENTION_DAYS=30 # Crear backup pg_dump -U ${DB_USER} -d ${DB_NAME} -F p -f ${BACKUP_FILE} # Comprimir gzip ${BACKUP_FILE} # Eliminar backups antiguos find ${BACKUP_DIR} -name "app_padel_*.sql.gz" -mtime +${RETENTION_DAYS} -delete # Log echo "[$(date)] Backup completado: ${BACKUP_FILE}.gz" >> ${BACKUP_DIR}/backup.log ``` ### 2. Configurar Permisos ```bash sudo chmod +x /opt/backups/backup-db.sh sudo chown postgres:postgres /opt/backups/backup-db.sh ``` ### 3. Configurar Cron ```bash sudo crontab -e ``` Añadir (backup diario a las 2 AM): ``` 0 2 * * * /opt/backups/backup-db.sh ``` ### 4. Backup Manual ```bash # Backup manual pg_dump -U app_padel app_padel > backup_$(date +%Y%m%d).sql # Restaurar backup psql -U app_padel app_padel < backup_20260131.sql ``` ### 5. Backup en Cloud (Opcional) Configurar sincronización con S3 o similar: ```bash # Instalar AWS CLI sudo apt install awscli -y # Configurar credenciales aws configure # Añadir al script de backup aws s3 cp ${BACKUP_FILE}.gz s3://tu-bucket/backups/ ``` --- ## 🔄 Script de Deploy Automatizado Crear script `deploy.sh`: ```bash #!/bin/bash set -e APP_DIR="/home/app-padel/app-padel/backend" PM2_APP_NAME="app-padel-api" echo "🚀 Iniciando deploy..." cd $APP_DIR echo "📥 Pull de código..." git pull origin main echo "📦 Instalando dependencias..." npm ci --only=production echo "🏗️ Compilando..." npm run build echo "🔄 Ejecutando migraciones..." npx prisma migrate deploy echo "🔄 Reiniciando aplicación..." pm2 reload $PM2_APP_NAME echo "✅ Deploy completado!" # Health check echo "🏥 Verificando salud..." sleep 3 if curl -s http://localhost:3000/api/v1/health | grep -q '"success":true'; then echo "✅ API funcionando correctamente" else echo "❌ Error: API no responde" exit 1 fi ``` Hacer ejecutable: ```bash chmod +x deploy.sh ``` --- ## 📊 Monitoreo ### 1. PM2 Monit ```bash pm2 monit ``` ### 2. Logs ```bash # Logs de aplicación pm2 logs app-padel-api # Logs de Nginx sudo tail -f /var/log/nginx/app-padel-error.log # Logs del sistema sudo journalctl -u app-padel-api -f ``` ### 3. Health Check ```bash curl https://api.tudominio.com/api/v1/health ``` --- ## 🛡️ Seguridad Adicional ### Firewall (UFW) ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh sudo ufw allow http sudo ufw allow https sudo ufw enable ``` ### Fail2Ban ```bash sudo apt install fail2ban -y sudo systemctl enable fail2ban ``` --- ## ✅ Post-Deploy Checklist - [ ] API responde correctamente - [ ] HTTPS funcionando - [ ] Webhooks de MercadoPago reciben notificaciones - [ ] Emails enviándose correctamente - [ ] Backups configurados - [ ] Monitoreo activo - [ ] Documentación actualizada --- *Última actualización: Enero 2026*