EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
Quick Start: Deploy to DigitalOcean + Cloudflare

This guide will get demo.everydayoffice.au live in ~15 minutes.

Prerequisites

  • ✅ DigitalOcean API token (in .env)
  • ✅ Cloudflare API key (in .env)
  • ✅ Managed PostgreSQL database (provisioned)
  • ✅ Database migrations applied
  • ✅ Root tenant/admin initialized

Step 1: Provision Droplet (2 minutes)

cd devops/digitalocean
./provision_droplet.sh

Output: Droplet IP address (save this!)

Wait 2-3 minutes for cloud-init to finish installing Node.js, NGINX, etc.

Step 2: Add Droplet to Database Firewall (30 seconds)

# The provision script outputs this command - copy and run it:
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

Step 3: SSH into Droplet

ssh root@<DROPLET_IP>

Step 4: Create Environment Files on Droplet

# Create backend .env
mkdir -p /opt/apps && cd /opt/apps
git clone https://github.com/dablackfox/IBG_HUB.git
cd IBG_HUB/rmm-psa-platform/backend
cat > .env <<'ENV'
DATABASE_URL=postgresql://doadmin:AVNS_J8RJAmsEwsHFG52_-F2@rmm-psa-db-do-user-28531160-0.i.db.ondigitalocean.com:25060/defaultdb
JWT_SECRET=aFzl7P9UDEgc2hK7xLXGVj5tI1vTDsyRXSOEdBj55wA=
PORT=3000
ENV

Step 5: Deploy Application (3 minutes)

cd /opt/apps/IBG_HUB/rmm-psa-platform/devops/digitalocean
chmod +x deploy_to_droplet.sh
./deploy_to_droplet.sh

This will:

  • Install backend dependencies
  • Start backend with PM2
  • Build dashboard (static files)
  • Configure NGINX

Test locally:

curl http://localhost:3000/ # Backend health
curl http://localhost/ # Dashboard

Step 6: Setup Cloudflare Tunnel (5 minutes)

Still on the droplet:

# Authenticate Cloudflare
cloudflared tunnel login
# This will print a URL - open it in your browser and authorize
# Create tunnel
cloudflared tunnel create rmm-psa-demo
# Configure tunnel
mkdir -p /etc/cloudflared
cat > /etc/cloudflared/config.yml <<'TUNNEL'
tunnel: rmm-psa-demo
credentials-file: /root/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: demo.everydayoffice.au
service: http://localhost:80
- service: http_status:404
TUNNEL
# Get tunnel ID
TUNNEL_ID=$(cloudflared tunnel list | grep rmm-psa-demo | awk '{print $1}')
echo "Tunnel ID: $TUNNEL_ID"
# Update config with actual tunnel ID
sed -i "s/<TUNNEL_ID>/$TUNNEL_ID/g" /etc/cloudflared/config.yml
# Install as system service
cloudflared service install
systemctl enable cloudflared
systemctl start cloudflared
systemctl status cloudflared

Step 7: Create DNS Record (1 minute)

Back on your local machine:

cd /home/cw/Documents/IBG_HUB/rmm-psa-platform/devops/cloudflare
# Get tunnel CNAME from droplet
ssh root@<DROPLET_IP> "cloudflared tunnel list | grep rmm-psa-demo | awk '{print \$4}'"
# Example output: abc123.cfargotunnel.com
# Create DNS record
./create_dns_for_demo.sh <TUNNEL_CNAME>
# Example: ./create_dns_for_demo.sh abc123.cfargotunnel.com

Step 8: Test!

Wait 1-2 minutes for DNS propagation, then:

curl https://demo.everydayoffice.au/

Open in browser:

Login with:

Troubleshooting

Backend not starting

pm2 logs rmm-backend

Dashboard 404

ls -la /opt/apps/IBG_HUB/rmm-psa-platform/dashboard/dist/
nginx -t

Tunnel not routing

systemctl status cloudflared
journalctl -u cloudflared -f

Database connection error

# Test from droplet
curl https://api.digitalocean.com/v2/databases/655f5c3e-190c-4229-a5df-61978ff5236d/firewall \
-H "Authorization: Bearer $DO_API_TOKEN"
# Ensure droplet IP is in trusted_sources

Ongoing Maintenance

Auto-updates (already configured)

systemctl status rmm-auto-update.timer

Manual update

cd /opt/apps/IBG_HUB/rmm-psa-platform
git pull
cd backend && npm install --production && pm2 restart rmm-backend
cd ../dashboard && npm install && npm run build

View logs

pm2 logs rmm-backend # Backend logs
tail -f /var/log/nginx/access.log # NGINX access
tail -f /var/log/nginx/error.log # NGINX errors

Backup database

# DigitalOcean automatically backs up managed databases daily
# Manual export:
pg_dump "postgresql://doadmin:AVNS_J8RJAmsEwsHFG52_-F2@rmm-psa-db-do-user-28531160-0.i.db.ondigitalocean.com:25060/defaultdb?sslmode=require" > backup.sql

Cost Summary

  • Droplet (1GB): $6/month
  • Managed PostgreSQL (1GB): $15/month
  • Total: $21/month

Security Notes

  • ✅ Cloudflare proxy hides origin IP
  • ✅ Database firewall (droplet IP only)
  • ✅ UFW firewall on droplet
  • ✅ SSL via Cloudflare
  • ⚠️ Consider adding fail2ban for SSH protection
  • ⚠️ Enable unattended-upgrades for security patches