Control Center Setup
Step-by-step guide for installing and deploying the UniPulse Control Center on a VPS.
Prerequisites
| Requirement | Version | Purpose |
|---|---|---|
| Node.js | >= 20 | Runtime |
| PM2 | Latest | Process manager (npm install -g pm2) |
| Nginx | Latest | Reverse proxy with SSL |
| Git | Latest | Source control |
Installation
1. Clone and Setup
cd UniPulse-Control-Center
./setup.sh
The setup.sh script performs:
| Step | Action |
|---|---|
| 1 | Install npm dependencies |
| 2 | Build frontend (Vite) and backend (TypeScript) |
| 3 | Initialize SQLite database |
| 4 | Run Prisma migrations (creates 7 tables) |
| 5 | Configure PM2 process |
2. Configure Environment
cp apps/server/.env.example apps/server/.env
Edit the .env file:
| Variable | Required | Description | Example |
|---|---|---|---|
JWT_SECRET | Yes | JWT signing secret (min 32 chars) | your-cc-jwt-secret-min-32-chars |
JWT_REFRESH_SECRET | Yes | Refresh token secret | your-cc-refresh-secret |
GOOGLE_CLIENT_ID | Yes | Google OAuth client ID | 123456.apps.googleusercontent.com |
GOOGLE_CLIENT_SECRET | Yes | Google OAuth client secret | GOCSPX-xxxxx |
GITHUB_TOKEN | For CI/CD | GitHub personal access token (repo scope) | ghp_xxxxxxxxxxxx |
ALLOWED_EMAILS | Yes | Comma-separated whitelist of authorized emails | admin@example.com,dev@example.com |
PORT | No | Server port (default: 3001) | 3001 |
DATABASE_URL | No | SQLite path (default: file:./dev.db) | file:./prod.db |
ALLOWED_EMAILS
This is a critical security control. Only listed emails can access the Control Center. Make sure this is set correctly before starting the application.
3. Start with PM2
pm2 start ecosystem.config.js
PM2 Configuration:
// ecosystem.config.js
module.exports = {
apps: [{
name: 'control-center',
script: './apps/server/dist/index.js',
max_memory_restart: '500M', // Restart if memory exceeds 500MB
max_restarts: 10, // Max restart attempts
log_type: 'json', // Structured JSON logging
env: {
NODE_ENV: 'production',
PORT: 3001,
},
}],
};
4. Configure Nginx
# Copy the Nginx config
cp nginx/control-center.conf /etc/nginx/sites-available/control-center
ln -s /etc/nginx/sites-available/control-center /etc/nginx/sites-enabled/
# Test configuration
nginx -t
# Reload Nginx
systemctl reload nginx
The Nginx config provides:
| Feature | Configuration |
|---|---|
| SSL | Let's Encrypt certificates |
| Rate limiting (auth) | 5 requests/second |
| Rate limiting (API) | 30 requests/second |
| WebSocket proxy | Socket.IO /socket.io/ path |
| Security headers | X-Frame-Options, CSP, HSTS |
.env blocking | Deny access to .env files |
5. Generate SSL Certificate
certbot certonly --webroot -w /var/www/certbot -d ops.unipulse.tech
PM2 Management Commands
# View running processes
pm2 list
# View logs (real-time)
pm2 logs control-center
# View last 100 log lines
pm2 logs control-center --lines 100
# Restart
pm2 restart control-center
# Stop
pm2 stop control-center
# Monitor (interactive dashboard)
pm2 monit
# Save process list for auto-start on reboot
pm2 save
pm2 startup
Deployment (Updates)
cd UniPulse-Control-Center
./deploy.sh
deploy.sh performs:
| Step | Command |
|---|---|
| 1 | git pull origin main |
| 2 | npm install |
| 3 | npm run build |
| 4 | npx prisma migrate deploy (if schema changed) |
| 5 | pm2 restart ecosystem.config.js |
Verification
After setup or deployment, verify everything is working:
| Check | Command / URL | Expected |
|---|---|---|
| PM2 process | pm2 list | control-center status "online" |
| API health | curl http://localhost:3001/api/health | 200 OK |
| Nginx proxy | curl https://ops.unipulse.tech | Frontend loads |
| WebSocket | Browser console -- no WS errors | Socket connects |
| Docker access | Docker Manager page | Containers listed |
| VPS metrics | VPS Monitor page | Live charts updating |
| GitHub | PR Tracking page | PRs listed (if GITHUB_TOKEN set) |
| Login | Login page | Google OAuth works |
Troubleshooting
| Issue | Solution |
|---|---|
| PM2 process keeps restarting | Check logs: pm2 logs control-center |
| WebSocket connection failed | Verify Nginx WebSocket proxy config |
| Google OAuth redirect error | Check GOOGLE_CLIENT_ID and callback URL |
| Docker containers not listed | Ensure the PM2 process user has Docker socket access |
| SQLite lock errors | Only one instance should run at a time |
| 502 Bad Gateway | PM2 process not running or wrong port |
Cross-Reference
- Control Center Architecture -- tech stack and models
- VPS Monitoring -- metrics system
- Docker Management -- container operations
- CI/CD -- GitHub integration setup
- Nginx -- Nginx configuration details
- Deployment -- overall deployment strategy