How to use nginx to proxy a subdirectory to a subdomain

It’s common to host a wordpress blog on a subdomain like on separate servers from the main site for various reasons.

For SEO purpose(Google thinks subdomain is a separate site), you may want to use for your blog but keeping the blog installation on original server. It’s simply to do this using a proxy server.

For example: is on server A. is on server B.
We have a proxy server C.

Now, we need setup the proxy for main domain on server C.

The nginx site conf will look like this:

# proxy subdirectory to subdomain
location /blog/ {
    proxy_set_header Host;
    # strip /blog/ from the path
    rewrite /blog/(.*) /$1 break;

# proxy everything else to main domain server
location / {
    # pass everything to server
    proxy_pass http://server_A_IP;
    proxy_set_header Host $host;
    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 http;


Test conf and restart nginx

nginx -t && systemctl restart nginx

Next, change main domain A record to the proxy server. Once DNS is propagated, you will need to install the SSL for main domain so that you can use to go to your blog.

certbot --nginx -d

The only problem is that the links are still using the subdomain address You can simple add following two lines in wp-config.php file to replace all subdomain links to the proxy address “”

define('WP_HOME', '');
define('WP-SITEURL', '');

Now, when you go to, you will see what you have on
All the blog posts/pages will also be translated to the proxy address like it’s hosting on the same server as the main domain.

Fix wordpress missing a temporary folder error

When you try to upload an image in WordPress Media Library, you got “Missing a temporary folder” error.

First, try switching Media Library from grid view to list view. Grid view use PHP to crop the thumbnails to proper dimensions which can use more CPU/RAM and cause your site hit server resource limit.

Second, check whether you are using PHP-FPM or not. If yes, you may reached the PHP-FPM max_children setting. You can either raising it or disable PHP-FPM.


Fix cpanel http 504 gateway timeout error

You got http 504 gateway time out error in browser when visiting your wordpress site, and you see fcgi timeout error like follows in /usr/local/apache/logs/error_log

[proxy_fcgi:error] (70007)The timeout specified has expired: [client] AH01075: Error dispatching request to : (polling)

To fix this, you need to increase the TimeOut and ProxyTimeout in Apache Configuration file. It’s best to change this for an individual user than in global virtual host file.

Eg: the cpanel user id is “USERNAME”

You need to create file /etc/apache2/conf.d/userdata/ssl/2_4/USERNAME/php-fpm.conf, then add following two lines to overwrite the default settings.

TimeOut 600
ProxyTimeout 600

Include Multiple Server IPs in one SPF record

When you have one mail server, you can use the mail server IP in your spf record TXT "v=spf1 ip4: ~all"

When you have multiple mail servers or multiple IPs on one mail server, you have to do this TXT "v=spf1 ip4: ip4: ip4: ip4: ip4: ~all"

This is not convenient and cumbersome especially when you will adding more servers and migrate client from older server to new one.

To make it simple, you can create one spf record using a subdomain to include all mail server IPs. TXT "v=spf1 ~all"

To make above record work, you need to add the TXT record like follows to your domain first:

Main spf record which includes all mail servers: TXT "v=spf1 ~all"

The _netblocks1 subdomain includes all shared server IPs: TXT "v=spf1 ip4: ip4: ~all"

The _netblocks2 subdomain includes all VPS server IPs: TXT "v=spf1 ip4: ~all"

PS: Inspired by’s spf record. 3599 IN TXT "v=spf1 ~all" 299 IN TXT "v=spf1 ~all" 3599 IN TXT "v=spf1 ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ip4: ~all"