SSL Configuration for WordPress on CloudPloy
Securing your WordPress site with SSL/TLS is no longer optional - it is a ranking signal for Google, a requirement for WooCommerce payments, and the baseline expectation of every modern browser. CloudPloy handles certificate provisioning and renewal automatically, but understanding how SSL works on your stack helps you debug problems fast and configure advanced options when you need them.
This guide covers everything from the basics of how Let's Encrypt works on CloudPloy to advanced topics like HSTS preloading, Cloudflare SSL modes, mixed content fixes, and WooCommerce-specific HTTPS requirements.
How Automatic SSL Works on CloudPloy
CloudPloy uses Let's Encrypt to issue free, trusted SSL certificates for every WordPress site you deploy. Here is what happens automatically when you add a domain:
- DNS Verification: CloudPloy attempts an HTTP-01 challenge by placing a file at
http://yourdomain.com/.well-known/acme-challenge/. Let's Encrypt fetches this file to confirm you control the domain. - Certificate Issuance: Once verified, a 90-day certificate is issued and installed on your server's Nginx/Apache configuration automatically.
- Auto-Renewal: CloudPloy renews certificates 30 days before expiry. You never touch a certificate manually unless you opt for a custom cert.
- Nginx Configuration: SSL termination happens at the Nginx layer. Traffic is decrypted and passed to PHP-FPM internally over HTTP, which is why you need the proxy detection snippet in wp-config.php.
What is Included by Default
- TLS 1.2 and TLS 1.3 - older TLS 1.0/1.1 disabled by default
- Perfect Forward Secrecy (PFS) - ECDHE cipher suites ensure past sessions cannot be decrypted even if the private key is later compromised
- OCSP Stapling - reduces latency on the SSL handshake by caching certificate revocation status at the server
- HTTP/2 - multiplexed connections for faster page loads, enabled automatically with HTTPS
- HTTP to HTTPS redirect - 301 redirect configured at Nginx level
- Certificate monitoring - alerts sent 14 days before expiry if auto-renewal fails
Connecting a Custom Domain with SSL
If you are using a custom domain (e.g., yoursite.com) rather than a CloudPloy subdomain, follow these steps to get SSL working correctly.
Step 1: Point DNS to Your Server
Log into your domain registrar (Namecheap, GoDaddy, Cloudflare, etc.) and add an A record pointing to your CloudPloy server IP:
# DNS records to add at your registrar
# Replace 203.0.113.45 with your actual CloudPloy server IP
yoursite.com A 203.0.113.45
www.yoursite.com A 203.0.113.45
# OR use a CNAME for www (equivalent)
www.yoursite.com CNAME yoursite.com Find your server IP in CloudPloy Dashboard > Servers > [Your Server] > IP Address.
Step 2: Add the Domain in CloudPloy
- Open your WordPress application in the CloudPloy dashboard
- Go to Settings > Domains
- Click Add Domain
- Enter your domain (without http/https prefix)
- Choose whether to redirect www to non-www or vice versa
- Click Save
CloudPloy immediately starts the Let's Encrypt verification process. Provisioning typically completes in 2-5 minutes once DNS has propagated. You can check status at Settings > SSL Certificates.
Step 3: Verify DNS Propagation
Let's Encrypt cannot issue a certificate until your DNS is pointing to CloudPloy servers. Use these tools to check propagation:
- whatsmydns.net - checks propagation across multiple global DNS resolvers simultaneously
- dig command:
dig yoursite.com A +shortshould return your CloudPloy IP - Propagation can take anywhere from 5 minutes to 48 hours depending on your registrar's TTL settings
Step 4: Update WordPress URLs to HTTPS
Once the certificate is active, update WordPress to use HTTPS URLs. There are two approaches:
Method A - WordPress Admin (Recommended):
- Log into WordPress Admin
- Go to Settings > General
- Change WordPress Address (URL) from http:// to https://
- Change Site Address (URL) from http:// to https://
- Click Save Changes
- WordPress will log you out - log back in via HTTPS
Method B - wp-config.php (Use if locked out):
// Add before the line: "That's all, stop editing!"
define('WP_HOME', 'https://yoursite.com');
define('WP_SITEURL', 'https://yoursite.com'); Configuring WordPress to Detect HTTPS Behind a Proxy
CloudPloy terminates SSL at the Nginx reverse proxy layer. PHP sees requests arrive as HTTP internally, which means $_SERVER['HTTPS'] is not set - this causes WordPress to think the site is on HTTP even though users see HTTPS.
Fix this by adding the following to wp-config.php (add it after the database constants, before "That's all, stop editing!"):
// Tell WordPress it is behind an HTTPS proxy
// This fixes SSL detection on CloudPloy's Nginx setup
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
// Force SSL for admin area
define('FORCE_SSL_ADMIN', true); Without this, you may see: WordPress admin redirect loops, mixed content warnings, or the admin bar showing an insecure padlock.
Force HTTPS with .htaccess
CloudPloy handles the HTTP-to-HTTPS redirect at Nginx level, so you typically do not need .htaccess rules. However, if you are using Apache or want belt-and-suspenders protection, add these rules before the WordPress block in your .htaccess:
# Force HTTPS - add ABOVE the # BEGIN WordPress block
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Also handle X-Forwarded-Proto from the Nginx proxy
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# BEGIN WordPress
# @...existing WordPress rules below this line...
Fixing Mixed Content Warnings
Mixed content occurs when an HTTPS page loads resources (images, scripts, stylesheets, iframes) over HTTP. Browsers block active mixed content (scripts, iframes) and warn about passive mixed content (images). This is one of the most common SSL issues after migrating to HTTPS.
Identify Mixed Content
Open Chrome DevTools (F12) > Console tab. Mixed content errors appear as:
Mixed Content: The page at 'https://yoursite.com/page' was loaded over HTTPS,
but requested an insecure image 'http://yoursite.com/wp-content/uploads/photo.jpg'. Fix Approach 1: Search and Replace in Database
Use WP-CLI to do a safe search-and-replace across your database. This handles serialized data correctly (unlike manual SQL):
# SSH into your CloudPloy server, then:
cd /var/www/yoursite
# Do a dry run first to see what would change
wp search-replace 'http://yoursite.com' 'https://yoursite.com' --dry-run
# Run the actual replacement
wp search-replace 'http://yoursite.com' 'https://yoursite.com' --all-tables
# Clear caches after replacement
wp cache flush Fix Approach 2: Really Simple SSL Plugin
If WP-CLI is not available, the Really Simple SSL plugin automatically fixes mixed content using an output buffer that rewrites HTTP references to HTTPS. Install from Plugins > Add New. It also adds the proxy detection code to wp-config.php automatically.
Fix Approach 3: Content Security Policy Header
Add an upgrade-insecure-requests directive to auto-upgrade HTTP sub-resources to HTTPS without replacing URLs:
# Add to .htaccess or CloudPloy custom headers
Header always set Content-Security-Policy "upgrade-insecure-requests" Common Sources of Mixed Content
- Hardcoded URLs in theme files - search theme PHP files for "http://" references
- Plugin assets - some older plugins hardcode http:// CDN URLs
- External embeds - YouTube, Twitter, Google Maps iframes using HTTP
- WordPress uploads - URLs stored in the database pointing to http:// paths
- Custom HTML widgets - sidebar widgets with hardcoded image URLs
Cloudflare SSL Configuration
If your domain is behind Cloudflare (orange cloud enabled), you need to configure SSL mode carefully to avoid redirect loops:
Recommended: Full (Strict) Mode
In your Cloudflare dashboard under SSL/TLS > Overview, select Full (Strict). This means:
- Cloudflare connects to your CloudPloy server over HTTPS
- Cloudflare validates your Let's Encrypt certificate is valid
- No redirect loops possible
What NOT to Use
- Flexible mode - Cloudflare connects to your server over HTTP. This causes infinite redirect loops when CloudPloy's Nginx forces HTTPS. Never use Flexible with CloudPloy.
- Off mode - disables SSL entirely, leaving users on HTTP
Cloudflare-Specific Settings to Enable
- Always Use HTTPS - under SSL/TLS > Edge Certificates, enables 301 redirect for all HTTP traffic
- Automatic HTTPS Rewrites - rewrites mixed content URLs in HTML responses
- HSTS - enable after confirming HTTPS works correctly (see section below)
- Minimum TLS Version - set to TLS 1.2 to block outdated clients
HSTS - HTTP Strict Transport Security
HSTS tells browsers to always use HTTPS for your domain, even before the first HTTP response. Once a browser sees the HSTS header, it refuses to load your site over HTTP for the specified duration - even if it receives an HTTP redirect.
Warning: Only enable HSTS after you are confident HTTPS works perfectly. A misconfigured HSTS header can lock users out of your site for up to a year.
Adding the HSTS Header
CloudPloy automatically sets HSTS on all sites with SSL. The header looks like:
Strict-Transport-Security: max-age=31536000; includeSubDomains This tells browsers to use HTTPS for all requests to your domain (and all subdomains) for one year (31536000 seconds).
HSTS Preload List
For maximum security, you can submit your domain to the HSTS preload list - a list hardcoded into Chrome, Firefox, Safari, and Edge. Browsers on this list never make an initial HTTP request to your domain.
Requirements for preloading:
- A valid HTTPS certificate
- HTTP redirects to HTTPS on the same domain
- All subdomains served over HTTPS
- HSTS header with max-age >= 31536000 (1 year)
- The
includeSubDomainsandpreloaddirectives in your HSTS header
Submit at hstspreload.org. Note: removal from the preload list takes months - only submit when you are fully committed to HTTPS.
Testing Your SSL Configuration
After setting up SSL, verify the configuration is correct using these tools:
SSL Labs Server Test
Go to ssllabs.com/ssltest and enter your domain. Aim for an A or A+ rating. The test checks cipher suites, protocol support, certificate chain, HSTS, and more. A+ requires HSTS with preload directive.
Command Line Verification
# Check certificate details
openssl s_client -connect yoursite.com:443 -servername yoursite.com 2>/dev/null | openssl x509 -noout -subject -dates
# Verify TLS 1.3 is supported
openssl s_client -connect yoursite.com:443 -tls1_3 2>&1 | grep "Protocol"
# Check HSTS header is present
curl -sI https://yoursite.com | grep -i strict-transport
# Verify HTTP redirects to HTTPS
curl -sI http://yoursite.com | grep -i location Check for Mixed Content
# Use curl to scan a page for HTTP references
curl -s https://yoursite.com | grep -E 'src=["\']http:|href=["\']http:'
# Or use the browser console approach:
# Open Chrome DevTools > Console and paste:
# document.querySelectorAll('[src^="http:"], [href^="http:"]')
WooCommerce SSL Requirements
WooCommerce requires HTTPS for all payment pages. If your store is not fully HTTPS, checkout will either show security warnings or fail to load payment gateways. Verify:
- The WooCommerce "Force secure checkout" option is enabled at WooCommerce > Settings > Advanced > Force secure checkout
- Your payment gateway (Stripe, PayPal, etc.) webhooks use the HTTPS URL
- Product images load over HTTPS (check wp-content/uploads URLs)
- No mixed content on /cart, /checkout, or /my-account pages
// wp-config.php: required for WooCommerce HTTPS checkout
define('FORCE_SSL_CHECKOUT', true);
define('FORCE_SSL_ADMIN', true); SSL Troubleshooting
Certificate Not Provisioning
If CloudPloy shows a pending certificate status after more than 15 minutes:
- Verify DNS is propagated:
dig yoursite.com Amust return your CloudPloy server IP - Check there is no CAA record blocking Let's Encrypt:
dig yoursite.com CAA- if a CAA record exists, add0 issue "letsencrypt.org" - Ensure port 80 is open on your server (needed for HTTP-01 challenge even if you want HTTPS-only)
- If your domain is behind Cloudflare, temporarily disable the proxy (grey cloud) during certificate provisioning
- Contact CloudPloy support - provide your domain and we will check the ACME challenge log
ERR_TOO_MANY_REDIRECTS
This almost always means Cloudflare is set to Flexible SSL mode while CloudPloy also forces HTTPS, creating an infinite redirect loop. Fix: change Cloudflare SSL to Full (Strict).
If not using Cloudflare, check wp-config.php for conflicting URL definitions and remove any duplicate HTTPS forced rules in .htaccess.
WordPress Admin Redirect Loop
If WordPress admin is stuck in a redirect loop after enabling HTTPS:
// wp-config.php - add these lines
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
define('FORCE_SSL_ADMIN', true);
define('WP_HOME', 'https://yoursite.com');
define('WP_SITEURL', 'https://yoursite.com'); Mixed Content After Migrating from HTTP
After running the search-replace and still seeing mixed content:
- Check the postmeta table - many page builders store URLs in serialized meta values
- Clear all caches: object cache, page cache, CDN cache, browser cache
- Check theme and child-theme style.css for hardcoded HTTP background images
- Run
wp search-replaceagain targeting specific tables:--tables=wp_postmeta,wp_options,wp_posts
Certificate Expiry Warnings
CloudPloy auto-renews certificates 30 days before expiry. If you receive an expiry alert:
- Check the CloudPloy dashboard under Settings > SSL Certificates for renewal status
- Ensure DNS still points to CloudPloy (TTL changes may have caused propagation issues)
- If Cloudflare proxy is enabled, ensure port 80 is accessible from Let's Encrypt's servers
- Trigger a manual renewal from the SSL Certificates panel if auto-renewal is stuck
Security Headers Beyond SSL
CloudPloy applies the following security headers automatically to all HTTPS sites:
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=() For additional protection, consider adding a Content Security Policy (CSP) header. CSP is powerful but complex - a misconfigured CSP can break your site. Start with report-only mode:
# Test CSP without blocking anything
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri /csp-report Frequently Asked Questions
Does CloudPloy charge extra for SSL certificates?
No. SSL certificates via Let's Encrypt are included for all CloudPloy plans at no extra cost. Custom certificates (EV, OV, wildcard from commercial CAs) can be uploaded for enterprise accounts.
Can I use my own SSL certificate?
Yes. Under Settings > SSL Certificates, enterprise accounts can upload custom certificates with the private key, certificate, and certificate chain. This is useful for Extended Validation (EV) certificates that show a green company name in older browsers.
How long does certificate provisioning take?
Typically 2-5 minutes after DNS propagates. If DNS takes 30-60 minutes to propagate globally, certificate provisioning will wait until the domain resolves correctly.
Does SSL slow down my WordPress site?
Modern TLS adds less than 1ms of latency thanks to TLS 1.3's single round-trip handshake, session resumption, and OCSP stapling. HTTP/2 (which requires HTTPS) is actually faster than HTTP/1.1 for loading multiple assets in parallel. HTTPS is a net performance win.
Why does my SSL score show TLS 1.0/1.1 warnings?
CloudPloy disables TLS 1.0 and 1.1 by default. If SSL Labs shows these as supported, you may have a custom Nginx configuration that re-enables them, or you may be testing through Cloudflare which has its own TLS settings - check Cloudflare > SSL/TLS > Edge Certificates > Minimum TLS Version.