From 9cf48258360fc3e57554d0f5524e067e6a33d06f Mon Sep 17 00:00:00 2001 From: Thomas Scott Date: Wed, 17 Dec 2025 12:05:05 +0000 Subject: [PATCH] Add PM2_GUIDE.md Signed-off-by: Thomas Scott --- PM2_GUIDE.md | 636 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 636 insertions(+) create mode 100644 PM2_GUIDE.md diff --git a/PM2_GUIDE.md b/PM2_GUIDE.md new file mode 100644 index 0000000..4fb5be8 --- /dev/null +++ b/PM2_GUIDE.md @@ -0,0 +1,636 @@ +# PM2 Management Guide + +Complete guide for managing the Redmine-Gitea Sync Server with PM2. + +## Quick Start + +### Install PM2 +```bash +npm install -g pm2 +``` + +### Start Application +```bash +pm2 start ecosystem.config.cjs +pm2 save +pm2 startup +``` + +## Essential Commands + +### Process Management + +```bash +# Start the application +pm2 start ecosystem.config.cjs + +# Start in development mode +pm2 start ecosystem.config.cjs --env development + +# Stop the application +pm2 stop redmine-gitea-sync + +# Restart the application +pm2 restart redmine-gitea-sync + +# Reload with zero downtime (cluster mode) +pm2 reload redmine-gitea-sync + +# Delete from PM2 +pm2 delete redmine-gitea-sync + +# Update environment variables and restart +pm2 restart redmine-gitea-sync --update-env +``` + +### Monitoring + +```bash +# List all processes +pm2 list +pm2 ls + +# Show detailed information +pm2 show redmine-gitea-sync + +# Monitor in real-time +pm2 monit + +# View resource usage +pm2 status +``` + +### Log Management + +```bash +# View logs in real-time +pm2 logs redmine-gitea-sync + +# View last 100 lines +pm2 logs redmine-gitea-sync --lines 100 + +# View only errors +pm2 logs redmine-gitea-sync --err + +# View only output +pm2 logs redmine-gitea-sync --out + +# Clear logs +pm2 flush + +# Follow logs with grep +pm2 logs redmine-gitea-sync | grep ERROR +``` + +### Save and Restore + +```bash +# Save current process list +pm2 save + +# Resurrect saved process list +pm2 resurrect + +# Clear saved process list +pm2 cleardump +``` + +## Configuration + +### Ecosystem File + +The `ecosystem.config.cjs` file contains all configuration: + +```javascript +module.exports = { + apps: [{ + name: 'redmine-gitea-sync', + script: './server.mjs', + env: { + // Your environment variables + }, + instances: 1, + exec_mode: 'fork', + max_memory_restart: '300M', + // ... other settings + }] +}; +``` + +### Update Configuration + +1. Edit `ecosystem.config.cjs` +2. Restart with updated environment: + ```bash + pm2 restart redmine-gitea-sync --update-env + ``` + +### Multiple Environments + +```javascript +// ecosystem.config.cjs +module.exports = { + apps: [{ + name: 'redmine-gitea-sync', + script: './server.mjs', + env: { + NODE_ENV: 'production', + PORT: 3002, + }, + env_development: { + NODE_ENV: 'development', + PORT: 3002, + LOG_LEVEL: 'debug', + }, + env_staging: { + NODE_ENV: 'staging', + PORT: 3003, + } + }] +}; +``` + +Start with specific environment: +```bash +pm2 start ecosystem.config.cjs --env development +pm2 start ecosystem.config.cjs --env staging +``` + +## Auto-Start on Boot + +### Setup Startup Script + +```bash +# Generate startup script for your system +pm2 startup + +# This will output a command like: +# sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u yourusername --hp /home/yourusername + +# Run the command it outputs +sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u yourusername --hp /home/yourusername + +# Save your process list +pm2 save +``` + +### Disable Startup + +```bash +pm2 unstartup +``` + +## Clustering + +For high-traffic scenarios, use cluster mode: + +### Update ecosystem.config.cjs + +```javascript +module.exports = { + apps: [{ + name: 'redmine-gitea-sync', + script: './server.mjs', + instances: 'max', // or specific number like 4 + exec_mode: 'cluster', + // ... other settings + }] +}; +``` + +### Commands + +```bash +# Start in cluster mode +pm2 start ecosystem.config.cjs + +# Scale up/down +pm2 scale redmine-gitea-sync +2 # Add 2 instances +pm2 scale redmine-gitea-sync 4 # Set to 4 instances + +# Reload with zero downtime +pm2 reload redmine-gitea-sync +``` + +## Log Rotation + +### Install PM2 Log Rotate Module + +```bash +pm2 install pm2-logrotate +``` + +### Configure Log Rotation + +```bash +# Set max file size (default: 10MB) +pm2 set pm2-logrotate:max_size 10M + +# Set number of files to keep (default: 10) +pm2 set pm2-logrotate:retain 7 + +# Enable compression +pm2 set pm2-logrotate:compress true + +# Set rotation interval (daily/hourly) +pm2 set pm2-logrotate:rotateInterval '0 0 * * *' # Daily at midnight + +# View configuration +pm2 conf pm2-logrotate +``` + +## Monitoring and Metrics + +### PM2 Plus (Optional) + +PM2 Plus provides advanced monitoring: + +```bash +# Link to PM2 Plus +pm2 link + +# Unlink +pm2 unlink +``` + +### Custom Metrics + +Add to your application: + +```javascript +const pmx = require('pmx'); + +// Custom metric +const metric = pmx.probe().metric({ + name: 'Sync Operations', + value: 0 +}); + +// Increment +metric.set(metric.val() + 1); +``` + +### System Monitoring + +```bash +# Install system monitoring module +pm2 install pm2-server-monit + +# View dashboard +# Access via http://localhost:9615 +``` + +## Troubleshooting + +### Process Keeps Restarting + +```bash +# Check error logs +pm2 logs redmine-gitea-sync --err + +# View restart count +pm2 list + +# Increase restart delay in ecosystem.config.cjs +restart_delay: 5000, +max_restarts: 5, +``` + +### High Memory Usage + +```bash +# Check memory +pm2 list +pm2 monit + +# View detailed info +pm2 show redmine-gitea-sync + +# Adjust memory limit in ecosystem.config.cjs +max_memory_restart: '500M', +``` + +### Application Not Starting + +```bash +# Check if port is in use +sudo lsof -i :3002 + +# Check logs for errors +pm2 logs redmine-gitea-sync --err --lines 50 + +# Try starting manually to see errors +node server.js +``` + +### PM2 Not Starting on Boot + +```bash +# Verify startup is configured +pm2 startup + +# Check systemd status +systemctl status pm2-yourusername + +# Regenerate startup script +pm2 unstartup +pm2 startup +pm2 save +``` + +### Logs Not Appearing + +```bash +# Check log file locations +pm2 show redmine-gitea-sync + +# Verify log directory exists and is writable +ls -la ./logs/ + +# Create logs directory if missing +mkdir -p ./logs + +# Restart application +pm2 restart redmine-gitea-sync +``` + +## Advanced Usage + +### Watch Mode + +Monitor file changes and auto-restart: + +```javascript +// ecosystem.config.cjs +watch: true, +watch_delay: 1000, +ignore_watch: ['node_modules', 'logs', '.git'], +``` + +Or from command line: +```bash +pm2 start ecosystem.config.cjs --watch +``` + +### Cron Restart + +Restart at specific intervals: + +```javascript +// ecosystem.config.cjs +cron_restart: '0 3 * * *', // Every day at 3 AM +``` + +### Max Restarts + +Limit restart attempts: + +```javascript +// ecosystem.config.cjs +max_restarts: 10, +min_uptime: '10s', +``` + +### Environment-Specific Commands + +```bash +# Production +pm2 start ecosystem.config.cjs --env production + +# Development +pm2 start ecosystem.config.cjs --env development + +# Staging +pm2 start ecosystem.config.cjs --env staging +``` + +## PM2 Runtime Configuration + +### Update PM2 + +```bash +# Update PM2 to latest version +npm install -g pm2@latest + +# Update in-memory PM2 +pm2 update +``` + +### PM2 Home Directory + +By default: `~/.pm2` + +Change location: +```bash +export PM2_HOME=/path/to/custom/location +``` + +### Reset PM2 + +```bash +# Kill PM2 daemon +pm2 kill + +# Clear everything +rm -rf ~/.pm2 + +# Restart PM2 +pm2 start ecosystem.config.cjs +``` + +## Integration with CI/CD + +### Deploy Script Example + +```bash +#!/bin/bash + +# Pull latest code +git pull origin main + +# Install dependencies +npm install --production + +# Restart with zero downtime +pm2 reload ecosystem.config.cjs + +# Check if running +pm2 list +``` + +### GitHub Actions Example + +```yaml +name: Deploy + +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.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.SSH_KEY }} + script: | + cd /opt/redmine-gitea-sync + git pull + npm install --production + pm2 reload ecosystem.config.cjs +``` + +## Performance Tuning + +### Node.js Options + +```javascript +// ecosystem.config.cjs +node_args: '--max-old-space-size=2048', +``` + +### Increase File Descriptors + +```bash +# Check current limit +ulimit -n + +# Increase limit (temporary) +ulimit -n 10000 + +# Permanent: Edit /etc/security/limits.conf +* soft nofile 10000 +* hard nofile 10000 +``` + +### Process Priority + +```bash +# Start with higher priority (lower nice value) +pm2 start ecosystem.config.cjs --node-args="--nice=-10" +``` + +## Backup and Restore + +### Backup PM2 Configuration + +```bash +# Backup process list +pm2 save + +# Backup ecosystem file +cp ecosystem.config.cjs ecosystem.config.cjs.backup + +# Backup PM2 directory +tar -czf pm2-backup.tar.gz ~/.pm2 +``` + +### Restore + +```bash +# Restore PM2 directory +tar -xzf pm2-backup.tar.gz -C ~/ + +# Resurrect processes +pm2 resurrect +``` + +## Security Best Practices + +### Run as Dedicated User + +```bash +# Create user +sudo useradd -r -s /bin/false pm2user + +# Set ownership +sudo chown -R pm2user:pm2user /opt/redmine-gitea-sync + +# Run PM2 as user +sudo su - pm2user -s /bin/bash -c "pm2 start /opt/redmine-gitea-sync/ecosystem.config.cjs" +sudo su - pm2user -s /bin/bash -c "pm2 save" + +# Setup startup as that user +sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u pm2user --hp /home/pm2user +``` + +### Secure Environment Variables + +Never commit sensitive data to version control: + +```bash +# Protect ecosystem file +chmod 600 ecosystem.config.cjs + +# Use external .env file +# In ecosystem.config.cjs: +require('dotenv').config(); + +env: { + REDMINE_API_KEY: process.env.REDMINE_API_KEY, + GITEA_TOKEN: process.env.GITEA_TOKEN, +} +``` + +## Quick Reference + +### Most Common Commands + +```bash +# Start +pm2 start ecosystem.config.cjs + +# Status +pm2 list + +# Logs +pm2 logs + +# Restart +pm2 restart redmine-gitea-sync + +# Stop +pm2 stop redmine-gitea-sync + +# Monitor +pm2 monit + +# Save +pm2 save +``` + +### Useful Aliases + +Add to `~/.bashrc`: + +```bash +alias pm2-status='pm2 list' +alias pm2-logs='pm2 logs redmine-gitea-sync' +alias pm2-restart='pm2 restart redmine-gitea-sync' +alias pm2-sync='cd /opt/redmine-gitea-sync && pm2 logs redmine-gitea-sync' +``` + +## Additional Resources + +- [PM2 Official Documentation](https://pm2.keymetrics.io/) +- [PM2 GitHub Repository](https://github.com/Unitech/pm2) +- [PM2 Plus (Monitoring)](https://pm2.io/) +- [PM2 Cheat Sheet](https://pm2.keymetrics.io/docs/usage/quick-start/) + +## Support + +For PM2-specific issues: +- Check PM2 logs: `pm2 logs` +- Consult PM2 documentation +- Search PM2 GitHub issues + +For application issues: +- Check application logs: `pm2 logs redmine-gitea-sync` +- Review main documentation +- Check server health: `curl http://localhost:3002/health` \ No newline at end of file