🚀 Deployment Guide

This guide covers deploying your StoneJS Framework application to production environments. We'll cover different hosting options, best practices, and security considerations.

Pre-Deployment Checklist

Before deploying to production, ensure you have:

1. Environment Configuration

Production .env File

# Environment NODE_ENV=production PORT=3000 # Session Security SESSION_SECRET=your-very-long-random-secret-key-here # Database DB_TYPE=postgresql DB_HOST=your-production-db-host.com DB_PORT=5432 DB_USER=your_db_user DB_PASSWORD=your_strong_password DB_NAME=your_production_db # Redis (for session storage and caching) REDIS_HOST=your-redis-host.com REDIS_PORT=6379 REDIS_PASSWORD=your_redis_password # SSL/TLS HTTPS_ENABLED=true SSL_CERT_PATH=/path/to/cert.pem SSL_KEY_PATH=/path/to/key.pem # Logging LOG_LEVEL=error LOG_FILE=/var/log/stonejs/app.log

Production Server Configuration

require('dotenv').config(); const StoneJS = require('stonejs-framework'); const app = new StoneJS({ root: './pages', port: process.env.PORT || 3000, // Performance autoReload: false, // Disable auto-reload in production // Session with Redis session: { secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, store: new RedisStore({ host: process.env.REDIS_HOST, port: process.env.REDIS_PORT, password: process.env.REDIS_PASSWORD }), cookie: { secure: true, // Require HTTPS httpOnly: true, maxAge: 86400000, sameSite: 'strict' } }, // Cache with Redis cache: { store: 'redis', host: process.env.REDIS_HOST, port: process.env.REDIS_PORT, password: process.env.REDIS_PASSWORD, defaultTTL: 3600 }, // Database database: { type: 'postgresql', host: process.env.DB_HOST, port: process.env.DB_PORT, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, ssl: true, pool: { min: 2, max: 20 } } }); app.listen();

2. Deployment Options

Option A: Traditional VPS (DigitalOcean, Linode, AWS EC2)

Step 1: Set Up Server

# Update system sudo apt update && sudo apt upgrade -y # Install Node.js (via NodeSource) curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt install -y nodejs # Install PM2 for process management sudo npm install -g pm2 # Install Nginx for reverse proxy sudo apt install -y nginx # Install PostgreSQL sudo apt install -y postgresql postgresql-contrib # Install Redis sudo apt install -y redis-server

Step 2: Deploy Application

# Clone your repository git clone https://github.com/yourorg/your-app.git cd your-app # Install dependencies npm install --production # Set up environment variables cp .env.example .env nano .env # Edit with production values # Start with PM2 pm2 start server.js --name stonejs-app pm2 save pm2 startup

Step 3: Configure Nginx Reverse Proxy

# Create Nginx config sudo nano /etc/nginx/sites-available/stonejs-app # Add this configuration: server { listen 80; server_name yourdomain.com www.yourdomain.com; location / { proxy_pass http://localhost:3000; 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; } } # Enable the site sudo ln -s /etc/nginx/sites-available/stonejs-app /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx

Step 4: Set Up SSL with Let's Encrypt

# Install Certbot sudo apt install -y certbot python3-certbot-nginx # Get SSL certificate sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # Auto-renewal is set up automatically

Option B: Docker Deployment

Create Dockerfile

FROM node:18-alpine # Create app directory WORKDIR /usr/src/app # Copy package files COPY package*.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose port EXPOSE 3000 # Start application CMD ["node", "server.js"]

Create docker-compose.yml

version: '3.8' services: app: build: . ports: - "3000:3000" environment: - NODE_ENV=production - DB_HOST=postgres - REDIS_HOST=redis depends_on: - postgres - redis restart: unless-stopped postgres: image: postgres:15 environment: POSTGRES_DB: your_database POSTGRES_USER: your_user POSTGRES_PASSWORD: your_password volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped redis: image: redis:7-alpine restart: unless-stopped nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl:/etc/nginx/ssl:ro depends_on: - app restart: unless-stopped volumes: postgres_data:

Deploy with Docker

# Build and start docker-compose up -d # View logs docker-compose logs -f app # Stop docker-compose down

Option C: Platform as a Service (Heroku, Railway, Render)

Heroku Deployment

# Install Heroku CLI curl https://cli-assets.heroku.com/install.sh | sh # Login heroku login # Create app heroku create your-app-name # Add PostgreSQL addon heroku addons:create heroku-postgresql:hobby-dev # Add Redis addon heroku addons:create heroku-redis:hobby-dev # Set environment variables heroku config:set NODE_ENV=production heroku config:set SESSION_SECRET=your-secret-key # Deploy git push heroku main # View logs heroku logs --tail

Option D: Serverless (AWS Lambda, Vercel, Netlify)

Note: StoneJS Framework is designed for traditional server deployments. For serverless environments, you may need to adapt the architecture or consider using serverless-specific frameworks.

3. Security Best Practices

Critical Security Measures:

1. Remove Demo Directory

# Option 1: Delete it rm -rf pages/demo # Option 2: Protect with authentication (in autohandler) if (!$session.isAdmin && $req.path.startsWith('/demo')) { $res.status(403).send('Forbidden'); return; }

2. Secure Session Configuration

session: { secret: process.env.SESSION_SECRET, // Strong random value resave: false, saveUninitialized: false, cookie: { secure: true, // HTTPS only httpOnly: true, // Prevent XSS maxAge: 3600000, // 1 hour sameSite: 'strict' // CSRF protection } }

3. Enable Helmet for HTTP Headers

npm install helmet // In server.js const helmet = require('helmet'); app.use(helmet());

4. Rate Limiting

npm install express-rate-limit const rateLimit = require('express-rate-limit'); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100 // limit each IP to 100 requests per windowMs }); app.use(limiter);

5. Input Validation

6. Environment Variables

4. Performance Optimization

Enable Compression

npm install compression const compression = require('compression'); app.use(compression());

Static Asset Caching

// In Nginx config location /static { expires 1y; add_header Cache-Control "public, immutable"; }

Database Connection Pooling

database: { pool: { min: 2, max: 20, idleTimeoutMillis: 30000, connectionTimeoutMillis: 2000 } }

Redis Caching

5. Monitoring and Logging

Set Up PM2 Monitoring

# Monitor with PM2 pm2 monit # Enable PM2 web dashboard pm2 web # View logs pm2 logs stonejs-app # Rotate logs pm2 install pm2-logrotate

Application Logging

npm install winston const winston = require('winston'); const logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }) ] }); if (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ format: winston.format.simple() })); }

Error Tracking (Sentry)

npm install @sentry/node const Sentry = require('@sentry/node'); Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV });

6. Backup and Recovery

Database Backups

# Automated daily backup script #!/bin/bash BACKUP_DIR="/backups/postgresql" DATE=$(date +%Y%m%d_%H%M%S) pg_dump -U your_user your_database > "$BACKUP_DIR/backup_$DATE.sql" # Keep only last 7 days find $BACKUP_DIR -name "backup_*.sql" -mtime +7 -delete

Application Backups

7. Continuous Deployment

GitHub Actions Example

# .github/workflows/deploy.yml name: Deploy to Production on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Deploy to server uses: appleboy/ssh-action@master with: host: ${{ secrets.SERVER_HOST }} username: ${{ secrets.SERVER_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} script: | cd /var/www/your-app git pull origin main npm install --production pm2 restart stonejs-app

8. Scaling Your Application

Horizontal Scaling with PM2 Cluster Mode

# ecosystem.config.js module.exports = { apps: [{ name: 'stonejs-app', script: './server.js', instances: 'max', // Use all CPU cores exec_mode: 'cluster', env: { NODE_ENV: 'production' } }] }; # Start cluster pm2 start ecosystem.config.js

Load Balancing with Nginx

upstream stonejs_cluster { least_conn; server localhost:3000; server localhost:3001; server localhost:3002; server localhost:3003; } server { location / { proxy_pass http://stonejs_cluster; } }

9. Health Checks and Uptime Monitoring

Add Health Check Endpoint

// Create pages/health <% $res.setHeader('Content-Type', 'application/json'); const health = { status: 'healthy', timestamp: new Date().toISOString(), uptime: process.uptime(), database: $db ? 'connected' : 'disconnected', cache: $cache ? 'available' : 'unavailable' }; $res.send(JSON.stringify(health)); %>

External Monitoring

10. Rollback Strategy

# Keep last 5 releases /var/www/your-app/ ├── current -> releases/20240121_120000 ├── releases/ │ ├── 20240121_120000/ │ ├── 20240120_150000/ │ ├── 20240119_100000/ │ ├── 20240118_140000/ │ └── 20240117_110000/ # Rollback script #!/bin/bash cd /var/www/your-app PREVIOUS=$(ls -t releases | sed -n '2p') ln -snf releases/$PREVIOUS current pm2 restart stonejs-app

Post-Deployment Checklist

After deployment, verify:

Resources

Need help with deployment? Join our community or consult with a DevOps professional for complex setups.