Last week I was searching for a bit of a performance boost for my site running on a Linode package. It's pretty OK, but not 'zippy' at all. During my search I came across a lot of interesting articles about Squid, lighttpd, <span style="display: none;"> </span>Varnish and Nginx. EVO techblog has an article about using Nginx in combination with TYPO3 running a complex dynamic site. There are also articles about using Nginx as a load balancer that show pretty impressive improvement in system performance since the switch to Nginx. An article on drupal.org notes 300M of memory being freed after switching from Apache to Nginx.
After reading all that information, I was interested enough to give Nginx a go (Mental note to self; experiment more with emerging software and technologies). Nginx is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Written by Igor Sysoev in 2005, Nginx now hosts between 1% and 4% of all domains worldwide (1, 2). Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.
This article will describe how to set up Nginx to run TYPO3 natively.
I run Debian on my system but the same setup should work for Ubuntu or any other platform or distro. First we get nginx:
apt-get install nginx
That was easy. Now configure nginx and start it. I just edited the /etc/nginx/sites-available/default file and changed the port number so that Nginx listens on port 8080. Then I started the server:
/etc/init.d/nginx start
That was easy too. Now you can admire the default nginx site on your server running on port 8080.
Start a php-cgi process
There is no nginx_php module so we will use php-cgi to serve php files. There are several ways to do this. The most elegant way I have found was adapted and made public by Till Klampaeckel. The original script can be found here: https://unix.derkeiler.com/Mailing-Lists/FreeBSD/questions/2007-09/msg00468.html. The adaption lives on here: https://till.klampaeckel.de/blog/archives/51-Ubuntu-nginx+php-cgi-on-a-socket.html. And there is even a git repository that stores the latest version.
Install php5-cgi:
apt-get install php5-cgi
Don't forget to check your /etc/php5/cgi/php.ini. It should be about the same as your /etc/php5/apache2/php.ini.
Get the php-fcgi super-duper-control thing (yes, that's what it is called, just check the source) and put the startup script in /etc/init.d/, 'chmod +x' it and don't forget it to use 'update-rc.d php-fcgid defaults' in case you want to start the processes when the server boots up.
Configure the script, set up the number of children and the user and group the children should run as. If you start up the service, a socket will be created in the directory you specified. You will need to note down the socket name because we will need it in the configuration of Nginx.
Create a TYPO3 Nginx configuration that uses php
We can use an existing document root for now, we're just running on another port.
server {
listen 8080;
server_name www.typofree.org;
location / {
root /var/www/typofree.org;
index index.php;
# serve exising files directly
if (-f $request_filename) {
break;
}
# if the file does not exist, pass it on to TYPO3
if (!-f $request_filename) {
rewrite .* /index.php last;
return 200;
}
}
# pass the PHP scripts to FastCGI server
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fcgid/.fastcgi.www-data/socket;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/typofree.org/$fastcgi_script_name;
}
}
This configuration should do the trick. Adjust the paths where needed. Also change the location of the socket which may be different in your setup.
Restart Nginx
Now restart Nginx and you should be able to reach your site on port :8080. The site will be able to handle a realurl setup fine.
Next
- Rejoice
- Do some performance test (I'll write about that later)
Update, May 1 22:47
This is my current setup:
server {
listen 8080;
server_name www.typofree.org;
location / {
root /var/www/typofree.org;
if (-f $request_filename) {
break;
}
if ($request_uri ~ '^/(typo3(/|conf|temp)|fileadmin|uploads|t3lib|clear.gif|index.php|favicon.ico)') {
break;
}
if (!-e $request_filename) {
rewrite .* /index.php last;
return 200;
}
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fcgid/.fastcgi.www-data/socket;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/typofree.org/$fastcgi_script_name;
}
}
Update 19 May 2011
This is my current setup:
server {
listen 109.74.192.51;
server_name typofree.org;
rewrite ^ $scheme://www.typofree.org$request_uri? permanent;
}
server {
listen 109.74.192.51;
server_name www.typofree.org;
root /var/www/typofree.org;
location = /clear.gif {
empty_gif;
expires max;
}
include sites-available/staticfile.conf;
location /typo3temp/tx_ncstaticfilecache {
expires 43200;
}
location / {
include sites-available/expires.conf;
try_files $uri $uri/ /index.php;
}
include sites-available/php-fastcgi.conf;
}
php-fastcgi.conf:
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fcgid/.fastcgi.www-data/socket;
fastcgi_index index.php;
include fastcgi_params;
}
A new projet, without any PHP core patch, here: https://launchpad.net/php-fpm, but i have no experience with it.
I have been running over some very odd behavour using Nginx with Typo3.
For some particular reason everything between the <body></body> tag is ignored in the output.
Any ideas on how to remedy this issue ?
The fact that you do not have anything in the body may be character set related. A client had the exact same thing recently. In their case, they had made a copy of the database by dumping and importing it. Somehow the character set and collation got messed up. This case had the exact same symptoms you describe.
Try to dump the db with a script like this: https://www.typofree.org/article/archive/2008/july/title/typo3-database-backup-without-the-heavy-tables/
And when creating a new table, take care to create it with the same character set and collation as the old one:
mysql> CREATE DATABASE databasenaam CHARACTER SET utf8 COLLATE utf8_general_ci;
Hope that solves it, kind regards,
Michiel
we had the same problem, setting cgi.fix_pathinfo = 0 in cgi/php.ini did the trick. I think this occurs only if you don't specify a particular server_name, for example if you have server_name _; ...
Georg
I changed the request_uri string to:
if ($request_uri ~ '^/(typo3(/|conf|temp)|fileadmin|uploads|t3lib|clear.gif|index.php|favicon.ico)') {
and it works for me now.
/Jimmy
if ($request_uri ~ '^/(typo3(/|conf|temp)|fileadmin|uploads|t3lib|clear.gif|index.php|favicon.ico)') {
to
if ($request_uri ~ '^/(typo3(/|conf|temp)|typo3|fileadmin|uploads|t3lib|clear.gif|index.php|favicon.ico)') {
Sorry about posting wrong before.
/Jimmy
One comment though:
Instead of
if (!-e $request_filename) {
rewrite .* /index.php last;
return 200;
}
I use a simple
try_files $uri /index.php;
Works like a charm