WordPress in Docker with Nginx reverse proxy causing redirect loops without SSL

I set up a Docker environment with WordPress, MariaDB, and Adminer. Everything runs behind an Nginx reverse proxy that handles domain routing. The proxy has a valid SSL certificate configured.

In my WordPress configuration, I set everything to use HTTP URLs. The admin panel works fine when I access it through HTTP and displays correctly. But whenever I click any link or button, it automatically redirects to HTTPS and the site layout breaks completely.

I keep getting ERR_TOO_MANY_REDIRECTS error in the browser. Already cleared all browser data but that didn’t fix anything.

I tried changing WordPress URLs to HTTPS in the settings but nothing improved. Also attempted to configure WordPress for reverse proxy usage following their documentation, but the same issues persist.

The admin area looks fine over HTTP but every link switches back to HTTPS with broken styling. The frontend also loads incorrectly because resources are mixed between HTTP and HTTPS protocols.

Anyone know how to solve this redirect loop issue?

Classic mixed protocol issue. Nginx is handling SSL but WordPress doesn’t know it’s behind HTTPS. Add these lines to wp-config.php:
define(‘FORCE_SSL_ADMIN’, true);
$_SERVER[‘HTTPS’] = ‘on’;
Also set your WordPress site URL and home URL to HTTPS in the database or wp-config. You’re basically telling WordPress that even though it gets HTTP requests internally, the external connection is HTTPS. Without this, WordPress gets confused about which protocol to use for assets and redirects. Had the exact same problem last year with my staging environment - these changes fixed it right away.

check if your nginx config is missing the X-Real-IP header. WordPress often needs that plus the forwarded proto stuff. also disable any redirect plugins - they’ll create weird loops even when your proxy setup is correct.

Your Nginx proxy isn’t sending the right headers to WordPress, causing the redirect loop. Add these headers to your Nginx proxy block: proxy_set_header X-Forwarded-Proto https;, proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;, and proxy_set_header Host $host;. Then check your wp-config.php for this code: if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; }. This tells WordPress it’s running behind SSL even though internal traffic uses HTTP. Fixed the same issue when I moved a client site to Docker.

The Problem:

You’re experiencing a redirect loop (ERR_TOO_MANY_REDIRECTS) in your WordPress setup running behind an Nginx reverse proxy. Your WordPress admin panel works fine over HTTP, but any link click redirects to HTTPS, breaking the site’s styling and functionality due to mixed content issues. Changing WordPress URLs to HTTPS and configuring for reverse proxy use didn’t solve the problem. The root issue is a mismatch between how Nginx presents the connection to WordPress and how WordPress itself perceives the protocol.

:thinking: Understanding the “Why” (The Root Cause):

The redirect loop arises because Nginx, your reverse proxy, correctly handles HTTPS on the client-side but doesn’t properly communicate this to WordPress. WordPress receives internal HTTP requests but lacks crucial information indicating the external connection is HTTPS. This leads to WordPress generating links with the wrong protocol (HTTP instead of HTTPS), causing the browser to repeatedly redirect between HTTP and HTTPS, eventually resulting in the ERR_TOO_MANY_REDIRECTS error.

:gear: Step-by-Step Guide:

This guide focuses on properly configuring Nginx to communicate the HTTPS connection to WordPress. We’ll achieve this by adding necessary headers to your Nginx configuration and updating WordPress’s settings.

Step 1: Configure Nginx to Forward Protocol Information:

Locate your Nginx configuration file for the WordPress proxy block (usually within /etc/nginx/sites-available/ or a similar location). Add or modify the following lines within the location ~ ^/wp-admin/ block and the location ~ ^/(.*\.php)$ block. These headers are crucial to inform WordPress about the HTTPS connection:

location ~ ^/wp-admin/ {
    # ... other directives ...
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    # ... other directives ...
}

location ~ ^/(.*\.php)$ {
    # ... other directives ...
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    # ... other directives ...
}

Step 2: Update WordPress Configuration (wp-config.php):

Add the following code to your wp-config.php file. This explicitly tells WordPress that it’s operating behind an HTTPS proxy, regardless of internal requests using HTTP:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Step 3: Verify WordPress URLs:

Ensure your WordPress site URL and home URL are correctly set to HTTPS in the WordPress database (using phpMyAdmin or a similar tool) and within the WordPress settings page.

Step 4: Test and Restart Nginx:

After saving your Nginx configuration and wp-config.php changes, test your website. Restart the Nginx service using a command appropriate for your system (e.g., sudo systemctl restart nginx). Check if the redirect loop is resolved.

:mag: Common Pitfalls & What to Check Next:

  • Nginx Configuration Errors: Carefully check your Nginx configuration file for any syntax errors after making the changes. An incorrect configuration can lead to unexpected behavior.
  • Cached Files: Clear your browser cache and cookies after making the changes.
  • Plugin Conflicts: If the problem persists, temporarily deactivate plugins to rule out any conflicts. Some plugins might interfere with URL handling or redirect mechanisms.
  • Incorrect Server Block: Double-check that you’ve made the changes in the correct Nginx server block for your WordPress site. Make sure the right server_name directive is in place.

:speech_balloon: Still running into issues? Share your (sanitized) config files, the exact command you ran, and any other relevant details. The community is here to help!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.