Nginx – PHP app breaks on Nginx, but works on Apache

nginxPHPphp-fpm

I want to migrate a PHP application from Apache to Nginx. The problem is that the App breaks, because the routing doesn't work anymore and I'm not exactly sure how to fix it.

The PHP application includes some .htaccess files and I tried to convert those to Nginx.

The first one is in the document root:

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteRule    ^$    public/    [L]
  RewriteRule    (.*) public/$1    [L]
</IfModule>

The second one is in /public/

<IfModule mod_rewrite.c
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  # Rewrite all other URLs to index.php/URL
  RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>

<IfModule !mod_rewrite.c>
ErrorDocument 404 index.php
</IfModule>

The third and last one is:

deny from all

My nginx version of it looks like the following:

#user nobody;
worker_processes 1;


#pid logs/nginx.pid;


events {
worker_connections 1024;
}


http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    #tcp_nopush on;
    keepalive_timeout 65;
    gzip on;

    server {
      listen 8080;
      server_name localhost;
      root /Library/WebServer/Documents/admin;

      location / {
        index index.php;
        rewrite ^/$ /public/ break;
        rewrite ^(.*)$ /public/$1 break;
      }

      location /public {
        if (!-e $request_filename){
          rewrite ^(.*)$ /index.php?url=$1 break;
        }
      }

      location /library {
        deny all;
      }
      #error_page 404 /404.html;

      # redirect server error pages to the static page /50x.html
      #
      error_page 500 502 503 504 /50x.html;
      location = /50x.html {
        root html;
      }

      location ~ \.php$ {
        root /Library/WebServer/Documents/admin;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
       }
   }
}

The problem I face is that something that the routing is broken and just returns a 404 page instead. Hopefully someone has an idea and know how to fix it 😉

Thanks

EDIT

I got it working with this config

location /library {
     deny all;
   }

   location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
       access_log off;
        rewrite ^(.*)$ /public/$1 break;
      }

      location / {
       rewrite ^/(.+)$ /index.php?url=$1 last;
      }

I'm sure there are better solutions and I'm open for suggestions.

Best Answer

It appears as though you have a routing loop.

You are directing all traffic from / to /public and then all traffic from /public to /index.php

Based on /public/.htaccess, all requests to /public should be routed to /public/index.php?url=$1 instead of /index.php?url=$1

 location /public {
        if (!-e $request_filename){ 
          rewrite ^(.*)$ /public/index.php?url=$1 break;
        }
      }
Related Topic