Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
Core: - Add catalog reference implementations (auth, payments, notifications, websocket, etc.) - New agent profiles: Database Auditor, Integration Validator, LLM Agent, Policy Auditor, Trading Strategist - Update SIMCO directives and add escalation/git guidelines - Add deployment inventory and audit execution reports Projects: - erp-suite: DevOps configs, Dockerfiles, shared libs, vertical enhancements - gamilit: Test structure, admin controllers, service refactoring, husky/commitlint - trading-platform: MT4 gateway, auth controllers, admin frontend, deployment scripts - platform_marketing_content: Full DevOps setup, tests, Docker configs - betting-analytics/inmobiliaria-analytics: Initial app structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
15 KiB
15 KiB
Deployment Guide
Production Environment
Server Information
- IP: 74.208.126.102
- OS: Linux
- Process Manager: PM2
- Database: PostgreSQL 16
- Node.js: v18+
Deployed Services
| Service | Port | Instances | Status |
|---|---|---|---|
| Backend API | 3006 | 2 (cluster) | Active |
| Frontend | 3005 | 1 | Active |
| PostgreSQL | 5432 | 1 | Active |
URLs
- Frontend: http://74.208.126.102:3005
- Backend API: http://74.208.126.102:3006/api
- API Docs (Swagger): http://74.208.126.102:3006/api/docs
Prerequisites
Server Requirements
- Ubuntu 20.04+ or similar Linux distribution
- Node.js 18+ and npm 9+
- PostgreSQL 16+
- PM2 installed globally
- Git
Development Requirements
- Node.js 18+
- PostgreSQL 16+
- npm 9+
Initial Setup
1. Clone Repository
git clone <repository-url> gamilit
cd gamilit
2. Install Dependencies
# Backend
cd apps/backend
npm install
# Frontend
cd ../frontend
npm install
3. Database Setup
# Connect to PostgreSQL
psql -U postgres
# Create database
CREATE DATABASE gamilit_production;
# Create user
CREATE USER gamilit_user WITH ENCRYPTED PASSWORD 'your_secure_password';
# Grant privileges
GRANT ALL PRIVILEGES ON DATABASE gamilit_production TO gamilit_user;
# Exit psql
\q
# Run DDL scripts
cd apps/database
psql -U gamilit_user -d gamilit_production -f ddl/schemas/auth_management/schema.sql
psql -U gamilit_user -d gamilit_production -f ddl/schemas/student_learning/schema.sql
# ... repeat for all schemas
# Run migrations
cd ../backend
npm run migration:run
# Seed initial data (optional)
npm run seed
4. Environment Configuration
Backend .env
# apps/backend/.env
# Server
NODE_ENV=production
PORT=3006
HOST=0.0.0.0
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=gamilit_production
DB_USER=gamilit_user
DB_PASSWORD=your_secure_password
DB_SSL=false
DB_LOGGING=false
# JWT
JWT_SECRET=your_super_secret_jwt_key_min_32_characters
JWT_EXPIRES_IN=24h
# CORS
CORS_ORIGIN=http://74.208.126.102:3005
# Email (SMTP)
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USER=your_email@gmail.com
MAIL_PASSWORD=your_app_password
MAIL_FROM=noreply@gamilit.com
# Web Push (VAPID)
VAPID_PUBLIC_KEY=your_vapid_public_key
VAPID_PRIVATE_KEY=your_vapid_private_key
VAPID_SUBJECT=mailto:admin@gamilit.com
# File Upload
UPLOAD_DIR=./uploads
MAX_FILE_SIZE=5242880
# Rate Limiting
RATE_LIMIT_TTL=60
RATE_LIMIT_MAX=100
# Logging
LOG_LEVEL=info
Frontend .env
# apps/frontend/.env
VITE_API_URL=http://74.208.126.102:3006/api
VITE_WS_URL=ws://74.208.126.102:3006
VITE_APP_NAME=GAMILIT
VITE_APP_VERSION=2.0.0
5. Build Applications
# Backend
cd apps/backend
npm run build
# Frontend
cd ../frontend
npm run build
Deployment with PM2
1. Install PM2
npm install -g pm2
2. PM2 Ecosystem File
Create ecosystem.config.js in project root:
module.exports = {
apps: [
{
name: 'gamilit-backend',
script: 'dist/main.js',
cwd: './apps/backend',
instances: 2,
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 3006
},
error_file: './logs/backend-error.log',
out_file: './logs/backend-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
autorestart: true,
watch: false,
max_memory_restart: '1G'
},
{
name: 'gamilit-frontend',
script: 'npx',
args: 'serve -s dist -l 3005',
cwd: './apps/frontend',
instances: 1,
exec_mode: 'fork',
env: {
NODE_ENV: 'production'
},
error_file: './logs/frontend-error.log',
out_file: './logs/frontend-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
autorestart: true,
watch: false
}
]
};
3. Start Services
# Start all apps
pm2 start ecosystem.config.js
# Or start individually
pm2 start ecosystem.config.js --only gamilit-backend
pm2 start ecosystem.config.js --only gamilit-frontend
# Save PM2 process list
pm2 save
# Setup PM2 to start on system boot
pm2 startup
# Follow instructions displayed
PM2 Commands
Basic Operations
# View status
pm2 status
# View logs (all apps)
pm2 logs
# View logs (specific app)
pm2 logs gamilit-backend
pm2 logs gamilit-frontend
# Real-time monitoring
pm2 monit
# Restart all
pm2 restart all
# Restart specific app
pm2 restart gamilit-backend
# Stop all
pm2 stop all
# Stop specific app
pm2 stop gamilit-backend
# Delete app from PM2
pm2 delete gamilit-backend
# Reload app (zero-downtime for cluster mode)
pm2 reload gamilit-backend
# Flush logs
pm2 flush
Advanced Monitoring
# Show app info
pm2 show gamilit-backend
# List processes with details
pm2 list
# Monitor CPU/Memory
pm2 monit
# Generate startup script
pm2 startup
# Save current process list
pm2 save
# Resurrect previously saved processes
pm2 resurrect
Deployment Scripts
Pre-deployment Check
Create scripts/pre-deploy-check.sh:
#!/bin/bash
echo "🔍 Pre-deployment checks..."
# Check Node.js version
NODE_VERSION=$(node -v)
echo "✓ Node.js version: $NODE_VERSION"
# Check npm version
NPM_VERSION=$(npm -v)
echo "✓ npm version: $NPM_VERSION"
# Check PostgreSQL
psql --version
echo "✓ PostgreSQL installed"
# Check PM2
pm2 -v
echo "✓ PM2 installed"
# Check disk space
df -h
echo "✅ Pre-deployment checks complete!"
Build Script
Create scripts/build-production.sh:
#!/bin/bash
echo "🔨 Building for production..."
# Backend
echo "Building backend..."
cd apps/backend
npm run build
if [ $? -ne 0 ]; then
echo "❌ Backend build failed"
exit 1
fi
echo "✓ Backend built successfully"
# Frontend
echo "Building frontend..."
cd ../frontend
npm run build
if [ $? -ne 0 ]; then
echo "❌ Frontend build failed"
exit 1
fi
echo "✓ Frontend built successfully"
echo "✅ Build complete!"
Deployment Script
Create scripts/deploy-production.sh:
#!/bin/bash
echo "🚀 Deploying to production..."
# Run pre-deployment checks
./scripts/pre-deploy-check.sh
# Build
./scripts/build-production.sh
# Run migrations
echo "Running database migrations..."
cd apps/backend
npm run migration:run
cd ../..
# Reload PM2 apps (zero-downtime)
echo "Reloading PM2 applications..."
pm2 reload ecosystem.config.js
# Save PM2 process list
pm2 save
echo "✅ Deployment complete!"
echo "Frontend: http://74.208.126.102:3005"
echo "Backend: http://74.208.126.102:3006/api"
Make scripts executable:
chmod +x scripts/*.sh
Database Migrations
Create Migration
cd apps/backend
npm run migration:create -- -n MigrationName
Run Migrations
npm run migration:run
Revert Migration
npm run migration:revert
Show Migrations
npm run migration:show
Backup & Recovery
Database Backup
# Create backup directory
mkdir -p backups
# Backup database
pg_dump -U gamilit_user -d gamilit_production -F c -f backups/gamilit_$(date +%Y%m%d_%H%M%S).dump
# Backup with plain SQL
pg_dump -U gamilit_user -d gamilit_production > backups/gamilit_$(date +%Y%m%d_%H%M%S).sql
Automated Backup Script
Create scripts/backup-database.sh:
#!/bin/bash
BACKUP_DIR="/path/to/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="gamilit_production"
DB_USER="gamilit_user"
# Create backup
pg_dump -U $DB_USER -d $DB_NAME -F c -f $BACKUP_DIR/gamilit_$DATE.dump
# Keep only last 7 days of backups
find $BACKUP_DIR -name "gamilit_*.dump" -mtime +7 -delete
echo "Backup completed: gamilit_$DATE.dump"
Schedule Automatic Backups
# Edit crontab
crontab -e
# Add daily backup at 2 AM
0 2 * * * /path/to/scripts/backup-database.sh
Restore Database
# From custom format
pg_restore -U gamilit_user -d gamilit_production -c backups/gamilit_20251212_020000.dump
# From SQL file
psql -U gamilit_user -d gamilit_production < backups/gamilit_20251212_020000.sql
Docker Deployment (Alternative)
Dockerfile (Backend)
Create apps/backend/Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3006
CMD ["node", "dist/main.js"]
Dockerfile (Frontend)
Create apps/frontend/Dockerfile:
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 3005
docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: gamilit_production
POSTGRES_USER: gamilit_user
POSTGRES_PASSWORD: your_secure_password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
backend:
build:
context: ./apps/backend
dockerfile: Dockerfile
ports:
- "3006:3006"
environment:
NODE_ENV: production
DB_HOST: postgres
depends_on:
- postgres
frontend:
build:
context: ./apps/frontend
dockerfile: Dockerfile
ports:
- "3005:3005"
depends_on:
- backend
volumes:
postgres_data:
Docker Commands
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
# Rebuild
docker-compose up -d --build
SSL/TLS Configuration (Nginx Reverse Proxy)
Install Nginx
sudo apt update
sudo apt install nginx
Nginx Configuration
Create /etc/nginx/sites-available/gamilit:
server {
listen 80;
server_name your-domain.com;
# Frontend
location / {
proxy_pass http://127.0.0.1:3005;
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;
}
# Backend API
location /api {
proxy_pass http://127.0.0.1:3006;
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;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# WebSocket
location /socket.io {
proxy_pass http://127.0.0.1:3006;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Enable site:
sudo ln -s /etc/nginx/sites-available/gamilit /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
SSL with Let's Encrypt
# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Obtain certificate
sudo certbot --nginx -d your-domain.com
# Auto-renewal is set up automatically
# Test renewal
sudo certbot renew --dry-run
Monitoring & Logging
PM2 Logging
Logs are stored in:
apps/backend/logs/backend-error.logapps/backend/logs/backend-out.logapps/frontend/logs/frontend-error.logapps/frontend/logs/frontend-out.log
Application Logs
Backend uses Winston for logging. Logs are written to:
- Console (development)
- Files (production):
apps/backend/logs/
Log Rotation
Install logrotate:
sudo apt install logrotate
Create /etc/logrotate.d/gamilit:
/path/to/gamilit/apps/backend/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0644 username username
}
Troubleshooting
Backend Not Starting
# Check logs
pm2 logs gamilit-backend
# Check if port is in use
sudo lsof -i :3006
# Restart backend
pm2 restart gamilit-backend
Database Connection Issues
# Check PostgreSQL status
sudo systemctl status postgresql
# Restart PostgreSQL
sudo systemctl restart postgresql
# Check connection
psql -U gamilit_user -d gamilit_production -c "SELECT 1"
High Memory Usage
# Check PM2 processes
pm2 monit
# Restart with memory limit
pm2 restart gamilit-backend --max-memory-restart 500M
Port Already in Use
# Find process using port
sudo lsof -i :3006
# Kill process
sudo kill -9 <PID>
Performance Tuning
PM2 Cluster Mode
Backend runs in cluster mode with 2 instances for better performance and availability.
Database Optimization
- Create indexes on frequently queried columns
- Use connection pooling (configured in TypeORM)
- Regular VACUUM and ANALYZE
-- Run maintenance
VACUUM ANALYZE;
-- Check table sizes
SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
Nginx Caching
Add to Nginx config for static assets caching:
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
Security Checklist
- Change default passwords
- Enable firewall (ufw)
- Use SSL/TLS certificates
- Keep dependencies updated
- Regular security audits (
npm audit) - Implement rate limiting
- Use environment variables for secrets
- Regular database backups
- Monitor logs for suspicious activity
- Disable root SSH login
Rollback Procedure
1. Stop Current Version
pm2 stop all
2. Restore Previous Code
git checkout <previous-commit-hash>
3. Rebuild
./scripts/build-production.sh
4. Revert Database
npm run migration:revert
5. Restart Services
pm2 restart all
CI/CD Pipeline (Future)
GitHub Actions workflow example:
name: Deploy Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to server
run: |
ssh user@74.208.126.102 'cd /path/to/gamilit && git pull && ./scripts/deploy-production.sh'
Support
For deployment issues:
- Check logs:
pm2 logs - Check database:
psql -U gamilit_user -d gamilit_production - Review this documentation
- Contact DevOps team