Architecture Decision
We'll use a simple single-server deployment to get you up and running quickly:
Option A: Single DigitalOcean Droplet (Recommended for MVP)
- Backend: Node.js API on port 3000
- Dashboard: Built static files served by NGINX on port 80/443
- Tunnel: Cloudflare Tunnel to expose both securely
- Database: Already provisioned Managed PostgreSQL
Pros:
- Simple to manage
- Low cost ($6/month droplet + $15/month DB)
- Fast to deploy
- Easy to monitor
Cons:
- Single point of failure
- Coupled scaling
Option B: Separate Deployments (Future upgrade)
- Backend on DO App Platform ($5/month)
- Dashboard on Cloudflare Pages (free)
- More scalable but more complex
Deployment Steps (Option A - Single Droplet)
1. Provision DigitalOcean Droplet
# Create Ubuntu 22.04 droplet (Basic, 1GB RAM, $6/mo)
# Region: Sydney (syd1) - same as database
# Enable monitoring
# Add SSH key
2. Initial Server Setup
# Update system
apt update && apt upgrade -y
# Install Node.js 20.x
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
# Install NGINX
apt install -y nginx
# Install git
apt install -y git
# Install cloudflared for Cloudflare Tunnel
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
dpkg -i cloudflared.deb
3. Clone Repository
cd /opt
git clone https://github.com/dablackfox/IBG_HUB.git
cd IBG_HUB/rmm-psa-platform
4. Setup Backend
cd backend
npm install --production
cp .env.example .env
# Edit .env with production values (DATABASE_URL, JWT_SECRET)
# Use PM2 to manage Node process
npm install -g pm2
pm2 start index.js --name rmm-backend
pm2 startup
pm2 save
5. Build Dashboard
cd ../dashboard
npm install
npm run build
# This creates dashboard/dist/ with static files
6. Configure NGINX
server {
listen 80;
server_name localhost;
# Dashboard (React app)
location / {
root /opt/IBG_HUB/rmm-psa-platform/dashboard/dist;
try_files $uri $uri/ /index.html;
}
# Backend API
location /api {
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_cache_bypass $http_upgrade;
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;
}
}
7. Setup Cloudflare Tunnel
# Authenticate
cloudflared tunnel login
# Create tunnel
cloudflared tunnel create rmm-psa-demo
# Configure tunnel (see cloudflare/cloudflare_tunnel_setup.md)
# Route demo.everydayoffice.au to http://localhost:80
# Install as service
cloudflared service install
systemctl enable cloudflared
systemctl start cloudflared
8. Add DB Firewall Rule
# Get droplet IP
DROPLET_IP=$(curl -s ifconfig.me)
# Add to DB trusted sources
curl -X PUT -H "Authorization: Bearer $DO_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"trusted_sources\":[{\"type\":\"ip_addr\",\"source\":\"$DROPLET_IP\"}]}" \
https://api.digitalocean.com/v2/databases/655f5c3e-190c-4229-a5df-61978ff5236d/firewall
9. Setup Auto-Update
# Install the auto-update timer we created
cd /opt/IBG_HUB/rmm-psa-platform/devops/auto-update
chmod +x install_auto_update.sh
./install_auto_update.sh
10. Test
Environment Variables Needed on Server
backend/.env
# From devops/digitalocean/db_credentials.txt
DATABASE_URL=postgresql://doadmin:AVNS_J8RJAmsEwsHFG52_-F2@rmm-psa-db-do-user-28531160-0.i.db.ondigitalocean.com:25060/defaultdb
# From backend/.env (local)
JWT_SECRET=aFzl7P9UDEgc2hK7xLXGVj5tI1vTDsyRXSOEdBj55wA=
# Port
PORT=3000
dashboard/.env (build time)
VITE_API_URL=https://demo.everydayoffice.au/api
Security Checklist
- Database firewall (trusted sources only)
- SSH key-only authentication
- UFW firewall (allow 80, 443, SSH only)
- Regular security updates (unattended-upgrades)
- Cloudflare proxy enabled (hides origin IP)
- JWT secret rotation implemented
Monitoring
- PM2 dashboard: pm2 monit
- NGINX logs: /var/log/nginx/access.log
- Backend logs: pm2 logs rmm-backend
- Database metrics: DigitalOcean dashboard
Estimated Costs (Monthly)
- Droplet (Basic, 1GB): $6
- Managed PostgreSQL (1GB): $15
- Total: $21/month
Next Steps
- Create DO droplet
- Run provisioning script
- Setup Cloudflare Tunnel
- Point DNS
- Test end-to-end