1

I am trying to move an old app to nginx from apache but I froze on here.

The /.htaccess

RewriteEngine on
RewriteRule ^(.*) public/$1 [L]

The /public/.htaccess

Options +Indexes +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

The structure is really simple. This app has

./application
    ./*back-end*
./vendor 
    ./*back-end includes*
./public 
    ./public/.htaccess <- this one
    ./*front-end*
./tests
./.htaccess <- this one

The only way I made it work was by changing the server root to ./public and added

location / {
    if (!-d $request_filename){ set $rule_0 1$rule_0; }
    if (!-f $request_filename){ set $rule_0 2$rule_0; }
    if ($request_filename !~ "-l"){ set $rule_0 3$rule_0; }
    if ($rule_0 = "321"){ 
        rewrite ^/(.+)$ /index.php?url=$1 last; 
    }
} #from winginx convertor

but that way my outside of ./public folders are left out and the app is broken. So I am looking for a way to rewrite it without excluding the back-end folders.

dev
  • 111
  • 1
  • 3

1 Answers1

1

Resetting your document root back to the top. Try this:

location / {
    try_files $uri $uri/ @public;
}
location @public {
    rewrite ^ /public$request_uri last;
}
location /public {
    try_files $uri $uri/ @rewrite;
}
location @rewrite {
    rewrite ^/(.*)$ /public/index.php?url=$1 last;
}

The first and second location blocks will serve the back-end files and ensure that anything else gets rewritten to the /public folder (your first .htaccess rule set).

The third and fourth location blocks will serve files from the public folder (if they exist) and otherwise invoke the /public/index.php script.

I presume that you already have a PHP location block.

The above may be overkill (I am just following your Apache implementation), and this may also work (skipping a few steps):

location / {
    try_files $uri $uri/ @rewrite;
}
location @rewrite {
    rewrite ^/(.*)$ /public/index.php?url=$1 last;
}

If you don't mind a leading slash in the url parameter, it can be simplified to:

location / {
    try_files $uri $uri/ /public/index.php?url=$uri;
}

See this and this for more.

Richard Smith
  • 12,834
  • 2
  • 21
  • 29
  • I did tried some stuff like that one, but in the end it seems that there is something in the default nginx configuration that's been setup on the server. After my `location` directives there are few more configs included and one of them had `location ~ \.php$ {` which after 5 hours of testing seems to mess up the entire scenario. But after looking at your explanation I can see I am on the right path. – dev Mar 02 '16 at 15:40