I transitioned from [Apache][] to [Nginx][] a week or so ago, since words like “minimal” and “streamlined” are appealing to me ;). I was quite happy with Apache, but it's always nice to try something new. Anyhow here's a quick review my configuration. On [[Gentoo]], set the the [modules][] you want to install by adding the following lines to your `/etc/make.conf`: NGINX_MODULES_HTTP="access auth_basic autoindex charset fastcgi gzip gzip_static limit_req map proxy rewrite scgi ssi stub_status" NGINX_MODULES_MAIL="" Then install Nginx with: # emerge -av nginx Make any adjustments you like to `/etc/nginx/mime.types`. I added: types { … application/x-python py; application/x-shell sh; … } Now it's time to setup `/etc/nginx/nginx.conf`. Poking about online will give you lots of examples. Here are things that were useful to me, in the order they appear in the `http` block of my `nginx.conf`. Redirecting `www.example.com` to `example.com` ============================================== This keeps people who accidentally add a `www.` prefix to your URL from matching the wildcard virtual host block defined below. server { # www.example.com -> example.com listen 80; listen 443 ssl; server_name www.example.com; ssl_certificate /etc/ssl/nginx/www.example.com.pem; ssl_certificate_key /etc/ssl/nginx/www.example.com-key.pem; rewrite ^/(.*)$ $scheme://example.com/$1 permanent; } Gitweb (and general CGI approach) ================================= [[gitweb]] server: server { listen 80; server_name git.example.com; access_log /var/log/nginx/git.example.com.access_log main; error_log /var/log/nginx/git.example.com.error_log info; root /usr/share/gitweb/; index gitweb.cgi; location /gitweb.cgi { include fastcgi_params; fastcgi_pass unix:/var/run/fcgiwrap.sock-1; } } Because Nginx lacks built-in [[CGI]] support, we need some tricks to get `gitweb.cgi` working. We use the [fcgi module][fcgi] to pass the requests on to a FastCGI server which wraps `gitweb.cgi`. On [[Gentoo]], I installed the following packages: * `www-misc/fcgiwrap`, a [[FastCGI]] server for wrapping [[CGI]] scripts * `www-servers/spawn-fcgi`, a [[FastCGI]] manager for spawning `fcgiwrap`. Configure `spawn-fcgi` to launch `fcgiwrap` with: # cp /etc/conf.d/spawn-fcgi /etc/conf.d/spawn-fcgi.fcgiwrap # emacs /etc/conf.d/spawn-fcgi.fcgiwrap # cat /etc/conf.d/spawn-fcgi.fcgiwrap FCGI_SOCKET=/var/run/fcgiwrap.sock FCGI_ADDRESS= FCGI_PORT= FCGI_PROGRAM=/usr/sbin/fcgiwrap FCGI_USER=nginx FCGI_GROUP=nginx FCGI_EXTRA_OPTIONS="-M 0700" ALLOWED_ENV="PATH HOME" HOME=/ FCGI_CHILDREN=1 FCGI_CHROOT= # cd /etc/init.d/ # ln -s spawn-fcgi spawn-fcgi.fcgiwrap Start `fcgiwrap` with: # /etc/init.d/spawn-fcgi.fcgiwrap start Add it to the default runlevel with: # rc-update add spawn-fcgi.fcgiwrap default If you also want a virtual host serving Git over HTTP, you can add a virtual host like: server { # http-git.example.com listen 80; server_name http-git.example.com; access_log /var/log/nginx/http-git.example.com.access_log main; error_log /var/log/nginx/http-git.example.com.error_log info; location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend; fastcgi_param GIT_HTTP_EXPORT_ALL ""; fastcgi_param GIT_PROJECT_ROOT /var/git; fastcgi_param PATH_INFO $document_uri; fastcgi_pass unix:/var/run/fcgiwrap.sock-1; } } This uses the same FastCGI server we used for gitweb, but this time the backend CGI script is `git-http-backend`. Wildcard virtual hosts ====================== To add support for virual hosts stored under `/var/www/$host`, use: server { listen 80; #listen 443 ssl; server_name star.example.com *.example.com; access_log /var/log/nginx/star.example.com.access_log main; error_log /var/log/nginx/star.example.com.error_log info; #ssl_certificate /etc/ssl/nginx/$host.pem; #ssl_certificate_key /etc/ssl/nginx/$host.key; root /var/www/$host/htdocs; # deny access to .htaccess files location ~ /\.ht { deny all; } } Then adding a new host is as simple as creating a new entry in `/var/www/` and updating your [[DNS]] to get the new name pointed at your server. Unfortunately, [[SSL/TLS|GnuTLS]] doesn't work with this approach. It appears that certificates and keys are loaded when Nginx starts up, but `$host` is only defined after a request is received. Nginx does support [[SNI]] though, so it will work if you write SSL entries by hand for hosts that need them. Main host ========= The configuration for my main host is more complicated, so I'll intersperse some more comments. I setup both clear-text and SSL in the same definition using the [SSL module][SSL]. The `_` server name is a special name that matches any requests which haven't already matched and been handled by an earlier `server`. server { # catchall virtual host (optional SSL, example.com) listen 80 default_server; listen 443 default_server ssl; server_name _; ssl_certificate /etc/ssl/nginx/example.com.pem; ssl_certificate_key /etc/ssl/nginx/example.com-key.pem; Nothing special with the logging or root. access_log /var/log/nginx/example.com.access_log main; error_log /var/log/nginx/example.com.error_log info; root /var/www/example.com/htdocs; Turn on [[SSI]], and also use `index.shtml` as index pages. index index.html index.shtml; ssi on; Use the [proxy module][proxy] to pass requests for `/cookbook/` and subdirectories on to their [[underlying Django app|cookbook]]. location /cookbook/ { proxy_pass http://localhost:33333/cookbook/; proxy_set_header X-Real-IP $remote_addr; } Use the [scgi module][scgi] to pass requests for `/gallery/` and subdirectories on to their [[underlying SCGI app|gallery]]. location /gallery/ { include scgi_params; scgi_pass localhost:4000; } Turn on autoindexing for `/RAD/` and subdirectories using the [autoindex module][autoindex]. location /RAD/ { autoindex on; } Force SSL/TLS for `/tree/` and subdirectories, redirecting plain-text requests to the equivalent HTTPS page. Use the [auth_basic module][auth_basic] for authentication, the [SSL module][SSL] for `$ssl_protocol`, and the [rewrite module][rewrite] for the redirection. location /tree/ { auth_basic "Family Tree"; auth_basic_user_file /home/jdoe/htpasswd; if ($ssl_protocol = "") { rewrite ^ https://example.com$request_uri? permanent; } } Nothing special with the end of this `server` block. # deny access to .htaccess files location ~ /\.ht { deny all; } } [Apache]: http://www.apache.org/ [Nginx]: http://nginx.org/ [modules]: http://wiki.nginx.org/Modules [fcgi]: http://wiki.nginx.org/HttpFcgiModule [SSL]: http://wiki.nginx.org/HttpSslModule [proxy]: http://wiki.nginx.org/HttpProxyModule [scgi]: http://wiki.nginx.org/HttpScgiModule [autoindex]: http://wiki.nginx.org/HttpAutoindexModule [auth_basic]: http://wiki.nginx.org/HttpAuthBasicModule [rewrite]: http://wiki.nginx.org/HttpRewriteModule [[!tag tags/tools]] [[!tag tags/web]]