NginX redirect to PHP file if image does not exist on file server

19,180

Solution 1

Nginx uses the try_files directive to 'see if something exists and fallback to another option' instead of using if statements and rewrites.

Within your server block, create a location block that will match your files (e.g. files ending in jpg, gif, png - add whatever extensions you want). Within that block, you will add your try_files directive. Nginx will try the paths in order - so, you start with the direct path to the image, and then list the path to your php file (but that needs to be proxied, so use a named location instead). Perhaps something like the following:

location ~ \.(gif|jpg|png) {
    try_files $uri @img_proxy;
}

The above essentially amounts to the following: For any files ending in .gif, .jpg, or .png first try the path ($uri), and if it doesn't exist goto @img_proxy.

Now, you need to create a second location @img_proxy that nginx will use if it can't find the actual file. In this you will specify your proxy settings, will also have a rewrite to change the path, and finally will pass the URI to the backend server.

Something like the following (the regex is NOT what you are looking for - it will pass the entire path, not just the file name - you can modify it to suit your needs):

location @img_proxy {
    rewrite ^(.*)$ /image.php?id=$1;
    proxy_pass      http://127.0.0.1:8080;
}

[edited to fix some missing semicolons]

Solution 2

This is an old Post, since other answers did not work for me, then I'm sharing my simple solution with other programmers that have the same problem. The codes are missing redirect or permanent at the end of the rewrite rules :

location ~ \.(gif|jpg|png)${
    root /var/www/mysite.com/httpdocs/;
    try_files $uri @img_proxy;
}

location @img_proxy {
    rewrite ^(.*)$ /image.php?id=$1 redirect;
    proxy_pass      http://127.0.0.1:8080;
}

Or in one line :

location @img_proxy {
    rewrite ^(.*)$ http://127.0.0.1:8080/image.php?id=$1 redirect;
}
Share:
19,180

Related videos on Youtube

Simon Hayter
Author by

Simon Hayter

Updated on September 18, 2022

Comments

  • Simon Hayter
    Simon Hayter over 1 year

    This is what I am trying to do. I am not familiar with Nginx enough to create custom rewrite rules like you can with Apache. It would be greatly appreciated if someone could help me with the Nginx config file! Thank you in advance!

    I have an image server running Nginx on port 80 and Apache listening on 8080. What I would like to do is...

    when you request an image that does not exist like so:

    http://img.server.com/(...ANY DIRECTORY...)/123_4_anyimagename.jpg
    

    it will redirect to

    http://img.server.com:8080/image.php?id=123_4_anyimagename
    

    Thank you! I almost have this working! I had to put in the root

    location ~ \.(gif|jpg|png)${
        root /var/www/mysite.com/httpdocs/;
        try_files $uri @img_proxy
    }
    
    location @img_proxy {
        rewrite ^(.*)$ /image.php?id=$1
        proxy_pass      http://127.0.0.1:8080;
    }
    

    So in images.php file which is located at

    /var/www/mysite.com/httpdocs/image.php

    I simply have

    <?php echo "test"; ?>  
    

    to see if its working. The problem seems to be php is not kicking in and its just rendering as plain text. Its almost there! Any clues as to where to look?

    If I run http://mydomain.com:8080/image.php I get "test" as the output. So I know php is working. What am I overlooking?

    • squeeks
      squeeks over 12 years
      I was about to flag this for migration to Serverfault - then I see it came from there. Not sure that wasn't a mistake...
    • Chris Bornhoft
      Chris Bornhoft about 9 years
      @Cyclops Agreed. Why is this here?