I'm attempting to test out NGINX and potentially make a switch from Apache. Which I've read nginx is much faster, but I want to be the judge of that. I'm having issues getting the configuration of NGINX to match that of my Apache setup -- mainly rewrite rules. I'll explain how my applications works and what I want to be able to do in NGINX.
Currently I have my application handling all the REQUEST_URI's sent to the server. Even if the URI doesn't exist, my application handles processing of that URI. I'm able to do this because of a rewrite rule for Apache.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?_url=$1 [QSA,NC]
</IfModule>
As you can see if the file or directory doesn't actually exist, it gets sent to index.php. I don't even check for the query string, I just handle the processing of the URI itself via the PHP variable $_SERVER['REQUEST_URI'] which is setup inside NGINX as fastcgi_param REQUEST_URI $request_uri;. I want to accomplish this exact thing with NGINX, but I've been only kind of successful with that.
So basically, if domain.com/register.php exists, then it is going to go to that url, if not it is going to be redirected to domain.com/index.php and the application handles the URI from there.
Here is my config file for my server. This is included at the bottom of nginx.conf file
server {
listen ####:80;
server_name ####;
charset utf-8;
access_log /var/www/#####/logs/access-nginx.log;
error_log /var/www/#####/logs/error-nginx.log;
root /var/www/######/public/;
location / {
index index.php index.html;
include /etc/nginx/mime.types;
try_files $uri /index.php?_url=$1;
include /etc/nginx/fastcgi.conf;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm.socket;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
rewrite_log on;
}
}
So this kind of works. What I mean by that is the try_files $uri /index.php?_url=$1 directive is processing the URI the way I want it to, but MIME types don't seem to work. Everything is being processed as text/html. Which means that my .css and .js files have to be turned into a .php file and a header attached in order for it to be processed correctly. image and font files seem to function correctly, but Chrome still shows the mime type as html. I have the mime.types file being included, so I can't figure out why it's doing that. I did try to use a "rewrite" directive to handle the what try_files is doing, but that didn't work.
This is the rewrite I tried inside the location / block:
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?_url=$1;
}
So my question is this: How do I properly rewrite my uri for non-existent files and directories while serving the proper mime type for the files automatically?
I ended up solving my own issue. What I had to do here was to process PHP files on their own and it took for a while to figure out that for sure. Here is the final .conf file that sends the correct mime types and also rewrites the way I needed it. Hopefully this helps someone else as well.
server {
listen #######:80;
server_name ######;
charset utf-8;
access_log /var/www/######/logs/access-nginx.log;
error_log /var/www/#######/logs/error-nginx.log;
root /var/www/#########/public/;
location ~ \.php$ {
include /etc/nginx/mime.types;
try_files $uri /index.php?_url=$1;
include /etc/nginx/fastcgi.conf;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm.socket;
}
location / {
index index.php index.html;
include /etc/nginx/mime.types;
try_files $uri /index.php?_url=$1;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
rewrite_log on;
}
}
Using the location ~ .php$ section made it so that only PHP files were being sent to php-fpm. I also use the try_files directive to handle sending all the URI's that don't exist to my script, which is what my application expects. Hopefully this helps someone else out there!