Matrix on Nginx + PHP FastCGI


(Dan Simmons) #1

Hello there.


One day I was curious about different server architectures for running Matrix. I wanted to set up Matrix on Nginx with PHP FastCGI, to see how easy it would be, and also compare performance against Apache2 with PHP compiled as a module.



I haven’t had a chance to do comprehensive performance tests (I haven’t really had the time or proper testing conditions) but I thought I might post the Nginx configuration I had to come up with, as it required some minor tweaking and might benefit others.



/etc/nginx/sites/matrix.conf

[codebox]server {

listen xxx.xxx.xxx.xxx:80;

server_name your.hostname;



# Logging

access_log /var/log/nginx/matrix.access.log;

error_log /var/log/nginx/matrix.error.log;



# Save the original script URI in a variable before we rewrite it (we need to

# pass the original URI onto FastCGI later for Matrix’s sake).

#

set $orig_uri $uri;



location / {

root /var/www/matrix/core/web;

index index.php index.html;



# Rewrite ALL requests to Matrix’s index.php file

rewrite ^(.*)$ /index.php last;

}



# access_log off; prevents logging of these hits to the access log (you may or may not want this)

location /__data/ { alias /var/www/matrix/data/public/; }

location /__lib/ { access_log off; alias /var/www/matrix/core/lib/; }

location /__fudge/ { access_log off; alias /var/www/matrix/fudge/; }



location ~ .php$ {

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;



fastcgi_param SCRIPT_FILENAME /var/www/matrix/core/web$fastcgi_script_name;



# Modified for Matrix

fastcgi_param PHP_SELF $request_uri;

fastcgi_param PATH_INFO $orig_uri;

fastcgi_param SCRIPT_NAME $orig_uri;



# Some defaults

fastcgi_param QUERY_STRING $query_string;

fastcgi_param REQUEST_METHOD $request_method;

fastcgi_param CONTENT_TYPE $content_type;

fastcgi_param CONTENT_LENGTH $content_length;



#fastcgi_param SCRIPT_NAME $fastcgi_script_name;

fastcgi_param REQUEST_URI $request_uri;

fastcgi_param DOCUMENT_URI $document_uri;

fastcgi_param DOCUMENT_ROOT $document_root;

fastcgi_param SERVER_PROTOCOL $server_protocol;



fastcgi_param GATEWAY_INTERFACE CGI/1.1;

fastcgi_param SERVER_SOFTWARE nginx;



fastcgi_param REMOTE_ADDR $remote_addr;

fastcgi_param REMOTE_PORT $remote_port;

fastcgi_param SERVER_ADDR $server_addr;

fastcgi_param SERVER_PORT $server_port;

fastcgi_param SERVER_NAME $server_name;

}

}

[/codebox]



Most notably above, we save the original request URI in a variable so it can be passed to Matrix later (as Matrix needs this to determine hostname and path information).



Also, if you do get onto this track, see here for handy Debian Init script to spawn PHP FastCGI:

http://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg352883.html

http://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg352883.html



Splitting up application processing onto separate servers is something that probably wouldn’t be needed for most of the people using Matrix out there, but it’s exciting to think that this type of configuration could be used in all sorts of ways (eg. have dedicated application/database servers for running searches or similar).


(Rob) #2

I've been trying to implement Nginx + PHP FastCGI too.


I've installed nginx and have configured PHP using spawn-fcgi.

With the most basic of nginx config I can get a phpinfo{} to confirm at all is running with FastCGI as expected.



With a more complex config, most of it copied from this post, I can only get a partial page load. Not all URLs are being handled correctly by the rewrite condition (I think).



from the ngnix access logs…



This is a hit! I get the content.

    "GET /__data/assets/image/0019/63442/BHL.jpg HTTP/1.1" 304 0 "http://www..com/"


This is a miss! I don't get the content.
"GET /_designs/intelligence-squared/css/main_style.css HTTP/1.1" 404 31 "http://www.<my site>.com/"

Here is my nginx conf file:

    server {
        listen       172.16.41.10:80;
        server_name  www..com;
    # Logging
    access_log  /var/log/nginx/matrix.access.log;
    error_log  /var/log/nginx/matrix.error.log;

    # Save the original script URI in a variable before we rewrite it (we need to
    # pass the original URI onto FastCGI later for Matrix's sake).
    #
    set $orig_uri $uri;

    location / {
            root   /srv/www/matrix/core/web;
            index  index.php;

            # Rewrite ALL requests to Matrix's index.php file
            rewrite  ^(.*)$  /index.php  last;
    }

    # access_log off; prevents logging of these hits to the access log (you may or may not want this)
    location /__data/       { alias /srv/www/iq2_matrix/data/public/; }
    location /__lib/        { access_log off; alias /srv/www/iq2_matrix/core/lib/; }
    location /__fudge/      { access_log off; alias /srv/www/iq2_matrix/fudge/; }


    location ~ .php$ {
            fastcgi_pass   php5;
            fastcgi_index  index.php;

            fastcgi_param   SCRIPT_FILENAME /srv/www/matrix/core/web/$fastcgi_script_name;
            # Modified for Matrix
            fastcgi_param   PHP_SELF        $request_uri;
            fastcgi_param   PATH_INFO       $orig_uri;
            fastcgi_param   SCRIPT_NAME     $orig_uri;

            # Some defaults
            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            #fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;

            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;
    }
}</pre>

(Rob) #3

It's definitely something to do with the rewrite of the file pathways.


Accessing http://www.<my site>.com/_admin and logging in results in


    http://www..com/_admin/_admin/_admin/_admin//_admin/_admin/_admin/_admin/?


and this in the access logs.....

    "GET /__data/asset_types/system_user/icon.png HTTP/1.1" 200 639 "http://www..com/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/_admin/?SQ_BACKEND_PAGE=main" "Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8"

(Rhulse) #4

Hi Rob,


In reply to your DM, we are not using nginx/fastcgi for Matrix. nginx is running as a proxy for 3 reasons:


  1. We can gzip content as it passes through.



    Prior to upgrading our hardware, the old box was under such high load that we could not gzip html content.



    nginx can do this much fast and with less load than apache


  2. We run a static domain (radionz.net.nz)



    This serves all our __data cotent and we have custom setting for the html headers to ensure this content is publicly cacheable for as long as possible.


  3. Not really relevant here, but we can send requests to other applications.



    For example everything under /genre/recipes, /national/schedules, /concert/schedules, /news and the home page (/) is served by a Rails application (check the source).





    What is you reason for interest in using nginx? Depending on the hardware you may not see much (if any improvement).





    cheers,



    Richard

(Dw Andrew) #5

I have tried this and got it to a partially working stage (most things would render), but barely saw any gains. I got as much gain, or more by just installing APC. Will be interesting to see what you can put together :slight_smile:


The main advantage I think would be you could run matrix on much lower hardware, in comparison apache is a huge hog. Keep us updated!


(Anton Babushkin) #6

Can anyone explain what the PATH_INFO variable is used for by Matrix?


In my configuration of nginx, I found sending that variable would cause the following URL to load: http://mypage.com/test-page/test-page rather than http://mypage.com/test-page.



After removing that reference my rendering would work perfectly fine.