First of all, you can find several guides that are wrong, unsecure, or include unnecessary directives, on the first page, when googling for "symfony2 on nginx". The mistakes these guides are making, are all explained in the pitfalls section of the nginx documentation, namely:

  • Unnecessary "location /" directives
  • Unnecessary if statements
  • Unnecessary rewrites
  • Forwarding every .php file to PHP

The first 3 are simply a performance issue, on a development machine you might not really care about it. The 4th is major though, since it's a security issue, that comes from a line like this:

location ~ .php$ {

If visitors can upload files through your site, and you place those under the document root, and a .php file gets through your filtering, it will allow people to run arbitrary code on your webserver. Even if you don't allow, or secure your uploads, there is still a vulnerability around PHP's ini setting cgi.fix_pathinfo (which is turned on by default), that can bite you. That's a lot of ifs, and whens, but still, why not attack the problem at the root. Also, it might be a good idea to read the if is evil section of the docs.

So refining a bit on the example configuration on the nginx page, and keeping the pitfalls in mind, this is probably the most compact, and secure Symfony2 config for nginx:

bash

server {
  server_name symfony2.local;
  root /srv/http/symfony2/web;
  index app.php;
  try_files $uri $uri/ /app.php?$query_string;
  location ~ ^/(app_dev|app_test.php|app)\.php(/|$) {
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTPS off;
  }
}

If you are using this for development, replace the app.php in the index, and try_files directives with app_dev.php. On production, you can remove the app_dev.php from the location directive. It might also be a good idea to throw in an error_log in the server block. Keep in mind that this only allows the app.php, and app_dev.php files to run, every other PHP file will get sent to the client as plain text, but you shouldn't be placing other PHP files there anyway, since you are using a front controller. It will be a problem if you use the the web based configurator (config.php) script though.

The differences between this and the config on the nginx wiki, is that the wiki's example includes two location directives, and some rewrite magic, that could be left out, and there is a fastcgi_split_path_info line, that is probably supposed to work around the vulnerability that I mentioned above, but since we are only allowing the app_dev.php, and app.php files in the document root to be executed, it is also unnecessary. There is also a line that deals with stripping the app.php from the URL if it is present, but it didn't seem to work for me (infinite redirect).

Upstream sent too big header while reading response header from upstream

If you get internal server errors for some pages, and see the above line in your logs, it means that the application is sending too many and/or too long headers. In Symfony, this is 99% of the time caused by FirePHP, since it sends everything in the headers. This is usually not a problem, since by default there are just a few lines of logs, but after you start writing loggers for your own logic, they might get fat, and nginx will choke on it. The solution is to include the two lines in your location block (adjust the numbers until it works):

fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;