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]


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. Commented Dec 5, 2015 at 19:20

3 Answers 3


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.

  • This works great! Little side-note for anyone who uses this, run: valet restart after making changes :)
    – Loosie94
    Commented Nov 18, 2020 at 14:37

if wordpress site is inside /var/www/html/web/wordpress then nginx config should be

location ~ ^/web/wordpress/index\.php$ { }

location /web/wordpress/ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php7.2-fpm.sock;
if (!-e $request_filename){
    rewrite ^/web/wordpress/(.*)$ /web/wordpress/index.php break;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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