» CakePHP and Nginx
I still got sites running Apache, but all new projects are launched with Nginx. I don't need many of the features that Apache offers, and the speed gain of Nginx is just tremendous. Once you've experienced it, I doubt you'll want to go back.
Even though there has been quite some fuzz about Nginx and I bet most of you have at least heard of it by now, I think the acceptance is still a bit low.
I'd like to help that process along by providing developers a simple yet effective example.
Maybe you'll play with it on your local box - and eventually decide to go production. Who knows.
Let me show you how easy it is to get hooked to the power of Nginx.
In this article I'm demonstrating a CakePHP setup, but 1 slight modification and this applies to pretty much any PHP Framework.
So there are a few differences from your typical Apache setup that I'd like to highlight.
Install Nginx
If you're running Ubuntu like me it helps to have Karmic or higher. Then just type:
aptitude install nginx
Other operating systems: it shouldn't be much harder then that, just replace aptitude with your package manager.
If you find yourself compiling you're on the wrong track, and going to spe nd way too much time on this.
Don't forget to shut down any existing web servers you may have.
PHP FastCGI: spawn-fcgi
In this setup, PHP is daemonized and keeps running as a process, listening to a socket.
Nginx will be configured to pass any *.php requests to this PHP process. Normally PHP would have to be fired up all the time. But now it resides in memory.
To install spawn-fcgi in Ubuntu you'd do:
aptitude install spawn-fcgi php5-cgi
# It doesn't provide a startup script yet. Here's how to get one:
wget -O/etc/init.d/spawn-fcgi http://github.com/kvz/kvzlib/raw/master/configs/spawnfcgi_initd
chmod u+x /etc/init.d/spawn-fcgi
update-rc.d spawn-fcgi defaults
Now start it with:
/etc/init.d/spawn-fcgi start
Excellent. PHP is listening on port 9000 for incoming Nginx jobs.
You can configure your new PHP install like you're used to.
Only in this directory: /etc/php5/cgi/ instead of this one /etc/php5/apache2/
Alternative: php-fpm
There also is php-fpm. Pretty much does the same thing, but faster.
Unfortunately at the time of writing I'm experiencing too many crashes for it to be recommendable. This will probably change soon though.
HtAccess
It's true that Nginx doesn't support .htaccess, but to be honest: .htaccess files are the worst.
The additional recursive dir-stats, I/O, & processing involved with every request, is equal to the exact amount of punches in the face.
That it doesn't support .htaccess does not imply however, that you can't do rewrites and all the other fancy things you could do with .htaccess files.
Just slightly modify the syntax, and place those new rules in your Nginx VHost.
As a present, I've already converted the .htaccess rules required to run CakePHP, and put them in the Nginx VHost example below.
Nginx Vhost
VHost concept works the same as Apache. Have 1 for every site.
Save it in /etc/nginx/sites-available/site. To activate, symlink it to /etc/nginx/sites-enabled/site
run:
/etc/init.d/nginx reload
..and you're in business. Use
tail -f /var/log/nginx/*.log
to see what's going on.
You don't need to change Nginx's main config, it's tight by default so just stick with your VHost for now.
Here's what a fully working CakePHP VHost looks like:
server { listen 80; server_name example.com www.example.com; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; rewrite_log on; root /var/www/example.com/app/webroot; index index.php index.html index.htm; # Not found this on disk? # Feed to CakePHP for further processing! if (!-e $request_filename) { rewrite ^/(.+)$ /index.php?url=$1 last; break; } # Pass the PHP scripts to FastCGI server # listening on 127.0.0.1:9000 location ~ \.php$ { # fastcgi_pass unix:/tmp/php-fastcgi.sock; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_intercept_errors on; # to support 404s for PHP files not found fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Static files. # Set expire headers, Turn off access log location ~* \favicon.ico$ { access_log off; expires 1d; add_header Cache-Control public; } location ~ ^/(img|cjs|ccss)/ { access_log off; expires 7d; add_header Cache-Control public; } # Deny access to .htaccess files, # git & svn repositories, etc location ~ /(\.ht|\.git|\.svn) { deny all; } }
Notes about the example
Nginx config is simple & powerful. If you want you can use if statements and put some very basic logic in there.
In this example the /app/webroot is the document root. Some people may have a / as their CakePHP webroot or even /app. But I recommend changing that to /app/webroot so you're not exposing any more PHP files then is strictly required.
Notice how this config turns off access log for some static files? How cool is that?!
Checkout how simple it is to set expire headers for different content types
Change example.com to your domainname
- Update #1: Chris Hartjes takes a similar approach in articles written way before mine, be sure to check it out!
Free bonus
Here's a VHost if you'd want to use phpmyadmin as installed in by Ubuntu's Apt:
server { listen 80; server_name phpmyadmin.example.com; root /usr/share/phpmyadmin; index index.php; # Add your IP to the allow list! location / { allow 123.123.123.123; deny all; } location ~ \.php$ { index index.php index.html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_intercept_errors on; # to support 404s for PHP files not found include fastcgi_params; } }
I'm keeping the larger code blocks on GitHub so it'll be really easy for you to download, fork, etc.
For instance I have another CakePHP configuration that's a bit bigger - shows you some other stuff you can do with Nginx here
That's it
Now go out there, play, tell me your findings.
You probably shouldn't follow me
Like this Article?
| I'd appreciate it if you leave a comment, spread the word, or consider a small donation |
RelatedArticles like this one» Survive heavy traffic with your webserver |
tags: php, nginx, cakephp, apache, performance
category: Programming - PHP - CakePHP
read: 20,405 times
tagcloud
#17. vangel on 21 April 2011
turns out its not really the whole problem. The problem is the images referenced in CSS files don't work anymore.
Also it seems authentication does not work although cookies are set... still investigating.
#16. vangel on 21 April 2011
using cake 1.2.9 stable.
thanks again.
#15. Bram on 06 October 2010
#14. Bram on 16 September 2010
It might be that is has nothing to do with your Vhost template and that it is an error with FastCGI or Nginx.
The error is the following:
... [more]
I get a 502 with this in my /var/log/sitexyz.error.log:
2010/09/16 15:58:59 [error] 2792#0: *81 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 172.20.0.2, server: testserver.xyz, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "testserver.xyz"
Any thoughts?
#13. Kevin on 08 September 2010
You probably have a different location for PHP and Nginx only executes 1 (best matching) location per request.
The order in which it will pick locations can be found in the documentation wiki.
#12. gvphoenix on 03 September 2010
I want to turn off logging for any hits to files in the '/sqlview/' folder off of the web root. Here's what I tried, with no luck:
... [more] location ~* /sqlview/ {
access_log off;
}
Any ideas where I'm going wrong?
Thanks!
#11. Kevin on 28 February 2010
@ jefftrackaid: For loadbalancing I mostly use lvs right now. This blog is powered by varnish as well, but I found you can tune Nginx to server static files so fast; the need for varnish diminishes. I will do another post on that topic later
@ Erwin Bleeker: Good catch Bleeker! Thanks a lot!
#10. Erwin Bleeker on 26 February 2010
Minor typo:
wget -0 should be wget -O
#9. jeffatrackaid on 26 February 2010
Like PHP op-code caches, I find that HTTP server performance varies significantly depending on the underlying application.
Another tool we've started exploring more is varnish for HTTP acceleration and most recently Citrix NetScaler for Layer 7 load balancing.
... [more]
What would be useful is a lighttpd - apache - nginx config converter to allow you to quickly do benchmarking and regression testing on all platforms.
#8. till on 26 February 2010
Not sure about the unstableness, maybe you can detail what you experienced. I didn't see anything yet. I've been "attacking" the test server with siege and didn't see any drops.
For me, fpm is great because of the management. E.g., the graceful restarts and all.
#7. Kevin on 26 February 2010
Had similar issues on Jaunty but after upgrading to Karmic we were all good.
@ Joris van de Sande: Cool let me know how it works out. I intend to switch to fpm as soon as I get it stable.
#6. till on 26 February 2010
PHP processes idle, but the webserver claims it cannot get to them.
I managed to set it up using a socket instead, no spawn-fcgi, see my blog entry for more details:
... [more]
http://till.klampaeckel.de/blog/archives/44-Nginx+PHP+FastCGI-Testing-your-web-application-with-bleeding-edge-PHP.html
#5. Joris van de Sande on 26 February 2010
#4. Kevin on 26 February 2010
And then php-fpm would just be gone.
#3. Joris van de Sande on 26 February 2010
What type of crashes are you experiencing?
According to http://php-fpm.org/download/ , php-fpm should be integrated in PHP as of version 5.3.3.
#2. Kevin on 25 February 2010
#1. Rachman Chavik on 25 February 2010
Played around with nginx + cakephp a few months back to no avail. But now your post make it seem so simple! Now to find the time to test :)