TYPO free

home

fighting for TYPO free code

Running TYPO3 on Nginx

4 Aug 2009

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: http://unix.derkeiler.com/Mailing-Lists/FreeBSD/questions/2007-09/msg00468.html. The adaption lives on here: http://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

  1. Rejoice
  2. 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;
}
Dominique 16 Aug 2009, 09:37
A good thing when using PHP as FastCGI process is to use the http://php-fpm.org/ patch. Great improvement ;-)

A new projet, without any PHP core patch, here: https://launchpad.net/php-fpm, but i have no experience with it.
Jimmy 13 Nov 2009, 23:09
Great article.

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 ?
Michiel 14 Nov 2009, 08:23
Hi Jimmy,

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: http://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
Ulf 16 Feb 2010, 01:08
Thanks for this article, it was very helpful. Got TYPO3 with nginx running in no time.
snillo 12 Apr 2010, 17:11
Hey Jimmy,

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
Olivier 1 May 2010, 21:32
Just a silly question. do you have problems with the /typo3 backend? did you do a separate location config for that?
Jimmy 12 Oct 2010, 12:27
Oliver, I just had that same problem.

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
Jimmy 12 Oct 2010, 12:28
snillo, yea I got that sorted out too after a few hours tinkering :)
Jimmy 16 Oct 2010, 13:34
Correction:

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
garfieldius 24 Apr 2011, 22:20
Once again your blog showed me how cool web tech is.
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
Commenting is closed for this item