EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
DigitalOcean WordPress Hosting Architecture

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:

-- collegeo_user can ONLY access collegeo_wp
GRANT ALL PRIVILEGES ON collegeo_wp.* TO 'collegeo_user'@'%';
-- If hacker gets collegeo credentials, they cannot:
SELECT * FROM coomerawaters_wp.wp_posts; -- ❌ Access denied
DROP DATABASE corne582_wp; -- ❌ Access denied

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:

  1. Customer uploads image in WordPress admin
  2. WP Offload Media plugin intercepts the upload
  3. Image saved to DigitalOcean Spaces (S3-compatible object storage)
  4. WordPress URL rewritten to point to Spaces CDN
  5. 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?