Nginx

= Overview =

The main nginx wiki article describes this software well:

Nginx is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Written by Igor Sysoev in 2005, Nginx now hosts nearly 6% (13M) of all domains worldwide.

Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.

Nginx is one of a handful of servers written to address the C10K problem. Unlike traditional servers, Nginx doesn't rely on threads to handle requests. Instead it uses a much more scalable event-driven (asynchronous) architecture. This architecture uses small, but most importantly, predictable amounts of memory under load. Even if you don't expect to handle thousands of simultaneous requests, you can still benefit from Nginx's high-performance and small memory footprint. Nginx scales in all directions: from the smallest VPS all the way up to clusters of servers.

Nginx powers several high-visibility sites, such as WordPress, Hulu, Github, Ohloh, SourceForge and TorrentReactor.

Nginx is available on DreamHost Private Servers as an optional web server to run your sites. Older Private Servers may need to be moved to the new cluster for this feature to work out-of-the-box. If the feature is not available as described below, then you can write in to tech support to get your PS moved to a newer server that supports it.

Why nginx?
So, all DreamHost Private Servers use Apache by default. That's good enough, right? Well, yes and no. A very well tuned Apache server can certainly hold its own, but that can be difficult to do and requires a fair amount of knowledge/tinkering. Most people wanting a PS are interested in better performance because they've outgrown shared servers. Nginx is a very good choice in cases where you have a blog or other site that gets large volumes of traffic and are running into performance/memory issues on a PS for the reasons mentioned in the quote above. Basically, in general, it will serve your site faster while using less memory than Apache -- which will let you handle a much larger amount of traffic much more gracefully than Apache would. For a more detailed look at this, take a look at the Web Server Performance Comparison page.

Why doesn't DreamHost use nginx by default then?!
Inquiring minds want to know!! Well, the reason for that is really quite simple. Practically every piece of web software in existence expects to be served using Apache. Generally, that means this software uses htaccess for various and sundry things. For instance, an out-of-the-box WordPress installation will work fine with nginx. However, if you turn permalinks on, suddenly links to your posts will break. Why? Permalinks generate htaccess rewrite rules that route requests to the index.php file that will then translate nice looking URLs like http://www.someblog.com/2009/12/some-article/ into something that WordPress knows how to work with. Note that nginx does not read .htaccess files! As such, most web software that utilizes them will be "broken" immediately upon installation without additional work.

= PHP, Nginx, and You =

One thing to keep in mind before enabling Nginx is how PHP is handled with it. When using Nginx a set number of PHP processes are started up for every user a domain is hosted under. The same number are started regardless of how many domains are hosted for it. As such, if you have 10 domains spread across 10 separate FTP users you'll get 10x as many PHP processes as you would otherwise get. So, if Nginx is starting up 5 PHP processes, you would end up with 50, which would eat up a considerable amount of memory. The best configuration when using Nginx is to consolidate your domains under one FTP user. You should definitely do this prior to switching to Nginx. Also keep in mind that the number of PHP processes that spawn per user is automatically scaled with the amount of memory your PS is set to use, so increasing your PS's memory allocation

Limiting the amount of processes spawned per domain

 * Globally - With an admin user and sudo, place  into , where 8 is the number of desired processes per domain.


 * Per-user - Create  as an executable (chmod a+x) script containing the following, where 8 is the number of desired processes per domain:

export PHP_FCGI_CHILDREN=8 exec /dh/cgi-system/php5.cgi $*
 * 1) !/bin/sh

(Note: The "Globally" method seemed to produce a 'ulimit' error for me which won't go away, even if I revert the file. The "Per-user" method, however, with a value of 2 reduced my memory footprint from 1.3 GB to 130 megs. This should be done by DH by default... seems like a huge waste without it.)

Customizing PHP under Nginx
Dreamhost has a few bits of custom logic in their nginx init script to allow PHP customization:


 * If you have a file at $HOME/.php-ini, it's used in place of the system php.ini.
 * If you have an executable at $HOME/.php-launcher, it's used instead of the default PHP binary.

Running PHP 5.3 or 5.4 under Nginx
To change the version of PHP that runs, you need to do 2 things:
 * 1) Edit or create $HOME/.php-launcher to run the version of PHP you want:
 * exec /dh/cgi-system/php53.cgi $*
 * exec /dh/cgi-system/php54.cgi $*
 * 1) * Note - you will also need to give the .php-launcher file the user execution bit using this command (or something similar to it):
 * chmod u+x $HOME/.php-launcher
 * 1) Link $HOME/.php-ini with the php.ini for the correct PHP version by either executing the following command:
 * ln -s /etc/php53/php.ini .php-ini
 * ln -s /etc/php54/php.ini .php-ini
 * 1) * Or create a copy of the DreamHost php.ini file using this command
 * cp /etc/php53/php.ini .php-ini
 * cp /etc/php54/php.ini .php-ini

Once you have done those two things, you need to restart PHP (which you can do using the command below) or the nginx server or the entire VPS. sudo /etc/init.d/nginx restartphp

= Enabling Nginx =

So, you know the benefits and the downside to using nginx now and want to proceed anyways. This is how! Before proceeding, you may want to read through the entire guide to make preparations beforehand to avoid potential downtime due to not having the necessary configuration settings in place. Also keep in mind that enabling this will do so for all domains on your PS!

Browse to the Private Servers -> Configure Server area of your webpanel and switch the HTTP Server to nginx (if this option isn't available, contact support and ask if your PS can be moved to a newer server):



That's it! After a few minutes your PS will be running with nginx rather than Apache.

= Configuration File Locations =

The default nginx configuration will likely work for most people out-of-the-box. If you want to look at it though, you can find it here:

/dh/nginx/servers/httpd-psXXXXXX/nginx.conf

You cannot work with this file through FileZilla or similar SFTP tools, you must use SSH and pico to view/edit.

sudo pico /dh/nginx/servers/httpd-psXXXXXX/nginx.conf

Where "psXXXXXX" is your PS. Note that you'll need an admin user created with sudo privileges to access that directory. The defaults in there will be fine. Each domain has a directory that the default nginx.conf will load files from when nginx starts. These directories will follow this naming convention:

/home/YOURUSER/nginx/YOURDOMAIN.COM/*

Where "YOURUSER" is (surprise, surprise) the user your site is hosted under and "YOURDOMAIN.COM" is your domain or subdomain. The nginx directory mentioned above may, or may not exist. If it doesn't, simply create it like so:

cd ~ mkdir -p nginx/yourdomain.com

Create new .conf files in this directory to customize your nginx server. All of the entries in this file get "inserted" into the SERVER block of the default nginx.conf.

Whenever you make changes to these files make sure you reload nginx with your admin user to make sure there aren't syntax issues that will bite you later!

sudo /etc/init.d/nginx reload

Create new .conf files in this directory to customize your nginx server. All of the entries in this file get "inserted" into the SERVER block of the default nginx.conf.

= Nginx and Custom PHP Install =

When you install your own version of php, such as one that DreamHost doesn't support with Nginx (such as php 5.4.X) you need a way to start/stop nginx and php.

Quick php install:

sudo ./configure --prefix=/home/example/php --enable-sockets --with-curl --enable-mbstring --with-mysql --with-gd sudo make sudo make install

Next copy the following script into

BIND=/home/username/.php.sock     # Binds to the socket USER=username                     # User that will own this process PHP_FCGI_CHILDREN=15              # Number of php children PHP_FCGI_MAX_REQUESTS=1000        # Number of max requests per child PHP_DIR=/home/username/php/bin    # Location of your php install PHP_CGI=$PHP_DIR/php-cgi          # Location of php-cgi PHP_CGI_NAME=`basename $PHP_CGI` PHP_CGI_ARGS="- USER=$USER PATH=$PHP_DIR PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND" RETVAL=0 start { echo -n "Starting Nginx: " /etc/init.d/nginx start echo -n "Starting PHP FastCGI: " start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS RETVAL=$? echo "$PHP_CGI_NAME." } stop { echo -n "Stopping Nginx: " /etc/init.d/nginx stop echo -n "Stopping PHP FastCGI: " killall -q -w -u $USER $PHP_CGI RETVAL=$? echo "$PHP_CGI_NAME." } case "$1" in   start)      start  ;;    stop) stop ;;   restart)      stop      start  ;;    *) echo "Usage: php-fastcgi {start|stop|restart}" exit 1 ;; esac exit $RETVAL
 * 1) !/bin/bash

You now can use one of the following commands (depending on your goal) to start, stop, or restart the server:

sudo /etc/init.d/php-fastcgi start sudo /etc/init.d/php-fastcgi stop sudo /etc/init.d/php-fastcgi restart

= Nginx Configurations for Common Web Applications =

That's great and all, but let's get down to business! You have a web application that needs some tender love and affection to get running with nginx! Below are some of the most common use cases. In all examples, we'll assume a domain named example.com exists and is the site we're setting this configuration up for. Also, note that any line prefaced with a "#" is a comment.

WordPress
This is probably the most used web application around and it works great with nginx! Before we get going here, you should create a  file (the name doesn't really matter, but generally you want to at least give it a .conf extension) in the following location:

/home/YOURUSER/nginx/example.com/

Like so:

nano /home/YOURUSER/nginx/example.com/wordpress.conf

This is where you'll put all your nginx config rules.

If you are going to share wordpress configuration across multiple sites, you can create a default file and then create symlinks for each of your sites, like so:

mkdir -p /home/YOURUSER/nginx/default-wp/ nano /home/YOURUSER/nginx/default-wp/wordpress.conf ln -s /home/YOURUSER/nginx/default-wp/ /home/YOURUSER/nginx/example.com ln -s /home/YOURUSER/nginx/default-wp/ /home/YOURUSER/nginx/example2.com

Permalinks
The most basic set of WordPress rules that will get you up and running immediately are these:

if (!-e $request_filename) { rewrite ^.*$ /index.php last; }
 * 1) Permalinks
 * 1) Permalinks

That will get all basic WordPress functionality going in terms of permalinks.

An alternate approach, which does not use 'if', is as follows:

try_files $uri $uri/ /index.php?$args;
 * 1) Permalinks
 * 1) Permalinks

Multisite
If you're using Multisite, you will need slightly more advanced rules:

if (!-e $request_filename) { rewrite ^/files(.*) /wp-includes/ms-files.php?file=$1 last; rewrite ^(/[^/]+)?(/wp-.*) $2 last; rewrite ^(/[^/]+)?(/.*.php) $2 last; rewrite ^.*$ /index.php last; }
 * 1) Permalinks
 * 1) Permalinks

This will provide basic functionality for Multisite.

W3 Total Cache
The W3 Total Cache plugin for Wordpress will automatically recognize that it is running under Nginx and will create a default Nginx configuration file which you can copy into your /nginx/ / directory.

W3 Total Cache should also be setup to use XCache: For the W3 settings, I basically turned on XCache support in my dreamhost config panel, then used it everywhere in the W3 settings. Then I enabled the Page Cache, Object Cache, and Browser Cache modules. All three are set to use the XCache to hold their data, so the cached info is stored in RAM, basically.

The Page Cache does whole-page caching, and is nice and fast for repeated queries to the same pages, for logged in or anon users.

The Object Cache does object caching, and causes my admin section to be nice and speedy, since things like posts and such are pulled from memory instead of the database.

The Browser Cache basically just sets the proper expire headers on everything, thus images and such don’t have to be redownloaded all the time. (Snarfed from here)

WP Super Cache
If you're using the WP Super Cache plugin, you'll want to use the following in place of the permalink rules above:

if (-f $request_filename) { break; } set $supercache_file '' ; set $supercache_uri $request_uri; if ($request_method = POST) { set $supercache_uri '' ; } if ($query_string) { set $supercache_uri '' ; } if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) { set $supercache_uri '' ; } if ($supercache_uri ~ ^(.+)$) { set $supercache_file /wp-content/cache/supercache/$http_host$1/index.html; } if (-f $document_root$supercache_file) { rewrite ^(.*)$ $supercache_file break; } if (!-e $request_filename) { rewrite ^.*$ /index.php last; }
 * 1) WP Super Cache
 * 1) WP Super Cache
 * 1) if the requested file exists, return it immediately
 * 1) Using pretty permalinks, so bypass the cache for any query string
 * 1) if we haven't bypassed the cache, specify our supercache file
 * 1) only rewrite to the supercache file if it actually exists
 * 1) all other requests go to Wordpress

FeedBurner
If you have your blog's RSS feed setup using FeedBurner, you'll want to add the following lines above the permalink or supercache lines mentioned previously:

if ($http_user_agent !~ FeedBurner) { rewrite ^/comment/feed/ http://feeds.feedburner.com/your-comment-feed last; rewrite ^/feed/ http://feeds.feedburner.com/your-feed last; }
 * 1) FeedBurner
 * 1) FeedBurner

You'll need to replace the "your-comment-feed" and "your-feed" bits with the appropriate FeedBurner URLs you get when you add your feeds to their system.

Drupal
Before we get going here, you should create a  file (the name doesn't really matter, but generally you want to at least give it a .conf extension) in the following location:

/home/YOURUSER/nginx/example.com/

Like so:

nano /home/YOURUSER/nginx/example.com/drupal.conf

This is where you'll put all your nginx config rules.

Top Level Domain Install
If your Drupal is installed at the top level of your domain (i.e., http://www.example.com/ is your Drupal install), then you want to add these rules:


 * 1) Drupal Clean URLs (Top Level Domain)
 * 1) Drupal Clean URLs (Top Level Domain)

if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?q=$1 last; }

Subdirectory Install
If your Drupal is installed in a subdirectory (i.e., http://www.example.com/drupal/ is your Drupal install), then you want to add these rules:


 * 1) Drupal Clean URLs (Subdirectory)
 * 1) Drupal Clean URLs (Subdirectory)

if (!-e $request_filename) { rewrite ^/drupal$ /drupal/ permanent; rewrite ^/drupal/(.*)$ /drupal/index.php?q=$1 last; rewrite ^/(.*)$ /index.php?q=$1 last; }

You would replace occurrences of "drupal" in the above with whatever your subdirectory is named.

Enable Clean URLs
If you haven't already, you need to login to your Drupal admin user and go to the Administer -> Site Configuration -> Clean URLs area and turn Clean URLs on. If you have trouble finding it, then try browsing to http://www.example.com/index.php?q=admin/settings/clean-urls. If you get an error message saying Clean URLs aren't supported, make sure you remembered to reload your nginx configuration as discussed earlier in the article.

Gotchas
Unfortunately, this configuration currently causes site searches that contain spaces to break. With Apache, when you search for "some thing" that gets converted to "search/node/some+thing". When this is processed by nginx the "+" gets encoded so you end up with "search/node/some%20thing". Thus, your search ends up looking for the string "some+thing" rather than "some thing". There are currently no known workarounds that were forthcoming.

Drupal 6 with Boost, Clean URLs
For this setup I had moved my drupal site off of apache to nginx. Been very happy with the performance. Getting drupal to work was easy but a little slow. I also wanted the drupal module boost to work as well. This here is the config file for my site exactly as it is. I will explain each section. First here is the entire config file located in /home/YOURUSER/nginx/example.com/drupal.conf


 * 1) nginx.conf catch-all
 * 1) nginx.conf catch-all

client_max_body_size 75M; gzip_static on; gzip on; gzip_comp_level 9; gzip_types application/x-javascript text/css text/plain text/xml application/xml application/xml+rss text/javascript;

location ~ \.(gif|jpg|jpeg|png|tif|bmp|jpe)$ {

valid_referers server_names none blocked ~(pcwintech.com|google.|simpleportforwarding.com);

if ($invalid_referer) {

rewrite ^ http://$host/showimage?file=${uri} permanent; }

}

location ~ \.(exe|zip|reg|vbs)$ {

valid_referers server_names none blocked ~(pcwintech.com|google.|simpleportforwarding.com);

if ($invalid_referer) {

rewrite ^ http://$host? permanent; }

}

location = /favicon.ico { log_not_found off; access_log off; }

location = /robots.txt { allow all; log_not_found off; access_log off; }

location ~* ^.+(\.(txt|engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)|code-style\.pl|/Entries.*|/Repository|/Root|/Tag|/Template)$ { return 404; }
 * 1) This is mostly based on Drupal's stock .htaccess

location ~* ^.+\.(jpg|jpeg|gif|png|ico|swf|flv)$ { access_log off; expires 30d; }
 * 1) serve static files directly

location ~* \.(txt|log)$ { allow 192.168.0.0/16; deny all; }
 * 1) Very rarely should these ever be accessed outside of your lan

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

if ($http_user_agent ~* (HTTrack|HTMLParser|libwww) ) { return 444; } if ($http_referer ~* (poker|sex|girl) ) { return 444; } if ($host = 'pcwintech.com' ) { rewrite ^/(.*)$ http://www.pcwintech.com/$1 permanent; }
 * 1) Deny some crawlers
 * 1) Deny certain Referers (case insensitive)
 * 1) www. redirect

location ~* ^/og { rewrite ^/og\-(.*)/ajax_comments/(.*)$ /index.php?q=ajax_comments/$2 last; rewrite ^/og\-(.*)/context/ajax-block-view$ /index.php?q=context/ajax-block-view last; rewrite ^/og\-(.*)/comment/reply/(.*)\?reload=1$ /index.php?q=comment/reply/$2&reload=1 last; rewrite ^/og\-(.*)/node/([0-9]+)/toggle/(.*)$ /index.php?q=node/$2/toggle/$3 last; rewrite ^/og\-(.*)/node/([0-9]+)/edit\?(.*)$ /index.php?q=node/$2/edit?$3 last; rewrite ^/og\-(.*)/user/([0-9]+)/watcher/toggle/(.*)$ /index.php?q=user/$2/watcher/toggle/$3 last; rewrite ^/(.*)$ /index.php?q=$1 last; }
 * 1) required only when using purl, spaces & og for modules: ajax_comments, watcher and fasttoggle
 * 2) the /og path should be modified to match your default for og/purl URL for organic groups
 * 1) the /og path should be modified to match your default for og/purl URL for organic groups

location / { deny 1.2.3.4; deny 83.228.199.228; deny 194.8.75.141; deny 84.122.26.246; deny 194.8.75.0/24; deny 194.8.74.0/24; try_files $uri @cache; }
 * 1) 6.x starts
 * 1) rewrite ^/(.*)/$ /$1 permanent; # remove trailing slashes - disabled

location @cache { if ( $request_method !~ ^(GET|HEAD)$ ) { return 405; } if ($http_cookie ~ "DRUPAL_UID") { return 405; } error_page 405 = @drupal; add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT"; add_header Cache-Control "must-revalidate, post-check=0, pre-check=0"; add_header X-Header "Boost Citrus 1.9"; charset utf-8; try_files /cache/normal/$host${uri}_$args.html /cache/$host${uri}_$args.html @drupal; }

location @drupal { rewrite ^/(.*)$ /index.php?q=$1 last; }
 * 1) now simplified to reduce rewrites
 * 1) now simplified to reduce rewrites

location ~* (/\..*|settings\.php$|\.(htaccess|engine|inc|info|install|module|profile|pl|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(Entries.*|Repository|Root|Tag|Template))$ { deny all; }

location ~* /files/.*\.php$ { return 444; } location ~* /themes/.*\.php$ { return 444; }

location ~ \.css$ { if ( $request_method !~ ^(GET|HEAD)$ ) { return 405; } if ($http_cookie ~ "DRUPAL_UID") { return 405; } error_page 405 = @uncached; access_log off; expires max; #if using aggregator add_header X-Header "Boost Citrus 2.1"; try_files /cache/perm/$host${uri}_.css /cache/$host${uri}_.css $uri =404; }

location ~ \.js$ { if ( $request_method !~ ^(GET|HEAD)$ ) { return 405; } if ($http_cookie ~ "DRUPAL_UID") { return 405; } error_page 405 = @uncached; access_log off; expires max; # if using aggregator add_header X-Header "Boost Citrus 2.2"; try_files /cache/perm/$host${uri}_.js /cache/$host${uri}_.js $uri =404; }

location ~ \.json$ { if ( $request_method !~ ^(GET|HEAD)$ ) { return 405; } if ($http_cookie ~ "DRUPAL_UID") { return 405; } error_page 405 = @uncached; access_log off; expires max; # if using aggregator add_header X-Header "Boost Citrus 2.3"; try_files /cache/normal/$host${uri}_.json /cache/$host${uri}_.json $uri =404; }

location @uncached { access_log off; expires max; # max if using aggregator, otherwise sane expire time }

location ~* /files/imagecache/ { access_log off; try_files $uri @drupal; #imagecache support - now it works }

location ~* ^.+\.(jpg|jpeg|gif|png|ico)$ { access_log off; expires 30d; try_files $uri =404; }

location ~* \.xml$ { if ( $request_method !~ ^(GET|HEAD)$ ) { return 405; } if ($http_cookie ~ "DRUPAL_UID") { return 405; } error_page 405 = @drupal; add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT"; add_header Cache-Control "must-revalidate, post-check=0, pre-check=0"; add_header X-Header "Boost Citrus 2.4"; charset utf-8; types { } default_type application/rss+xml; try_files /cache/normal/$host${uri}_.xml /cache/normal/$host${uri}_.html /cache/$host${uri}_.xml $uri @drupal; }

location ~* /feed$ { if ( $request_method !~ ^(GET|HEAD)$ ) { return 405; } if ($http_cookie ~ "DRUPAL_UID") { return 405; } error_page 405 = @drupal; add_header Expires "Tue, 24 Jan 1984 08:00:00 GMT"; add_header Cache-Control "must-revalidate, post-check=0, pre-check=0"; add_header X-Header "Boost Citrus 2.5"; charset utf-8; types { } default_type application/rss+xml; try_files /cache/normal/$host${uri}_.xml /cache/normal/$host${uri}_.html /cache/$host${uri}_.xml $uri @drupal; }


 * 1) nginx.conf catch-all
 * 1) nginx.conf catch-all

A lot of the code in the config file already has explanations for them, so I wont cover all of them..

location ~ \.(gif|jpg|jpeg|png|tif|bmp|jpe)$ {

valid_referers server_names none blocked ~(pcwintech.com|google.|simpleportforwarding.com);

if ($invalid_referer) {

rewrite ^ http://$host/showimage?file=${uri} permanent; }

}

location ~ \.(css|exe|zip|reg|vbs)$ {

valid_referers server_names none blocked ~(pcwintech.com|google.|simpleportforwarding.com);

if ($invalid_referer) {

rewrite ^ http://$host? permanent; }

}

These prevent hot linking to the site. For the Pictures I have them being redirected to a showimage page on the site. I have allowed my sites and goole access to them. All others will be redirected. On the zip and exe files they will be redirected to the sites home page instead.

You will notice ~(pcwintech.com|google.|simpleportforwarding.com) this allows for all sub domains of my site in. like forums.pcwintech.com and www.pcwintech.com On the google one this allows all subdomains and main domains like google.com or google.uk

if ($host = 'pcwintech.com' ) { rewrite ^/(.*)$ http://www.pcwintech.com/$1 permanent; }
 * 1) www. redirect

This will redirect to the www part of the site. so if a user comes to pcwintech.com they will be redirected to www.pcwintech.com

location / { deny 1.2.3.4; deny 83.228.199.228; deny 194.8.75.141; deny 84.122.26.246; deny 194.8.75.0/24; deny 194.8.74.0/24; try_files $uri @cache; }
 * 1) 6.x starts
 * 1) rewrite ^/(.*)/$ /$1 permanent; # remove trailing slashes - disabled

this section is used for boost, but also where I put the deny IPs rules. As you see deny 83.228.199.228; will block that IP where deny 194.8.75.0/24; will block the whole range of IPs. This config file should work as is for you. Make sure to change the domain in the config file to yours. This is where drupal is the top level domain, has boost enabled and clean urls. After this config the performance picked up a good amount and has been running very smooth. --Shane 17:14, 25 November 2010 (UTC)

MediaWiki
MediaWiki is a popular wiki software running this wiki and many others. It was developed by the founders of Wikipedia - which continues to use and maintain the software today. It is available for free and an open-source project. I moved a MediaWiki 1.17.0 site (using Clean URLs) off of Apache to nginx. First, create an  file in the appropriate directory:

/home/YOURUSER/nginx/example.com/mediawiki.conf

location / { try_files $uri $uri/ /index.php; } location /cache { deny all; } location ~* ^.+\.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; access_log off; } location /dumps { root /home/YOURUSER/example.com/local; autoindex on; } if ($request_uri ~* ^/(stats|failed_auth\.html).*$) {	break; }
 * 1) Dreamhost analog stats

--Varnent 21:28, 24 July 2011 (PDT)

Increase FastCGI Timeout
Put this in a .conf file as described above

fastcgi_read_timeout 120;

Source: https://www.phpbb.com/community/viewtopic.php?f=46&t=1778165#p10746575

Sending Mass E-Mail Settings
If you want to send mass emails with SMTP authentication you have to use POP-BEFORE-SMTP as the "Authentication method for SMTP".

JHeckman (talk) 22:51, 25 January 2013 (PST)

= Password Protecting Directories =

Unfortunately, the Htaccess / WebDAV section of the webpanel doesn't work with nginx -- including the password protection bit. Fortunately, that doesn't mean you can't password protect directories! You just have to do it the old fashioned way. First, create a  file in the appropriate directory:

/home/YOURUSER/nginx/example.com/basic_auth.conf

Then add the following content:

location / { auth_basic "Restricted"; auth_basic_user_file /home/YOURUSER/example.com/.htpasswd; }

The  parameter is just the title of the prompt the user is hit with. The  parameter specifies where the password file is. This password file is the same sort Apache uses. Now, you need to actually create that file! Run this:

htpasswd -c /home/YOURUSER/example.com/.htpasswd LOGIN

Where LOGIN is the username you want to be used to authenticate as. After typing that command you'll be prompted to enter a password and then confirm that password like this:

New password: Re-type new password: Adding password for user LOGIN

At this point, reload the nginx config as discussed previously and you should start getting prompted when you try browsing to that domain. As usual, you can specify subdirectories be protected as well:

location /subdirectory/ { auth_basic "Restricted"; auth_basic_user_file /home/YOURUSER/example.com/.htpasswd; }

If you are using PHP in that directory, you will also need to add the following to allow .php files to be password protected:

location ~ ^/.+\.php$ { auth_basic "Restricted"; auth_basic_user_file /home/YOURUSER/example.com/.htpasswd; }

To add new passwords or change existing ones, just use this command:

htpasswd /home/YOURUSER/example.com/.htpasswd LOGIN

The  parameter is only necessary if you need to create the file. Once it exists you no longer need that parameter. If you use an existing login it will change the password to the new one you enter.

= Redirecting Domains =

I used this to redirect a domain's additional domain extensions to the primary domain extension. First, create an  file in the appropriate directory:

/home/YOURUSER/nginx/example.com/domainredirects.conf

All of the files you create in that directory get loaded in the SERVER block of the default nginx.conf (/dh/nginx/servers/httpd-pXXXXXX/nginx.conf). So there is no need to alter the default .conf file for redirects.

if ($host = "(example.com|example.net|example2.com)" ) { rewrite ^/(.*)$ http://www.example.com/$1 permanent; }

--Varnent 00:33, 25 July 2011 (PDT)

Redirecting Single Files
if ($request_filename ~ oldfile.html){ rewrite ^ http://mydomain.com/newfile.php? permanent; }

= Blocking IPs =

Sometimes your site starts getting hit a ton by some abusive IP and you end up wanting to block it. Here's the nginx way to do that. First, create an  file in the appropriate directory:

/home/YOURUSER/nginx/example.com/access.conf

Then add the following content:

location / { deny 1.2.3.4; }

That line will block the  IP from accessing your site entirely. If you want to block it from a subdirectory, you would do this:

location /subdirectory/ { deny 1.2.3.4; }

If you want to block access to all IPs with some exceptions, you would do this:

location / { allow 9.8.7.6; deny all; }

It defaults to allowing all non-specified IPs (unless there's a deny all, of course). You can create multiple sets of these rules in your  file:

location / { allow 9.8.7.6; deny all; } location /subdirectory/ { allow all; }

The above would allow  to browse your entire site. All other IPs would be blocked from everywhere in your site except for  which everyone could view.

= Gzip Compression =

By default, gzip compression is enabled. If you want to disable them for a domain, then create a  file in the appropriate directory:

/home/YOURUSER/nginx/example.com/settings.conf

You could create one specifically named  if you wanted, but for simple settings like this, you might want to dump them all into one generic file. Add the following contents to the conf file you created:

gzip off;

That's it! As usual, don't forget to reload nginx. There are additional gzip compression options you can set that are all detailed here.

= Troubleshooting =

Common Problems:
 * If none of your website are coming back up after flipping the switch in the Dreamhost control panel to Nginx, it may be because the Nginx setup did not complete properly. In my case, when attempting to start Nginx from the root user admin command line:

"It failed saying it could not find the nginx.conf configuration file. Turns out the automated configuration process had created it, but for some reason, had not copied it over from the temporary file 'nginx.conf.pushing' which was under /dh/nginx/servers/httpd-/. A quick 'cp nginx.conf.pushing nginx.conf' and then a 'sudo /etc/init.d/nginx restart' and up she came."
 * As stated earlier in this page, Nginx starts up helper processes for each username. If you have websites on a Dreamhost VPS *and* a shared server, the automated setup script will create "server" entries for all your user, regardless if they are on the VPS or not.  In my case, I had one user with a few websites on the VPS and 15+ users on a shared server and it started up process for all of them.  You can fix this by going into your nginx.conf (as root user) and removing all the "server" sections that are for users not on your VPS.

= External Links =


 * Nginx Wiki
 * Nginx Configuration Examples
 * How To Modify A URL Extension With An Nginx Rewrite

WordPress-related

 * How to Speed Up WordPress with Nginx and WP Super Cache
 * Wordpress, Nginx, and WP Super Cache
 * Nginx - Making stats accessible when using wordpress

Drupal-related

 * Nginx Drupal Group
 * Nginx, Multisite and Rewrite Rules