I'm just getting my feet wet with nginx. In the past I've used an .htaccess file in /wp-content/uploads so if my dev or staging server doesn't have the file it redirects to the production server:

<IfModule mod_rewrite.c>
  RewriteEngine On

  RewriteBase /wp-content/uploads/
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.*) http://production.server.com/m/wp-content/uploads/$1 [L,P]

</IfModule>

I'm not having luck with doing this in nginx. It may be in part because this particular time my site is in a subdirectory (/m/).

# Tells nginx which directory the files for this domain are located
root         /srv/www/example/htdocs;
index               index.php;

    # Subdirectory location settings

    location /m {
            index index.php;
            try_files $uri $uri/ /m/index.php?$args;
            location /m/wp-content/uploads {
                    try_files $uri $uri/ @prod_svr;
            }
    }
    location @prod_svr {
            proxy_pass http://production.server.com/m/wp-content/uploads$uri;
    }

Any ideas would be greatly apprciated.

  • Did you want to proxy to your production server or redirect to your production server? In any event, the value of $uri is /m/wp-content/uploads/xxx so you should not be prefixing the path again. – Richard Smith Dec 5 '15 at 19:20

You could try something like this:

server {
    root /srv/www/example/htdocs;
    index index.php;

    # Matches any URL containing /wp-content/uploads/    
    location ~ "^(.*)/wp-content/uploads/(.*)$" {
        try_files $uri @prod_serv;
    }

    # Will redirect requests to your production server
    location @prod_serv {
        rewrite "^(.*)/wp-content/uploads/(.*)$" "http://yourdomain.com/m/wp-content/uploads/$2" redirect;
    }

    # The rest of your location blocks...
    location /m {
        index index.php;
        try_files $uri $uri/ /m/index.php?$args;
    }
}

If useful for anyone, I have a similar setup that I use in my WordPress localhost environments to handle this with some useful differences:

  1. I like to set my production environment using a variable, which allows me to quickly re-use this in multiple server blocks.
  2. I break on rewrite rather than redirect, which helps avoid issues with other requests that may match the same URL

Here's a basic example:

server {
    server_name mywebsite.dev;
    set $production mywebsite.wpengine.com;

    # Redirect requests to /wp-content/uploads/* to production server
    location @prod_uploads {
        rewrite "^(.*)/wp-content/uploads/(.*)$" "https://$production/wp-content/uploads/$2" break;
    }

    # Rule for handling requests to https://mywebsite.dev/wp-content/uploads/
    location ~ "^/wp-content/uploads/(.*)$" {
        try_files $uri @prod_uploads;
    }
}

In practice I actually include the location ~ "^/wp-content/uploads/(.*)$" rule inside of an included file called wp-common.conf. This allows me to run the $production switch on many different environments with the same set of common WordPress nginx config rules.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.