skip to Main Content

I don’t have much experience with regex, and less in an Nginx context, so this one is a difficult one for me.

What I want is that when I’m on a especific page (not subfolder) the server takes images from a different root.

My current configuration to handle images in all the pages of my website right now is this one.

location ~* .(png|jpg|jpeg|gif) {
        root /usr/share/nginx/nginxTestPHP/media;
    }

And I’d like that when I’m in the page example.com/My-Profile the server handles the images from /usr/share/nginx/nginxTestPHP/media/uploads, my idea is something like this, if it makes any sense.

location ~* /My-Profile/*.(png|jpg|jpeg|gif) {
        root /usr/share/nginx/nginxTestPHP/media/uploads;
    }

Obviously this one doesn’t work otherwise I wouldn’t be here asking this, so for the regex pros out there, what would be the solution for this one ?

Also how would I apply this in 2 different pages in the same regex, something like (My-Profile|Configuration) is my idea.

My Nginx configuration

server {
    listen       81;
    listen  [::]:81;
    server_name  IP;

    client_max_body_size 4M;

    charset UTF-8;

    include /etc/nginx/mime.types;

    error_log /var/log/nginx/error_log warn;
    access_log /var/log/nginx/access_log main;

        rewrite ^(/.*).html(?.*)?$ $1$2 permanent;
        rewrite ^/(.*)/$ /$1 permanent;

        root /usr/share/nginx/nginxTestPHP/PHP;

        index index.html index.htm Inicio.php Index.php;

        location / {
                try_files $uri/index.html $uri.html $uri/ @extensionless-php;
        }

        location @extensionless-php {
            rewrite ^(.*)$ $1.php last;
        }

        # pass the PHP scripts to FastCGI
        location ~ .php$ {
                try_files $uri =404;
                fastcgi_intercept_errors on;
                fastcgi_pass app:9000;
                fastcgi_index Inicio.php;
                fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
                include fastcgi_params;
        }

        location ^~ /vendor/ {
                deny all;
                return 403;
        }

        # deny access to .htaccess files
        location ~ /.ht {
                deny all;
        }

location ^~ /en/ {
    try_files $uri/.php $uri.php $uri/ @rewrite;
    fastcgi_intercept_errors on;
    fastcgi_pass app:9000;
    fastcgi_index Index.php;
    fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    include fastcgi_params;
    }

location ^~ /Blog/ {
    try_files $uri/.php $uri.php $uri/ @rewrite;
    fastcgi_intercept_errors on;
    fastcgi_pass app:9000;
    fastcgi_index Index.php;
    fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    include fastcgi_params;
    }


    location @rewrite {
        rewrite ^/(en|Blog)(/.*.(png|jpg|svg|ico))$ $2 last;
        return 404;
    }


    location ~ .css {
        root /usr/share/nginx/nginxTestPHP/CSS;
        default_type text/css;
        add_header  Content-Type    text/css;
    }

    location ~ .js {
        root /usr/share/nginx/nginxTestPHP/JavaScript;
        default_type text/javascript;
        add_header  Content-Type    application/x-javascript;
    }

    location ~ .txt {
        root /usr/share/nginx/nginxTestPHP/PHP;
    }
    
    location ~* ^/Mi-Perfil/([^/]+.(png|jpg|jpeg|gif))$ {
        alias /usr/share/nginx/nginxTestPHP/media/uploads/$1;
    }

    location ~* .(png|jpg|svg|ico|jpeg|gif) {
        root /usr/share/nginx/nginxTestPHP/media;
    }

    error_page  405     =200 $uri;

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/nginxTestPHP/PHP;
        try_files $uri /Inicio.php;
    }

}

2

Answers


  1. Little experience with Nginx here but the regex part looks relatively simple to fix – try using:

    location ~* /My-Profile/.+.(png|jpg|jpeg|gif)$ {
        root /usr/share/nginx/nginxTestPHP/media/uploads;
    }
    

    Note the .+ after My-Profile/ and the end-of-string anchor ($) – I’m assuming you want to only match images, not a URI like stackoverflow.com/test.png/somepage.

    From the little research I did, you may also want to look into nginx maps, especially if you’re looking to do this for multiple profile pages all following the same URI pattern.

    Login or Signup to reply.
    1. Your regex is broken, it is a dot (.) in PCRE patterns that acts as a wildcard, not an asterisk one. If you want to match any non-zero number of characters except a / one, you can use [^/]+ regex pattern:

      location ~* /My-Profile/[^/]+.(png|jpg|jpeg|gif)$ { ... }
      

      or to ensure that an URI started exactly with /My-Profile/ add a ^ anchor (matches start of the string):

      location ~* ^/My-Profile/[^/]+.(png|jpg|jpeg|gif)$ { ... }
      
    2. Check the difference between root and alias nginx directives. With your configuration nginx will search the files inside the /usr/share/nginx/nginxTestPHP/media/uploads/My-Profile folder. Use an alias directive instead:

      location ~* ^/My-Profile/[^/]+.(png|jpg|jpeg|gif)$ {
          alias /usr/share/nginx/nginxTestPHP/media/uploads;
      }
      

    Update

    I think I made a serious mistake. Since this is a regex matching location an alias directive argument should contain full path to image file with filename:

    location ~* ^/My-Profile/([^/]+.(png|jpg|jpeg|gif))$ {
        alias /usr/share/nginx/nginxTestPHP/media/uploads/$1;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search