This is not very hard to do but I had a tough time figuring out how to get this to work. I’m just writing this down in case someone finds it helpful.
In this scenario I’m running Nginx as the reverse proxy with SSL enabled on it and WordPress on a separate Nginx server in the backend. This should work with Apache2 in the backend too. Migrating existing setups will work with this or if you are doing a fresh install you can either do the setup over non-SSL or use SSL, run the setup and then do the “On the backend server” part.
On the reverse proxy
In your Nginx vhost put this at the top:
upstream my_blog { server 10.10.20.4:80; #replace with your backend server IP keepalive 64; }
In the server block put this in. This will be your location block. Configure SSL as normal.
location / { proxy_pass http://my_blog; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; proxy_buffering off; #change this to what you like }
If you are using Let’s Encrypt make sure you put this in the server block.
location ^~ /.well-known { alias /var/www/blog/.well-known; allow all; }
Replace /var/www/blog with webroot for the certbot plugin and set permissions with chown -R www-data:www-data /path/to/webroot. Make sure you replace www-data with appropriate Nginx user/group.
On the backend server
In the webroot of your WordPress install open up the wp-config.php file and add in the following above the require_once(ABSPATH . ‘wp-settings.php’); line.
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on'; if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST']; } if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $list = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']); $_SERVER['REMOTE_ADDR'] = $list[0]; } define('WP_HOME','https://varunpriolkar.com'); //replace this! define('WP_SITEURL','https://varunpriolkar.com'); //replace this! define('FORCE_SSL_ADMIN', true);
Set permissions with chown -R www-data:www-data /path/to/webroot. Make sure you replace www-data with appropriate backend web server user/group.
That’s it! Everything right from forwarded IPs to vhosts with different server blocks with different server_name directives on the backend server should just werk now. π
I hope you found this useful. Do let me know if you have any suggestions/need any help. π
Hi
thank you for nice tutorial.
After i changed all the setting, the page is reachable. π
But if i click on one button it doesn’t take me to the next site
“The requested URL /about/ was not found on this server.
Apache/2.4.10 (Debian) Server at regenata-institut.kara-network.ch Port 80”
Have you any idea why? π
Thanks
Hi I tried with the above configuration, URL is redirecting to apache/WP server when I access it using Nginx URL. My configuration details are as below.
Nginx Configuration:
===================
location /blog/ {
proxy_pass https://blog-one;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_buffering off;
}
Apache .htaccess:
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
wp-config.php
==============
if ( isset( $_SERVER[‘HTTP_X_FORWARDED_PROTO’] ) && $_SERVER[‘HTTP_X_FORWARDED_PROTO’] == ‘https’)
$_SERVER[‘HTTPS’]=’on’;
if (isset($_SERVER[‘HTTP_X_FORWARDED_HOST’])) {
$_SERVER[‘HTTP_HOST’] = $_SERVER[‘HTTP_X_FORWARDED_HOST’];
}
if(isset($_SERVER[‘HTTP_X_FORWARDED_FOR’])) {
$list = explode(‘,’,$_SERVER[‘HTTP_X_FORWARDED_FOR’]);
$_SERVER[‘REMOTE_ADDR’] = $list[0];
}
Note: nginx is running with ssl (9443), apache/wp is running with ssl (8443).
Also, I tried with the below.
proxy_pass https://blog-one;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
blog is loading fine but when I click on any link on the blog URL upstream is appearing in the response along with wp port as below.
https://blog-one:8443/blog/blog-page
Also, if I define the apache URL directly (no upstream) in the /blog location it is working perfectly fine.
location /blog/ {
proxy_pass https://blog-host-name:8443;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect default;
}
Please advise, what is causing the issue here. Thanks.
Rajendra
Thank you very much! This post saved my night π
After about one month of trouble with my wordpress and nginx reverse proxy I was losing my will to live and than google brought me to this site. Great config example. Thanks!
Glad you found it useful. I was surprised nobody had documented such a common use-case myself.
Pingback: How to config WordPress site behind Reverse Proxy – Digital Go