EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
DigitalOcean Spaces CDN Setup Guide

Overview

DigitalOcean Spaces provides S3-compatible object storage with integrated CDN. This guide will help you set up and configure Spaces for WordPress static assets.

Prerequisites

  • DigitalOcean account with Spaces enabled
  • Access to DigitalOcean API token
  • WordPress sites on DO App Platform

Step 1: Create or Verify Spaces Bucket

Via DigitalOcean Console

  1. Go to DigitalOcean Spaces
  2. Check if bucket exists (user mentioned "it's empty")
  3. Note the bucket name and region
  4. Enable CDN if not already enabled

Via doctl CLI

# List existing spaces (requires doctl authentication)
doctl spaces list-buckets
# Create a new space if needed
doctl spaces create wordpress-assets --region nyc3
# Enable CDN
doctl spaces cdn enable wordpress-assets

Step 2: Install and Configure s3cmd

s3cmd is a command-line tool for managing S3-compatible storage.

Install s3cmd

# Fedora/RHEL
sudo dnf install s3cmd
# Ubuntu/Debian
sudo apt install s3cmd
# Or via pip
pip install s3cmd

Configure s3cmd for DigitalOcean Spaces

s3cmd --configure

Configuration values:

Access Key: [Your DO Spaces Access Key]
Secret Key: [Your DO Spaces Secret Key]
Default Region: nyc3 (or your region)
S3 Endpoint: nyc3.digitaloceanspaces.com (replace nyc3 with your region)
DNS-style bucket+hostname:port template: %(bucket)s.nyc3.digitaloceanspaces.com
Encryption password: [Leave empty or set password]
Path to GPG program: [Leave empty]
Use HTTPS protocol: Yes
HTTP Proxy server name: [Leave empty]

Test configuration:

s3cmd ls

Step 3: Create Spaces Access Keys

  1. Go to API Tokens
  2. Scroll to Spaces access keys
  3. Click Generate New Key
  4. Save the Access Key and Secret Key (shown only once!)

Step 4: Sync WordPress Assets to Spaces

Option A: Manual Sync with s3cmd

# Sync wp-content/uploads from a WordPress site
s3cmd sync /path/to/wordpress/wp-content/uploads/ s3://bucket-name/wp-content/uploads/
# Example for specific site
s3cmd sync ~/wordpress-sites/performwrite/wp-content/uploads/ s3://wordpress-assets/performwrite/uploads/
# Sync with public read permissions
s3cmd sync --acl-public /path/to/wordpress/wp-content/uploads/ s3://wordpress-assets/uploads/

Option B: Automated Sync Script

Create /home/cw/Documents/IBG_HUB/rmm-psa-devops/scripts/sync-wordpress-assets.sh:

#!/bin/bash
BUCKET="wordpress-assets"
REGION="nyc3"
declare -A sites=(
["performwritecom"]="/path/to/performwrite/wp-content/uploads"
["soilife"]="/path/to/soilife/wp-content/uploads"
# Add all 16 sites
)
for site in "${!sites[@]}"; do
echo "Syncing $site to Spaces..."
s3cmd sync --acl-public "${sites[$site]}/" "s3://$BUCKET/$site/uploads/"
done
echo "✅ All assets synced to DigitalOcean Spaces"

Step 5: Configure WordPress to Use CDN

Option 1: Using Environment Variables (Recommended)

Add to wp-config.php:

// CDN Configuration
if (getenv('DO_SPACES_BUCKET')) {
$cdn_endpoint = getenv('DO_SPACES_CDN_ENDPOINT');
define('WP_CONTENT_URL', $cdn_endpoint . '/wp-content');
define('UPLOADS', 'wp-content/uploads');
}

Set in DO App Platform environment variables:

Option 2: Hardcode in wp-config.php

// CDN Configuration - DigitalOcean Spaces
define('WP_CONTENT_URL', 'https://wordpress-assets.nyc3.cdn.digitaloceanspaces.com/performwrite/wp-content');
define('UPLOADS', 'wp-content/uploads');

Option 3: Use WordPress Plugin

WP Offload Media Lite (Supports DigitalOcean Spaces)

  1. Install plugin: wp plugin install amazon-s3-and-cloudfront --activate
  2. Go to Settings → Offload Media
  3. Choose "DigitalOcean Spaces"
  4. Enter:
    • Bucket: wordpress-assets
    • Region: nyc3
    • Access Key: [Your key]
    • Secret Key: [Your secret]
  5. Enable "Rewrite Media URLs" to use CDN

Step 6: Configure CORS (If Needed)

Create cors.xml:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Apply CORS:

s3cmd setcors cors.xml s3://wordpress-assets

Step 7: Set Cache-Control Headers

# Set cache headers for images (1 year)
s3cmd modify --recursive --add-header="Cache-Control:public, max-age=31536000" s3://wordpress-assets/
# For specific file types
s3cmd modify --recursive --add-header="Cache-Control:public, max-age=31536000" --include='*.jpg' s3://wordpress-assets/
s3cmd modify --recursive --add-header="Cache-Control:public, max-age=31536000" --include='*.png' s3://wordpress-assets/
s3cmd modify --recursive --add-header="Cache-Control:public, max-age=31536000" --include='*.gif' s3://wordpress-assets/

Step 8: Test CDN Delivery

  1. Upload a test image to WordPress
  2. Check if it's synced to Spaces
  3. Verify CDN URL is being used:
    curl -I https://wordpress-assets.nyc3.cdn.digitaloceanspaces.com/performwrite/uploads/test-image.jpg
  4. Confirm cache headers are present

WordPress to Spaces Migration Plan

For Each of 16 Sites:

  1. Identify uploads directory on current cPanel hosting
  2. Download/export all wp-content/uploads
  3. Upload to Spaces using s3cmd sync
  4. Update wp-config.php to use CDN URLs
  5. Test image loading
  6. Set up automatic sync for new uploads

Estimated Data:

Based on database sizes (soilife_wp is 339MB), uploads could be several GB per site.

# Example sync command
for site in performwrite soilife collegeo; do
s3cmd sync --acl-public /backup/wordpress/$site/uploads/ s3://wordpress-assets/$site/uploads/
done

Monitoring & Maintenance

Check Space Usage

# Via s3cmd
s3cmd du -H s3://wordpress-assets
# Via DO Console
# Go to Spaces → Click bucket → See usage stats

Automated Sync (Cron Job)

# Add to crontab
0 2 * * * /home/cw/Documents/IBG_HUB/rmm-psa-devops/scripts/sync-wordpress-assets.sh >> /var/log/spaces-sync.log 2>&1

Pricing Estimate

DigitalOcean Spaces pricing (as of 2026):

  • Storage: $5/month for 250GB
  • Transfer: $1/GB outbound (first 1TB free with $12/month plan)

For 16 WordPress sites with ~10GB average uploads:

  • Total storage: ~160GB
  • Cost: $5/month (within free tier)
  • Additional storage: $0.02/GB/month

Troubleshooting

Access Denied Errors

  • Check Spaces access keys are correct
  • Verify bucket permissions (should be public for CDN)
  • Confirm CORS is configured if using AJAX

Images Not Loading from CDN

  1. Check file exists: s3cmd ls s3://bucket-name/path/to/file.jpg
  2. Verify file is public: s3cmd info s3://bucket-name/path/to/file.jpg
  3. Check CDN endpoint is correct
  4. Clear browser cache

Sync Issues

  • Ensure s3cmd is configured correctly
  • Check network connectivity
  • Verify write permissions on local directories
  • Use --verbose flag for debugging: s3cmd sync --verbose ...

Security Best Practices

  1. Rotate access keys regularly
  2. Use bucket policies to restrict access
  3. Enable versioning for important assets
  4. Monitor usage to detect anomalies
  5. Use signed URLs for private content

Next Steps

  • Create or verify DO Spaces bucket
  • Install and configure s3cmd
  • Export WordPress uploads from cPanel
  • Sync assets to Spaces
  • Update wp-config.php files with CDN URLs
  • Test CDN delivery
  • Set up automatic sync
  • Monitor usage and performance

Resources


Last Updated: February 17, 2026