This is a short tutorial on how to get Friendica up and running in no time with Nginx.

Any questions you have, you can consult the great docs at the Nginx wiki.

First, I'll paste in a snippet of my own configuration, explain the context, then briefly explain the parts.

location /fd/ {
    index index.php;
    if (!-f $request_filename) {
        rewrite ^/fd/(.+)$ /fd/index.php?q=$1 last;
    try_files $uri $uri/ =404;

This little section appears in a virtual host I have for the sub-domain my friendica appears on. I've already define where the document root is, previously in the file:

root /path/to/your/public_html/;

This is usually arranged by domain, sub-domain, then sub-directories, or similar set up. The root stanza is important for things like php, any cgi scripts you may have, etc.

I also have a location set for handling calls to php files, and passing them off to php5-fpm. If you can get FPM, do so, it makes life easier. On Debian, I think you can get it in backports ( for Squeeze (stable as of this writing). Wheezy (testing) and Sid (unstable) already have them. aptitude install php5-fpm

You need to have FPM configured so it listens somewhere, preferably on a unix socket, or on localhost (, or elsewhere if that's your set up. Nginx needs to find this, obviously, so configure it so it passes those requests along to FPM.

location ~* \.php {
    include fastcgi_params;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param HTTPS on;
    fastcgi_index index.php;
    try_files $uri $uri/ =404;

This is only an example, if you have issues with 404s, comment out the try_files stanza, especially if your FPM is listening on another machine. Then cross your fingers as there's security implications.

You can do something like this:

location ~ \..*/.*\.php$ {
    return 403;

To secure it a bit more. These last two you can insert in one of your global files, if you have many virtual hosts. This means, "if there's a request for /somewhere/../file.php, send a 403".

If you like you can add various location segments to handle expiry of images, CSS, scripts, so browsers will handle those better, and not end up having to go through php to get handled, which causes a LOT of slowdown, and possible 404s. This is what the try_files is for, it's to handle various little things like CSS, images, and scripts.

OK, so we have the first location segment, above, where we configure nginx to handle a sub-directory in our public HTML (AKA document root) a certain way.

The nginx docs say not to use ifs, or as little as possible, but I found that it works seamlessly if I handle both php and regular files in the one segment for Friendica, especially in this particular set up I have. You may find that this won't work for you. If not I refer you to their wiki. It was a great help to me when learning the intricacies of this httpd.

The if statement means that if there's no file by that name, pass it to the following, i.e. the index.php in the friendica directory.

You'll note that I have a a fastcgi_split_path_info there. That's for broken php applications who haven't gone past PATH_INFO yet :P. For most applications nowadays, only the rewrite /foo/(.+)$ /foo/index.php?q=$1 last; is the core statement. There's other ways of handling that, too. You might consider using .+ instead of .* in your regex, as .+ means that look for one or more characters, and .* is zero or more. It's a little thing, but can help secure things a bit too.

If it doesn't work first try, check for typos, misplaced directories, wrong ports, and try turning on debug logging and tail the error.log; on Debian, debug logging in enabled in the build. Also you may want to enable 404 logging as well for this.

I have 2 configured error logs, one is always commented out, for easy switching. This part is in the main nginx.conf:

http {
    log_not_found off; # on/off; 404s
    log_subrequest off; # on/off; default off - useful for debug IMO
    error_log /var/log/nginx/error.log;
    #error_log /var/log/nginx/error.log debug;

Mind you, I often do this on-the-fly ;-). If you have development server, go ahead and use that, then deploy to your production server.