Nginx, new config (once again :)
This is an open discussion with 4 replies, filed under General.
Search
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.
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.So after a bit of fighting I came up with this, which seems to behave quite well:
I have
include
s for other rules which don't necessarily pertain to Symphony 2, hence the minimalism of the above.Hope it helps someone…