-
Notifications
You must be signed in to change notification settings - Fork 0
DEPLOYMENT
This guide covers deploying NEXUS Support System to production environments.
- Deployment Options
- Pre-Deployment Checklist
- Environment Configuration
- Deploying to VPS
- Deploying to Cloud Platforms
- Deploying with Docker
- Database Setup
- SSL/HTTPS Configuration
- Monitoring and Logging
- Backup and Recovery
- Security Hardening
-
VPS (Virtual Private Server)
- DigitalOcean
- Linode
- AWS EC2
- Google Compute Engine
-
Platform as a Service (PaaS)
- Heroku
- Render
- Railway
- Fly.io
-
Container Services
- AWS ECS
- Google Cloud Run
- Azure Container Instances
Before deploying to production:
- Update all dependencies to latest versions
- Set strong secrets for JWT and webhook
- Configure production MongoDB instance
- Set up SSL/HTTPS
- Configure CORS for production domain
- Enable rate limiting
- Set up logging and monitoring
- Configure backup strategy
- Test all functionality in staging
- Review and update
.gitignore - Remove development dependencies from production
- Set up GitHub webhooks with production URL
- Configure error tracking (Sentry, etc.)
Create a production .env file:
# Server Configuration
PORT=3000
NODE_ENV=production
# MongoDB Configuration
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/nexus-support?retryWrites=true&w=majority
# GitHub Configuration
GITHUB_WEBHOOK_SECRET=<generate-secure-random-string>
GITHUB_TOKEN=<github-personal-access-token>
GITHUB_REPO_OWNER=<your-github-username>
GITHUB_REPO_NAME=<your-repository-name>
# JWT Secret
JWT_SECRET=<generate-secure-random-string>
# Domain Configuration (if needed)
DOMAIN=https://yourdomain.com# Generate webhook secret (32 bytes hex)
openssl rand -hex 32
# Generate JWT secret (64 bytes hex)
openssl rand -hex 64Choose a VPS provider and create a server with:
- Ubuntu 20.04 LTS or newer
- Minimum 2GB RAM
- 20GB SSD storage
ssh root@your-server-ip# Update system
apt update && apt upgrade -y
# Install Node.js (using NodeSource)
curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
apt install -y nodejs
# Install MongoDB
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list
apt update
apt install -y mongodb-org
# Install PM2
npm install -g pm2
# Install Nginx
apt install -y nginx
# Install Git
apt install -y git# Start MongoDB
systemctl start mongod
systemctl enable mongod
# Enable authentication (optional but recommended)
mongo
> use admin
> db.createUser({
user: "admin",
pwd: "secure-password",
roles: ["root"]
})
> exit
# Edit MongoDB config to enable authentication
nano /etc/mongod.conf
# Add security section
security:
authorization: enabled
# Restart MongoDB
systemctl restart mongod# Clone repository
git clone <your-repository-url>
cd nexus
# Install dependencies
npm install --production
# Create .env file
nano .env
# Add your production environment variables
# Start application with PM2
pm2 start server.js --name nexus
# Configure PM2 to start on boot
pm2 startup
pm2 save# Create Nginx configuration
nano /etc/nginx/sites-available/nexusAdd the following 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:
ln -s /etc/nginx/sites-available/githhb-uupportb-support /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx# Install Certbot
apt install -y certbot python3-certbot-nginx
# Obtain SSL certificate
certbot --nginx -d yourdomain.com -d www.yourdomain.com
# Certbot will automatically configure Nginx-
Create Heroku Account
- Sign up at heroku.com
-
Install Heroku CLI
npm install -g heroku
-
Login to Heroku
heroku login
-
Create App
heroku create your-app-name
-
Add MongoDB Add-on
heroku addons:create mongolab:sandbox
-
Set Environment Variables
heroku config:set GITHUB_WEBHOOK_SECRET=your-secret heroku config:set GITHUB_TOKEN=your-token heroku config:set GITHUB_REPO_OWNER=your-username heroku config:set GITHUB_REPO_NAME=your-repo heroku config:set JWT_SECRET=your-jwt-secret
-
Deploy
git push heroku main
-
Scale Dynos
heroku ps:scale web=1
-
Create Render Account
- Sign up at render.com
-
Connect GitHub Repository
- Link your repository to Render
-
Configure Web Service
- Runtime: Node
- Build Command:
npm install - Start Command:
node server.js
-
Add Environment Variables
- Add all required environment variables in Render dashboard
-
Deploy
- Render will auto-deploy on push to main branch
-
Create Railway Account
- Sign up at railway.app
-
New Project
- Click "New Project" → "Deploy from GitHub repo"
-
Add MongoDB
- Add MongoDB database from Railway marketplace
-
Configure Variables
- Add environment variables in Railway dashboard
-
Deploy
- Railway will auto-deploy
Create Dockerfile in project root:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]node_modules
npm-debug.log
.env
.git
.gitignore
README.md
docs
docker build -t nexus:latest .docker run -d \
--name nexus \
-p 3000:3000 \
--env-file .env \
nexus:latestCreate docker-compose.yml:
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mongodb:27017/nexus-support
- GITHUB_WEBHOOK_SECRET=${GITHUB_WEBHOOK_SECRET}
- GITHUB_TOKEN=${GITHUB_TOKEN}
- GITHUB_REPO_OWNER=${GITHUB_REPO_OWNER}
- GITHUB_REPO_NAME=${GITHUB_REPO_NAME}
- JWT_SECRET=${JWT_SECRET}
depends_on:
- mongodb
restart: unless-stopped
mongodb:
image: mongo:6.0
volumes:
- mongodb-data:/data/db
restart: unless-stopped
volumes:
mongodb-data:Run with Docker Compose:
docker-compose up -d-
Create Atlas Account
- Sign up at mongodb.com/cloud/atlas
-
Create Cluster
- Choose cluster tier (M0 free for development)
- Select region closest to your users
-
Configure Security
- Whitelist IP addresses (0.0.0.0/0 for all, or specific IPs)
- Create database user with username and password
-
Get Connection String
- Copy connection string from Atlas dashboard
- Format:
mongodb+srv://username:password@cluster.mongodb.net/database
-
Update Environment Variables
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/nexus-support?retryWrites=true&w=majority
For production, consider:
- Replica sets for high availability
- Sharding for large datasets
- Regular backups
- Monitoring with MongoDB Ops Manager
# Install Certbot
apt install -y certbot
# Obtain certificate
certbot certonly --standalone -d yourdomain.com
# Certificate location:
# /etc/letsencrypt/live/yourdomain.com/fullchain.pem
# /etc/letsencrypt/live/yourdomain.com/privkey.pemserver {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
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;
}
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}Certbot automatically sets up renewal:
# Test renewal
certbot renew --dry-run
# Renewal is automatic via cron# View real-time metrics
pm2 monit
# View logs
pm2 logs nexus
# View log file location
pm2 show nexusAdd Winston or similar logging library:
npm install winstonConfigure logger in server.js:
const winston = require('winston');
const logger = winston.createLogger({
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()
}));
}- Sentry: Error tracking and performance monitoring
- Loggly: Log aggregation and analysis
- Datadog: Full-stack monitoring
- New Relic: Application performance monitoring
Use MongoDB Atlas built-in monitoring or:
- MongoDB Ops Manager
- Percona Monitoring and Management (PMM)
# Create backup
mongodump --uri="mongodb://username:password@host:port/database" --out=/backup/path
# Restore backup
mongorestore --uri="mongodb://username:password@host:port/database" /backup/pathCreate backup script:
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/mongodb"
MONGODB_URI="mongodb://username:password@host:port/database"
mkdir -p $BACKUP_DIR
mongodump --uri="$MONGODB_URI" --out="$BACKUP_DIR/$DATE"
# Keep only last 7 days
find $BACKUP_DIR -type d -mtime +7 -exec rm -rf {} \;Add to crontab:
crontab -e
# Add: 0 2 * * * /path/to/backup-script.shAtlas provides automated backups:
- Enable in Atlas dashboard
- Configure retention period
- Set up point-in-time recovery
Backup application files:
# Backup application
tar -czf nexus-backup.tar.gz /path/to/nexus
# Backup environment variables
cp .env .env.backup# Install UFW
apt install -y ufw
# Allow SSH
ufw allow 22/tcp
# Allow HTTP/HTTPS
ufw allow 80/tcp
ufw allow 443/tcp
# Enable firewall
ufw enable-
Update dependencies regularly
npm audit npm audit fix
-
Use Helmet for security headers
- Already configured in
server.jswith explicit Content Security Policy - HSTS enabled with 1-year max age
- Already configured in
-
Implement rate limiting
- General rate limiting: 100 requests per 15 minutes per IP
- Login rate limiting: 5 attempts per 15 minutes per IP
- Already configured in
server.js
-
Validate all inputs
- Use Mongoose validators
- Use validator library for email validation
- Password complexity requirements enforced (8+ chars, uppercase, lowercase, number, special char)
- Input sanitization with express-mongo-sanitize, xss-clean, and hpp
-
Secure environment variables
- Never commit
.env - Use secrets management in production (AWS Secrets Manager, HashiCorp Vault, etc.)
- Set
NODE_ENV=productionin production - Use strong, random secrets for JWT_SECRET and GITHUB_WEBHOOK_SECRET
- Never commit
-
Enable CORS only for trusted origins
- Configure
CORS_ORIGINenvironment variable to specific domains - Never use wildcard (*) in production
- Configure
-
HTTPS enforcement
- Automatically enabled when
NODE_ENV=production - Requires reverse proxy (Nginx/Apache) with SSL certificates
- HSTS preload enabled
- Automatically enabled when
-
MongoDB SSL/TLS
- Enable MongoDB SSL/TLS in production
- Configure SSL/TLS options in environment variables:
MONGODB_SSL=trueMONGODB_TLS=true- Set CA file path for certificate verification
- Use connection string with
mongodb+srv://for Atlas
-
Security audit logging
- Logs written to
logs/security.log - Monitor logs regularly for suspicious activities
- Set up log rotation to prevent disk space issues
- Configure alerts for failed login attempts
- Logs written to
-
Body size limits
- 10kb limit on request bodies
- Prevents large payload attacks
-
Enable authentication
- Create database users
- Use strong passwords
-
Enable network encryption
- Use TLS/SSL connections
-
Restrict network access
- Use IP whitelisting
- Use VPN for admin access
-
Enable audit logging
- Monitor database access
-
Use clustering with PM2
pm2 start server.js -i max
-
Enable gzip compression
const compression = require('compression'); app.use(compression());
-
Implement caching
- Cache frequently accessed data
- Use Redis for session storage
-
Create indexes
ticketSchema.index({ ticketId: 1 }); ticketSchema.index({ status: 1, createdAt: -1 });
-
Use connection pooling
mongoose.connect(uri, { poolSize: 10, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000 });
-
Load Balancer
- Use Nginx as load balancer
- Distribute traffic across multiple instances
-
Session Storage
- Use Redis for session storage
- Share sessions across instances
-
Database
- Use MongoDB replica sets
- Consider sharding for large datasets
-
Increase server resources
- More CPU cores
- More RAM
- Faster storage (SSD)
- Check logs:
pm2 logs nexus - Verify environment variables
- Check MongoDB connection
- Verify port availability
- Verify MongoDB URI
- Check firewall rules
- Verify MongoDB is running
- Check authentication credentials
- Verify webhook URL is accessible
- Check webhook secret
- Review GitHub webhook delivery logs
- Check server logs
- Verify domain DNS configuration
- Check certificate expiration
- Renew certificate if needed
- Verify Nginx configuration
-
Update GitHub Webhooks
- Change webhook URL to production domain
- Update webhook secret if changed
-
Test All Functionality
- Create test ticket
- Test GitHub sync
- Test authentication
- Test webhook processing
-
Set Up Monitoring
- Configure alerts
- Set up log aggregation
- Enable performance monitoring
-
Document Deployment
- Record deployment steps
- Document configuration
- Update team documentation
- Weekly: Review logs for errors
- Monthly: Update dependencies
- Monthly: Review and rotate secrets
- Quarterly: Review backup strategy
- Quarterly: Security audit
- Test updates in staging
- Create backup before update
- Deploy updates during low-traffic periods
- Monitor after deployment
- Roll back if issues occur
For deployment issues:
- Check platform-specific documentation
- Review troubleshooting guide
- Contact support team
- Check GitHub issues