I have Django running behind Nginx. One of the domains serves image files, either from a cache on the local file system if such a file exists, or with a django script if not.

To hide the real filename from bots I sometimes want to shuffle the characters in the filenames. In this case the url has a "/x/" prefix. Here is my attempt at the nginx config:

server {
listen   80;
server_name  mydomain.com;

client_max_body_size 5M;

access_log  /var/log/nginx/mydomain.access.log;

location /robots.txt {
    root /srv/www/mydomain.com;

rewrite ^/x/(.)(.)(.)(.)(.)(.)(.*)$ $5$2$6$3$1$4.jpg last;

location ~* ^.+\.(jpeg|gif|png|jpg|webp) {
    root /srv/imagecache;
    try_files /$uri @aws;

location @aws {

    fastcgi_pass unix:/srv/django/myapp/myapp.sock;
        fastcgi_param SERVER_NAME $server_name;
        fastcgi_param SERVER_PORT $server_port;
        fastcgi_param SERVER_PROTOCOL $server_protocol;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;
        fastcgi_param REMOTE_ADDR $remote_addr;
        fastcgi_pass_header Authorization;
        fastcgi_intercept_errors off;


Everything works if the rewrite rule is not matched. If the rewrite rule is matched it only works when the file can be found on the file system. Django always returns 404. On its debug error page django says that "mydomain.com/abc123.gif" can not be found, where the url is the correctly rewritten one. If I copy-paste the url in the browser's address bar and try to load that, it works. Django doesn't call the function specified in urls.py, it doesn't even say anything about urls.py on the error page.

Why? How is the request passed to Django after a rewrite is different from a regular one?

  • You should probably add a leading / to your rewritten URI. Try: rewrite ^/x/(.)(.)(.)(.)(.)(.)(.*)$ /$5$2$6$3$1$4.jpg last; Oh, and remove it from the try_files statement. – Richard Smith Feb 17 '17 at 15:13
  • This indeed solved the problem. Amazing, thank you! – pramparam Feb 17 '17 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.