Security & Isolation Model
Database Security ✅
Your Concern: "Can we separate the database so specific apps only have access to specific prefixes to prevent one getting hacked all the rest becoming encrypted?"
Solution: Each site gets its own isolated database with unique credentials:
MySQL Cluster: wordpress-mysql-cluster ($15/month)
├── collegeo_wp → collegeo_user (password1) ← Only collegeo app has these credentials
├── coomerawaters_wp → coomerawaters_user (password2) ← Only coomerawaters app
├── corne582_wp → corne582_user (password3) ← Only corne582 app
└── ... (13 more isolated databases)
Security Features:
- ✅ Each WordPress site has different database credentials
- ✅ MySQL user has GRANT permissions ONLY on their database
- ✅ If one site is hacked, attacker cannot access other databases
- ✅ Each app has unique DB_USER and DB_PASSWORD environment variables
- ✅ Credentials stored as encrypted secrets in App Platform
Example:
GRANT ALL PRIVILEGES ON collegeo_wp.* TO 'collegeo_user'@'%';
SELECT * FROM coomerawaters_wp.wp_posts;
DROP DATABASE corne582_wp;
App Platform Storage Limitations
Your Question: "Can the app itself not host the DB?"
Answer: ❌ No - App Platform containers are ephemeral (stateless).
What "ephemeral" means:
- Container restarts on every deployment (code updates)
- Container can restart at any time (load balancing, maintenance)
- All local files are deleted when container restarts
- This is why we need external storage
Image Upload Solution
Your Question: "What if the customer logs into WordPress and uploads images. Where are they saved?"
Problem:
Customer uploads logo.jpg → Saved to /wp-content/uploads/
→ App redeploys
→ logo.jpg is GONE! ❌
Solution: DigitalOcean Spaces + WP Offload Media Plugin
How It Works:
- Customer uploads image in WordPress admin
- WP Offload Media plugin intercepts the upload
- Image saved to DigitalOcean Spaces (S3-compatible object storage)
- WordPress URL rewritten to point to Spaces CDN
- Image persists forever, even when app restarts
Customer uploads:
logo.jpg → WordPress /wp-content/uploads/2026/02/logo.jpg
→ Plugin uploads to Spaces: ibg-wordpress-media/collegeo/2026/02/logo.jpg
→ Serves from CDN: https://ibg-wordpress-media.syd1.digitaloceanspaces.com/collegeo/2026/02/logo.jpg
→ ✅ Permanent storage!
Spaces Folder Structure:
ibg-wordpress-media/
├── collegeo/
│ └── 2026/02/logo.jpg
├── coomerawaters/
│ └── 2026/01/banner.png
├── corne582/
│ └── 2025/12/product.jpg
└── ... (each site isolated)
Cost: $5/month for 250GB storage + bandwidth
Complete Architecture Diagram
┌─────────────────────────────────────────────────────────────┐
│ Customer │
└─────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ DNS (domain.com) │
│ └─> Points to App Platform URL │
└─────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ App Platform (16 separate apps - $5/month each) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ wordpress-collegeo │ │
│ │ Environment Variables: │ │
│ │ DB_NAME=collegeo_wp │ │
│ │ DB_USER=collegeo_user │ │
│ │ DB_PASSWORD=secret1 (encrypted) │ │
│ │ SPACES_ACCESS_KEY=xxx │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ wordpress-coomerawaters │ │
│ │ Environment Variables: │ │
│ │ DB_NAME=coomerawaters_wp │ │
│ │ DB_USER=coomerawaters_user │ │
│ │ DB_PASSWORD=secret2 (encrypted) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ... (14 more apps) │
└─────────────┬───────────────────────┬───────────────────────┘
│ │
│ Database Queries │ Upload Images
▼ ▼
┌─────────────────────────┐ ┌───────────────────────────┐
│ MySQL Cluster │ │ Spaces Object Storage │
│ ($15/month) │ │ ($5/month) │
│ ┌───────────────────┐ │ │ ┌─────────────────────┐ │
│ │ collegeo_wp │ │ │ │ collegeo/ │ │
│ │ (only collegeo_ │ │ │ │ uploads/ │ │
│ │ user can access) │ │ │ │ 2026/02/ │ │
│ └───────────────────┘ │ │ └─────────────────────┘ │
│ ┌───────────────────┐ │ │ ┌─────────────────────┐ │
│ │ coomerawaters_wp │ │ │ │ coomerawaters/ │ │
│ │ (isolated) │ │ │ │ uploads/ │ │
│ └───────────────────┘ │ │ └─────────────────────┘ │
│ ... (14 more DBs) │ │ ... (14 more folders) │
└─────────────────────────┘ └───────────────────────────┘
Security Benefits Summary
| Concern | Solution | Cost |
| Database isolation | 16 separate DBs with unique credentials | $15/month (1 cluster) |
| Prevent cross-site access | MySQL GRANT permissions per user | Included |
| Ephemeral container storage | DigitalOcean Spaces for uploads | $5/month |
| Customer separation | 16 separate App Platform apps | $80/month ($5 each) |
| SSL certificates | Auto-provisioned Let's Encrypt | Free |
| Auto-scaling | Built into App Platform | Free |
| GitHub auto-deploy | Built into App Platform | Free |
Total Cost: ~$100/month Total Revenue (16 sites × $12): $192/month Profit: $92/month
Manual Setup Required
1. Install DigitalOcean CLI
# macOS
brew install doctl
# Linux
cd ~
wget https://github.com/digitalocean/doctl/releases/download/v1.94.0/doctl-1.94.0-linux-amd64.tar.gz
tar xf doctl-1.94.0-linux-amd64.tar.gz
sudo mv doctl /usr/local/bin
# Authenticate
doctl auth init
2. Run Deployment Script
cd /home/cw/Documents/IBG_HUB/rmm-psa-backend
./migration-scripts/deploy_to_digitalocean.sh
3. After Deployment: Install WP Offload Media Plugin
For each site, SSH into the server or use WP-CLI:
# Install plugin via WP-CLI
wp plugin install amazon-s3-and-cloudfront --activate
# Or install via WordPress admin:
# 1. Login to WordPress admin
# 2. Plugins → Add New
# 3. Search "WP Offload Media Lite"
# 4. Install and activate
# 5. Settings → Offload Media → Configure Spaces credentials
Alternative: Self-Hosted Option (Cheaper but Less Secure)
If $100/month is too expensive, you could use a single Droplet:
$24/month Droplet with WordOps:
- All 16 sites on one server
- MySQL on same server (less secure if one site is hacked, attacker has root access)
- Still need Spaces for media ($5/month)
- Total: $29/month
- Profit: $163/month
Trade-offs:
- ❌ Less isolation (all sites on same server)
- ❌ Shared resources (one slow site affects others)
- ❌ Manual server management required
- ❌ No auto-scaling
- ✅ Much cheaper
- ✅ More control
Would you like me to create a WordOps deployment script instead?