How to configure nginx to run Kohana on Ubuntu
As a web developer I’ve been using Apache for a long long time. Recently though, I’ve started to move away from Apache in favor of nginx (pronounced “engine-X”). It’s not that I really need its power, it’s just that I wanted to learn something new to break my box.
It’s fairly simple to set up and get nginx running with FastCGI and MySQL on Ubuntu - a very well-written tutorial can be read on HowtoForge, which should take you less than 15 minutes for everything. In this article therefore I will only write about how to configure nginx to actually run a Kohana-powered site, with virtual host and rewriting and such. If you’re not familiar with Kohana, take a look at my article here.
The prerequisites
- I have my Kohana-power site located under
/home/phoenixheart/www/my-kohana/
directory with proper permission set (owner being www-data, that is). - nginx has been set up properly and listening on port 80, with the configuration directory being
/etc/nginx/
- I want my site to be locally accessible via my-kohana.dev. Any requests to www.my-kohana.dev should be permanently redirected to my-kohana.dev - which is also called “force non-www”.
- I want to have neat URL rewriting without “index.php”, for example
index.php?controller=product&function=get&id=1
should be rewritten into/product/get/1
- I also want that all existing files and directories under the root directory are accessible, except Kohana’s system directories
system
,application
, andmodules
. Any attempt to access system files and directories(beginning with dots, like .htaccess or .settings) should be disallowed also.
All clear. So let’s do it!
Set up the virtual host
The way nginx handles virtual hosts is totally different from Apache, as we can expect. Instead of using .conf files to declare and configure the hosts, nginx, when started, additionally scans through the configuration folder (/etc/nginx
in our case) to find (if any) configuration files under 2 directories: sites-available and sites-enabled. So under /etc/nginx/sites-available, create a file called my-kohana.dev with the following content:
server {
listen 80;
server_name my-kohana.dev;
access_log /home/phoenixheart/www/log/my-kohana/access.log; # remember to create this file
error_log /home/phoenixheart/www/log/my-kohana/error.log; # and this file
location / {
root /home/phoenixheart/www/my-kohana;
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/phoenixheart/www/my-kohana$fastcgi_script_name;
include fastcgi_params;
}
}
Of course, this is just the basis configuration for the site to get up and running. To continue, we must create a host entry. Open /etc/hosts and add this line:
127.0.0.1 my-kohana.dev www.my-kohana.dev
If this was Apache, we would be good enough to restart the webserver to see the result. But like I said, nginx is different. For nginx to properly recognize and serve our site, we must enable the site by creating a symlink of the configuration file under sites-enabled
. We do that as follow:
<code>ln -s /etc/nginx/sites-available/my-kohana.dev /etc/nginx/sites-enabled/my-kohana.dev</code>
Now, let’s restart nginx. Open Terminal and type:
<code>sudo /etc/init.d/nginx restart</code>
The result should be as followed:
<code>Restarting nginx: the configuration file /etc/nginx/nginx.conf syntax is ok configuration file /etc/nginx/nginx.conf test is successful nginx.</code>
If you receive any “failure” response, chance is some typos in the configuration.
Now, http://my-kohana.dev should be accessible via the browser (Note that, if Kohana complains about the logs folder inaccessible, try properly setting its owner to www-data). Next step is tweaking the configuration a bit to serve our needs.
Tweak it up
Force non-www
To force non-www, open sites-available/my-kohana.dev and add these lines at the top:
server {
listen 80;
server_name www.my-kohana.dev;
rewrite ^/(.*)$ http://my-kohana.dev/$1 permanent;
}
This kind of configuration is very similar to that of Apache, so I would assume there’s no need to explain. After a nginx restart, all request to http://www.my-kohana.dev should be silently redirected to http://my-kohana.dev.
Neat URL rewriting
Again, in sites-available/my-kohana.dev, modify the first location
block to the following
location / {
root /home/phoenixheart/www/my-kohana;
index index.php;
# this is where the rewriting gets done.
# refer to http://forum.kohanaphp.com/comments.php?DiscussionID=1505 for more info
rewrite ^(.+)$ /index.php?kohana_uri=$1 last;
}
But wait! We don’t want EVERY requests to be re-written. For example, a request to my-kohana.dev/css/style.css should be kept as-is. Same goes with javascripts and images. In short, if the request is for an existing file or folder, we keep it as-is; else, we route it to index.php using rewriting. To achieve that, modify the configuration above to this:
location / {
root /home/phoenixheart/www/my-kohana;
index index.php;
if (-f $request_filename) {
# translated into "if the request is an existing file, break (do nothing)"
break;
}
if (-d $request_filename) {
# translated into "if the request is an existing directory, break (do nothing)"
break;
}
# the request is not an existing file or directory
# this is where the rewriting gets done.
# refer to http://forum.kohanaphp.com/comments.php?DiscussionID=1505 for more info
rewrite ^(.+)$ /index.php?kohana_uri=$1 last;
}
Set files and folder accessibilities
Now, we prohibit access to the sensitive stuffs, including kohana system folders, dot files and directories etc. It’s fairly simple with nginx. All we need to do is adding two more location blocks, specific for this purpose:
location ~ /\. {
return 404;
# or, if you prefer
#return 403;
# or even
#deny all;
}
location ~* ^/(modules|application|system) {
return 404;
# or, if you prefer
#return 403;
# or even
#deny all;
}
The final configuration file should look like this:
server {
listen 80;
server_name www.my-kohana.dev;
rewrite ^/(.*)$ http://my-kohana.dev/$1 permanent;
}
server {
listen 80;
server_name my-kohana.dev;
access_log /home/phoenixheart/www/log/my-kohana.dev.access.log;
error_log /home/phoenixheart/www/log/my-kohana.dev.error.log;
location ~ /\. {
return 404;
}
location / {
root /home/phoenixheart/www/my-kohana;
index index.php;
if (-f $request_filename) {
# translated into "if the request is an existing file, break (do nothing)"
break;
}
if (-d $request_filename) {
# translated into "if the request is an existing directory, break (do nothing)"
break;
}
# the request is not an existing file or directory
# this is where the rewriting gets done.
# refer to http://forum.kohanaphp.com/comments.php?DiscussionID=1505 for more info
rewrite ^(.+)$ /index.php?kohana_uri=$1 last;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/phoenixheart/www/my-kohana$fastcgi_script_name;
include fastcgi_params;
}
location ~* ^/(modules|application|system) {
return 403;
}
}
After another nginx restart, our Kohana instance should run without any hassles.
Typos? Mistakes? Errors? Let’s hear it in your comment.
What others are reading
Loading…
drew
17 Mar, 2010
Wow, this post was awesome, and a huge help in getting my own nginx/kohana setup working. Thanks a lot!
Anders
19 Mar, 2010
I have just got a blog and use about 50 different plugins. Thank you very much for your plugin. It complete my website
drew
22 Mar, 2010
I think there might be a small but important typo:
Should probably be:
Notice the slash. I think that without this, kohana was co-opting all the requests, and nginx wasn’t serving up static files! Please correct me if I’m wrong, as this is still very new to me.
An
22 Mar, 2010
Hi Drew, right now I’m on a Windows box so can’t check this. I remember that I copied the code from the working configuration, but anyway if it works for you in this way or another way, it’s fine
jmoz
9 Apr, 2010
Thanks a lot man, this is exactly what I needed!
Axel
10 Jun, 2010
Your configuration for Kohana didn’t work at all for me. Plus Igor Sysoev, the nginx creator, doesn’t recommend this method. I wrote a VirtualHost configuration from scratch that works pretty well: http://vidax.net/blog/en/2010/06/kohana-with-nginx-virtualhost-configuration/
The static.xxx.com server is not required for normal users, I posted it as an example.
Thks
intel352
23 Sep, 2010
Axel, in what way does that config not work for you?
I attempted your solution, which only resulted in frustration, and ended up resorting to a working solution very similar to the above configuration.
If Igor is so against solutions as outlined above, why is that? Can you link us to his post? What is his recommended solution? Can you post *his* solution to what the above config achieves, in a working fashion?
Scott McDonald
22 Dec, 2010
Works great - Thanks!
-Scott
http://www.dnshat.com
Axel
22 Dec, 2010
Hi intel352, sorry for my late reply, I didn’t see your comment. Actually, your configuration doesn’t work when I try to access “.php” files. For instance, if I call:
http://my-kohana.dev/contact
that works well. However, if I call:
http://my-kohana.dev/contact.php
I get a “No input file specified.” error.
Concerning Igor, he doesn’t recommend the use of “-f” and “-d”, that’s what he told me by email when I posted my configuration on the mailing list. The “try_files” functions does the same and seems cleaner.
Why did my solution resulted to frustration? Wasn’t it working for you? Did you notice I use a “public” directory unlike you?
Thks
Axel
An
22 Dec, 2010
Hi Axel,
Regarding the “No input file specified” error I would assume there’s something wrong with the fastcgi pass at line 16. Nevertheless, a url ending with .php is rarely seen if we use a framework like Kohana.
About the -f and -d, you’re right, I was just starting to use nginx then and had very little experience. try_files is much cleaner.
An
intel352
22 Dec, 2010
It’s very possible that the discrepancies I and other users have seen, are due to versions of Nginx used, as Debian tends to distribute a more recent release (or there are more recent PPAs at least, I believe), whereas Redhat distros are running an ancient version.
Tester
4 Apr, 2012
This is a test.
Neil
15 May, 2012
Hi,
So if I just do plain nginx+php-fpm setup without this kind of configuration, my kohana won’t work? I recently built kohana, nginx and phpfpm. I’m getting tons of errors.
I noticed that on your configuration above, you used rewrite rules. I don’t have any. Is it required?
Thanks a lot! I will try this sometime.
Neil