Search

So, I bumped into some issues while trying to use Rowan's elegant Nginx config. I think the location block of Rowan's config didn't work well with my fastcgi_pass location block (below), and .php files were being served as downloads (!) instead of being passed to PHP.

# We ONLY execute scripts ending in .php for safety's sake.
location ~ (.*)?.php($|/) {

    # No tricks allowed
    if (!-f $request_filename) {
        return 404;
    }

    fastcgi_split_path_info ^(.+.php)(.*)$;
    fastcgi_pass            unix:/tmp/php5-fpm.sock;
    fastcgi_index           index.php;
    include                 templates/fastcgi-params.conf;
}

So after a bit of fighting I came up with this, which seems to behave quite well:

# Serve static files directly, otherwise pass as parameters
try_files $uri $uri/  /index.php?symphony-page=$uri&$args;

# Symphony admin redirects
location ~ ^/symphony(/?.*)$ {
    # If not requesting assest files...
    if (!-f $request_filename) {
        # ...internal redirect Symphony admin, which in turn will redirect to...
        rewrite ^/symphony/?$ /index.php?mode=administration&$query_string last;
        # ...some admin page.
        rewrite ^/symphony(/(.*/?))?$ /index.php?symphony-page=$1&mode=administration&$query_string last;
    }
}

# Any request to /image/ that is not a real file, send it to JIT. Just in case you have a real directory called "image" in the root.
location ~ ^/image/(.*)$ {
    try_files $uri $uri/ /extensions/jit_image_manipulation/lib/image.php?param=$1;
}

I have includes for other rules which don't necessarily pertain to Symphony 2, hence the minimalism of the above.

Hope it helps someone…

this is great! i've been mulling over nginx for about a month, so it's nice to see someone's still got it working with the newer versions of symphony.

thanks!

OK, took 10 minutes to "expand" the includes I mentioned before, here's the whole shebang.

NOTE: this config is normally split into multiple bits which are included or not depending on the site's needs. The following is the (fully expanded with includes) config I am using. I am not an Nginx expert, so there may be issues here and there, but it seems to work so far.

Gist: here.

CODE:

server {
    server_name     "~^((?<subdomain>www).)?(?<domain>location.com)$";
    index           index.php index.htm index.html default.asp;

    ## Performs 301 redirects to non-www plus other minor things.
    #include         templates/server.main.conf;
    # ----------------------------------------------------------------------->

    # set main domain root to _
    if ($subdomain = "") {
        set $subdomain _;
    }

    # Ditch www
    if ($subdomain ~ www) { rewrite ^(.*) http://$domain$1 permanent; }

    # favicon shitso
    rewrite ^/(.*)/favicon.ico$ /favicon.ico last;
    location ~* ^/favicon..*$ { try_files $uri @empty_gif; }
    location @empty_gif { empty_gif; }
    # <-----------------------------------------------------------------------




    # Set root and logs semi-automatically from the <named matches> above.
    root            /home/location/domains/$domain/$subdomain;
    access_log      /home/location/domains/.logs/$domain.$subdomain.access.log;
    error_log       /home/location/domains/.logs/$domain.$subdomain.error.log;




    ## include         templates/location.symphony2.conf;
    # ----------------------------------------------------------------------->
    # Serve static files directly, otherwise pass as parameters
    try_files $uri $uri/  /index.php?symphony-page=$uri&$args;

    # Symphony admin redirects
    location ~ ^/symphony(/?.*)$ {
        # If not requesting assest files...
        if (!-f $request_filename) {
            # ...internal redirect Symphony admin, which in turn will redirect to...
            rewrite ^/symphony/?$ /index.php?mode=administration&$query_string last;
            # ...some admin page.
            rewrite ^/symphony(/(.*/?))?$ /index.php?symphony-page=$1&mode=administration&$query_string last;
        }
    }

    # Any request to /images/ that is not a real file, send it to JIT
    location ~ ^/image/(.*)$ {
        try_files $uri $uri/ /extensions/jit_image_manipulation/lib/image.php?param=$1;
    }





    ## Pretty standard includes you might want to leave here.
    #include         templates/server.listen.local-only.conf;
    # ----------------------------------------------------------------------->
    listen 127.0.0.1:8081;





    #include         templates/gzip-settings.conf;
    # ----------------------------------------------------------------------->
    gzip  on;
    gzip_disable "msie6";
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types  text/plain
                text/css
                text/javascript
                text/xml
                application/json
                application/x-javascript
                application/xml
                application/xml+rss;

    # make sure gzip does not lose large gzipped js or css files (see http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl)
    gzip_buffers 16 8k;





    #include         templates/location.deny.conf;
    # ----------------------------------------------------------------------->
    location ~ /.ht {
        deny  all;
    }

    location ~ /.hg {
        deny  all;
    }

    location ~ /.git {
        deny  all;
    }





    #include         templates/server.nolog-assets.conf;
    # ----------------------------------------------------------------------->
    # this is proboably being overridden by previous location{} blocks, as Nginx stops at the first match if two collide.
    location ~* ^/.*.(jpe|g)|(gif)|(css)|(less)|(png)|(js)|(ico)$ {
      access_log        off;
      #log_not_found     off;
      expires           30d;
    }





    #include         templates/location.php5-socket.conf;
    # ----------------------------------------------------------------------->
    uninitialized_variable_warn off;



        #include templates/location.php5-security.conf;
        # ------------------------------------------------------------------->
        # should anyone manage to upload malicious PHP files, we block execution from some dirs.
        # these are usually upload dirs or static assets dirs
        location ~* ^(.*)?/uploads/(.*)?.php($|/)$ {return 403;}
        location ~* ^(.*)?/images/(.*)?.php($|/)$ {return 403;}
        location ~* ^(.*)?/videos/(.*)?.php($|/)$ {return 403;}
        location ~* ^(.*)?/media/(.*)?.php($|/)$ {return 403;}
        location ~* ^(.*)?/static/(.*)?.php($|/)$ {return 403;}
        location ~* ^(.*)?/web/(.*)?.php($|/)$ {return 403;}




    # We ONLY execute scripts ending in .php for safety's sake.
    location ~ (.*)?.php($|/) {

        # No tricks
        if (!-f $request_filename) {
            return 404;
        }

        fastcgi_split_path_info ^(.+.php)(.*)$;
        fastcgi_pass            unix:/tmp/php5-fpm.sock;
        fastcgi_index           index.php;
        #include                 templates/fastcgi-params.conf;
        # ------------------------------------------------------------------->
        fastcgi_param  SCRIPT_FILENAME      $document_root$fastcgi_script_name; # index.php or whatever is set as index
        fastcgi_param  QUERY_STRING         $query_string; # foo=123&bar=blahblah;

        # for POST requests                 
        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; # /foo/bar.php?arg=baz
        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/$nginx_version;

        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;

        # PHP only, required if PHP was built with --enable-force-cgi-redirect
        fastcgi_param  REDIRECT_STATUS      200;

        # This directive determines whether or not to transfer 4xx and 5xx errors back
        # to the client or to allow Nginx to answer with directive error_page
        fastcgi_intercept_errors            off;

        # This directive determines if current request to the FastCGI-server must be
        # aborted in case the client aborts the request to the server.
        fastcgi_ignore_client_abort         off;

        # Directive sets timeout period for connection with FastCGI-server.
        # It should be noted that this value can't exceed 75 seconds.
        fastcgi_connect_timeout             60;

        # Directive sets the amount of time for upstream to wait for a fastcgi process
        # to send data. Change this directive if you have long running fastcgi processes
        # that do not produce output until they have finished processing.
        # If you are seeing an upstream timed out error in the error log, then increase
        # this parameter to something more appropriate.
        fastcgi_send_timeout                180;
        fastcgi_read_timeout                180;

        # Sets the buffer size to 16k + 256 * 16k = 4112k. Anything greater than 4M
        # goes to disk
        fastcgi_buffers                     8 256k;

        # By default, the buffer size is equal to the size of one buffer in
        # fastcgi_buffers. This directive allows you to set it to an arbitrary value.
        fastcgi_buffer_size                 128k;

        #fastcgi_busy_buffers_size           256k;
        #fastcgi_temp_file_write_size        256k;
    }
}

Great config! I am considering moving from apache+mod_fcgi+apc to nginx+fcgi+apc to run our symphony site. One question regarding memory footprint ... My php5-cgi processes are about 28M and I can handle about 250 concurrent connections on a 8G machine. Should I expect the same memory footprint with nginx? Any way to reduce the per cgi foot print (probably a function of php app, php interpreter, synphony, apc).

You should use PHP5-fpm with Nginx. Although PHP's memory consumption per-worker won't decrease I believe.
Nginx uses a fraction of the memory and processor than any comparable Apache flavour. On top of that, the HttpFcgiModule module has some nice settings for caching or even mirroring the CGI server responses.

We use Apache only on one machine and only for WebDAV access. Everything else is a chain of
HAProxy --> Nginx --> PHP5-fpm --> MySQL or
HAProxy -->Node.js --> Redis
Or whatever... but not Apache, especially on small machines.

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details