CloudPloy

WordPress on CloudPloy - Complete Guide

CloudPloy manages the entire WordPress hosting stack: the server, Docker container, Nginx web server, PHP-FPM process manager, MySQL database, and SSL certificate. You focus on your site's content, plugins, and customizations. This guide explains how CloudPloy handles WordPress and how to configure it correctly for production.

How CloudPloy Runs WordPress

When CloudPloy detects WordPress in a repository (via wp-config.php or wp-login.php), it uses the cloudploy/wordpress:6 Docker image which includes:

  • PHP-FPM 8.2 with WordPress-required extensions (mbstring, gd, curl, imagick, exif, mysqli)
  • WP-CLI pre-installed at /usr/local/bin/wp
  • Nginx configured with WordPress-specific rewrite rules
  • Automatic SSL via Let's Encrypt once a domain is attached

The wp-content/uploads/ directory is automatically mounted as a persistent volume so your media library survives deployments and server restarts.

wp-config.php Best Practices

Never hardcode database credentials or security keys in wp-config.php. Read them from environment variables instead. This lets you commit wp-config.php to your repository without exposing secrets:

define('DB_NAME',     getenv('DB_DATABASE'));
define('DB_USER',     getenv('DB_USERNAME'));
define('DB_PASSWORD', getenv('DB_PASSWORD'));
define('DB_HOST',     getenv('DB_HOST') ?: 'localhost');
define('DB_CHARSET',  'utf8mb4');
define('DB_COLLATE',  '');

define('AUTH_KEY',         getenv('WP_AUTH_KEY'));
define('SECURE_AUTH_KEY',  getenv('WP_SECURE_AUTH_KEY'));
define('LOGGED_IN_KEY',    getenv('WP_LOGGED_IN_KEY'));
define('NONCE_KEY',        getenv('WP_NONCE_KEY'));
define('AUTH_SALT',        getenv('WP_AUTH_SALT'));
define('SECURE_AUTH_SALT', getenv('WP_SECURE_AUTH_SALT'));
define('LOGGED_IN_SALT',   getenv('WP_LOGGED_IN_SALT'));
define('NONCE_SALT',       getenv('WP_NONCE_SALT'));

// Environment-specific settings
define('WP_DEBUG',     getenv('WP_DEBUG') === 'true');
define('WP_DEBUG_LOG', '/dev/stderr');  // Logs appear in App > Logs
define('WP_SITEURL',   getenv('WP_SITEURL') ?: 'https://example.com');
define('WP_HOME',      getenv('WP_HOME')    ?: 'https://example.com');

Generate security keys at api.wordpress.org/secret-key/1.1/salt/ and add them as environment variables in App > Settings > Environment Variables.

Environment Variables Reference

Variable Example Value Purpose
DB_HOST From CloudPloy database panel MySQL host (internal network address)
DB_DATABASE wordpress_prod Database name created in App > Databases
DB_USERNAME wp_user Database user (not root)
DB_PASSWORD Random 32-char string Never commit to repository
WP_SITEURL https://yoursite.com WordPress site URL (must match domain)
WP_HOME https://yoursite.com WordPress home URL
WP_DEBUG false in production Disables PHP error display
WP_AUTH_KEY (and 7 more salts) Random 64-char strings Security keys for cookies and sessions
REDIS_HOST From CloudPloy Redis panel Required if using Redis Object Cache plugin

Redis Object Cache

WordPress makes dozens of database queries per page load by default. Redis object caching stores query results in memory so repeated requests do not hit MySQL. This is the single highest-impact performance improvement for WordPress.

Add Redis from App > Add-ons > Redis, then install the Redis Object Cache plugin:

# In App > Terminal
wp plugin install redis-cache --activate

# Configure Redis connection
wp config set WP_REDIS_HOST "$REDIS_HOST"
wp config set WP_REDIS_PORT "6379"

# Enable the cache
wp redis enable

Verify Redis is connected:

wp redis status
# Should show: Status: Connected

Add to wp-config.php for the connection details:

define('WP_REDIS_HOST', getenv('REDIS_HOST') ?: '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_TIMEOUT', 1);
define('WP_REDIS_READ_TIMEOUT', 1);

WooCommerce Configuration

WooCommerce stores require additional performance considerations. The order table grows large, and cart/session data writes frequently.

Critical WooCommerce settings for CloudPloy:

Setting Recommended Why
PHP memory limit 256MB WooCommerce product imports need headroom
Cart fragments Disable via plugin Prevents cart AJAX from breaking full-page cache
WooCommerce sessions Database (default) Required for logged-out cart persistence
Order auto-complete Configure per business Virtual products can auto-complete; physical cannot
Stock management Enable CloudPloy's Redis cache handles the query load

Increase PHP memory for WooCommerce in your Dockerfile or a custom php.ini:

; docker/php.ini
memory_limit = 256M
max_execution_time = 300
upload_max_filesize = 64M
post_max_size = 64M

File Uploads and Media Library

CloudPloy automatically mounts wp-content/uploads/ as a persistent volume. Files uploaded through the WordPress media library, WooCommerce product images, and generated thumbnails all persist across deployments.

For high-traffic sites, offload media to object storage to reduce server load:

# Install WP Offload Media or similar plugin
wp plugin install amazon-s3-and-cloudfront --activate

# Configure S3 credentials via wp-config.php
define('AS3CF_SETTINGS', serialize(array(
    'provider' => 'aws',
    'access-key-id' => getenv('AWS_ACCESS_KEY_ID'),
    'secret-access-key' => getenv('AWS_SECRET_ACCESS_KEY'),
    'bucket' => getenv('AWS_BUCKET'),
    'region' => getenv('AWS_DEFAULT_REGION'),
    'copy-to-s3' => true,
    'serve-from-s3' => true,
)));

WP-CLI Usage

WP-CLI is pre-installed in CloudPloy's WordPress container. Access it from App > Terminal. Common operations:

# Update WordPress core
wp core update

# Update all plugins
wp plugin update --all

# Update all themes
wp theme update --all

# Search and replace (after domain change or migration)
wp search-replace 'http://old-domain.com' 'https://new-domain.com' --skip-columns=guid

# Export database
wp db export - | gzip > backup.sql.gz

# Import database
gunzip -c backup.sql.gz | wp db import -

# Flush all caches
wp cache flush
wp redis flush   # If using Redis Object Cache

# Create admin user
wp user create admin admin@example.com --role=administrator --user_pass=secure-password

# Regenerate thumbnails after theme change
wp media regenerate --yes

Security Configuration

CloudPloy handles OS-level and network security. These application-level hardening steps are your responsibility:

Disable File Editing

Prevents attackers from editing plugin/theme files via wp-admin if they gain admin access:

define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true); // Also prevents plugin/theme installs via admin

Limit Login Attempts

# Install Limit Login Attempts Reloaded or similar
wp plugin install limit-login-attempts-reloaded --activate

Force HTTPS

define('FORCE_SSL_ADMIN', true);

// Add to wp-config.php if behind a reverse proxy (CloudPloy uses one)
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Protect wp-config.php

WordPress recommends moving wp-config.php one directory above the web root. CloudPloy mounts your entire repository at /var/www/html. Place wp-config.php at the repository root and set the web root to /var/www/html/public if your repository structure separates public files.

Performance Optimization

Page Caching

Redis object cache speeds up database queries but does not cache full HTML pages. For full-page caching, use a plugin compatible with CloudPloy's Nginx setup:

  • WP Super Cache - Generates static HTML files, served directly by Nginx (fastest option)
  • W3 Total Cache - Comprehensive caching with Redis page cache support
  • WP Rocket (paid) - Best balance of features and ease of configuration

For WooCommerce sites, configure your caching plugin to exclude cart, checkout, account, and dynamic pages from the cache.

PHP-FPM Worker Sizing

Each PHP-FPM worker handling WordPress requests uses 50-100MB of RAM. For a 4GB server, expect 25-40 concurrent PHP workers. If your traffic spikes cause 502 errors, increase server RAM rather than squeezing more workers out of the same RAM.

Image Optimization

# Install Imagify, ShortPixel, or similar
wp plugin install imagify --activate

# Or optimize existing images with WP-CLI
wp media regenerate --yes  # After switching to a WebP-capable theme

WordPress Multisite

CloudPloy supports WordPress Multisite (subdomain and subdirectory modes). Add to wp-config.php before the /* That's all, stop editing! */ line:

define('WP_ALLOW_MULTISITE', true);

// After running the network setup wizard:
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true); // or false for subdirectory
define('DOMAIN_CURRENT_SITE', getenv('MULTISITE_DOMAIN') ?: 'example.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

For subdomain multisite, add wildcard DNS (*.example.com) pointing to your CloudPloy server IP and configure the domain in App > Settings > Domains.

Common Issues

Problem Likely Cause Fix
White screen of death PHP fatal error, often a plugin conflict Set WP_DEBUG=true temporarily, check App > Logs
Mixed content warnings WP_SITEURL or WP_HOME set to http:// not https:// Update env vars to use https:// and run search-replace
Uploads not saving wp-content/uploads/ permissions Run wp eval 'echo get_option("upload_path");' and check volume mount
Infinite redirect loop Missing HTTP_X_FORWARDED_PROTO handling Add the $_SERVER['HTTPS'] fix to wp-config.php (shown above)
Cron jobs not running WP-Cron disabled or slow Add define('DISABLE_WP_CRON', true) and add a real server cron in CloudPloy
Plugin update failures DISALLOW_FILE_MODS set to true Update plugins via WP-CLI in terminal instead
Email not sending No SMTP configured Install WP Mail SMTP plugin and configure SMTP env vars

WordPress Guides

Step-by-step guides for specific WordPress tasks on CloudPloy:

  • Backup and Restore - Automated database and file backups, one-click restore from CloudPloy dashboard, and how to download offsite backups.
  • Migrate from cPanel - Export your cPanel database and files, import to CloudPloy, update DNS, and verify the migration step by step.
  • SSL Configuration - Automatic Let's Encrypt SSL, custom certificates, HSTS headers, and fixing mixed content after switching to HTTPS.
  • Staging Environment - Clone your production WordPress site to a staging URL, test changes safely, and push updates back to production.

Need help with a WordPress-specific issue? Open App > Terminal to run WP-CLI commands directly, check App > Logs for PHP errors, or contact CloudPloy support.