Nginx rewrite, from htaccess-files

nginxrewrite

I've got a PHP-project set up in this directory tree:

  • project
    • v1
      • app (project files)
      • public
        • index.php (controller of app)
        • documentation
          • php files
        • examples
          • php files

With "project" being the root of the webserver.

I want to skip the "public" segment of the URL, but keep the "v1":

http://myserver.com/v1/whatever/1

and not

http://myserver.com/v1/public/whatever/1

I got it working with this:

rewrite ^(.*)$ /v1/public/index.php?_url=/$1;

Also I want to be able to serve the files inside "documentation" and "examples" by this URL-structure:

http://myserver.com/v1/documentation/file_name.php
http://myserver.com/v1/examples/file_name.php

I had it working in Apache with these two .htaccess-files:

#/project/v1/.htaccess

RewriteEngine on
RewriteRule  ^$ public/    [L]
RewriteRule  (.*) public/$1 [L]
#/project/v1/public/.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]

I have failed in trying to convert these settings to Nginx. This is my result:

server {
    listen   80;
    server_name mysite.com;

    index index.php index.html index.htm;
    set $root_path '/var/www/html/project';
    root $root_path;

    try_files $uri $uri/ @rewrite;

    location @rewrite {
        rewrite ^(.*)$ /v1/public/index.php?_url=/$1 break;
    }

    location ~ \.php {
        fastcgi_pass 127.0.0.1:9000;
        #fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
        fastcgi_index /index.php;

        include /etc/nginx/fastcgi_params;

        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
        root $root_path;
    }

    location ~ /\.ht {
        deny all;
    }
}

Best Answer

First, you don't need the location ~* ^/(css|img|js|flv|swf|download)/(.+)$ block, because it doesn't change anything. Also, in general, root directory inside location blocks isn't what you usually want, alias is the thing you most likely want.

But to the actual problem, try adding these location blocks:

location /v1/documentation/ {
    rewrite ^/v1/documentation/(.+)$ /v1/public/documentation/$1 last;
}

location /v1/examples/ {
    rewrite ^/v1/examples/(.+)$ /v1/public/examples/$1 last;
}

An optional optimization for your @rewrite block

location @rewrite {
    rewrite ^ /v1/public/index.php?_url=$uri break;
}