mkogg.py: Fix 'self.get_mp4_metadata(self, source)'
[blog.git] / posts / Nginx.mdwn
1 I transitioned from [Apache][] to [Nginx][] a week or so ago, since
2 words like “minimal” and “streamlined” are appealing to me ;).  I was
3 quite happy with Apache, but it's always nice to try something new.
4 Anyhow here's a quick review my configuration.
5
6 On [[Gentoo]], set the the [modules][] you want to install by adding
7 the following lines to your `/etc/make.conf`:
8
9     NGINX_MODULES_HTTP="access auth_basic autoindex charset fastcgi gzip gzip_static limit_req map proxy rewrite scgi ssi stub_status"
10     NGINX_MODULES_MAIL=""
11
12 Then install Nginx with:
13
14     # emerge -av nginx
15
16 Make any adjustments you like to `/etc/nginx/mime.types`.  I added:
17
18     types {
19         …
20         application/x-python                  py;
21         application/x-shell                   sh;
22         …
23     }
24
25 Now it's time to setup `/etc/nginx/nginx.conf`.  Poking about online
26 will give you lots of examples.  Here are things that were useful to
27 me, in the order they appear in the `http` block of my `nginx.conf`.
28
29 Redirecting `www.example.com` to `example.com`
30 ==============================================
31
32 This keeps people who accidentally add a `www.` prefix to your URL
33 from matching the wildcard virtual host block defined below.
34
35     server {
36       # www.example.com -> example.com
37       listen 80;
38       listen 443 ssl;
39       server_name www.example.com;
40       ssl_certificate /etc/ssl/nginx/www.example.com.pem;
41       ssl_certificate_key /etc/ssl/nginx/www.example.com-key.pem;
42       rewrite  ^/(.*)$  $scheme://example.com/$1  permanent;
43     }
44
45 Gitweb (and general CGI approach)
46 =================================
47
48 [[gitweb]] server:
49
50     server {
51       listen 80;
52       server_name git.example.com;
53
54       access_log /var/log/nginx/git.example.com.access_log main;
55       error_log /var/log/nginx/git.example.com.error_log info;
56
57       root /usr/share/gitweb/;
58
59       index gitweb.cgi;
60
61       location /gitweb.cgi {
62         include fastcgi_params;
63         fastcgi_pass  unix:/var/run/fcgiwrap.sock-1;
64       }
65     }
66
67 Because Nginx lacks built-in [[CGI]] support, we need some tricks to
68 get `gitweb.cgi` working.  We use the [fcgi module][fcgi] to pass the
69 requests on to a FastCGI server which wraps `gitweb.cgi`.  On
70 [[Gentoo]], I installed the following packages:
71
72 * `www-misc/fcgiwrap`, a [[FastCGI]] server for wrapping [[CGI]] scripts
73 * `www-servers/spawn-fcgi`, a [[FastCGI]] manager for spawning `fcgiwrap`.
74
75 Configure `spawn-fcgi` to launch `fcgiwrap` with:
76
77     # cp /etc/conf.d/spawn-fcgi /etc/conf.d/spawn-fcgi.fcgiwrap
78     # emacs /etc/conf.d/spawn-fcgi.fcgiwrap
79     # cat /etc/conf.d/spawn-fcgi.fcgiwrap
80     FCGI_SOCKET=/var/run/fcgiwrap.sock
81     FCGI_ADDRESS=
82     FCGI_PORT=
83     FCGI_PROGRAM=/usr/sbin/fcgiwrap
84     FCGI_USER=nginx
85     FCGI_GROUP=nginx
86     FCGI_EXTRA_OPTIONS="-M 0700"
87     ALLOWED_ENV="PATH HOME"
88     HOME=/
89     FCGI_CHILDREN=1
90     FCGI_CHROOT=
91     # cd /etc/init.d/
92     # ln -s spawn-fcgi spawn-fcgi.fcgiwrap
93
94 Start `fcgiwrap` with:
95
96     # /etc/init.d/spawn-fcgi.fcgiwrap start
97
98 Add it to the default runlevel with:
99
100     # rc-update add spawn-fcgi.fcgiwrap default
101
102 If you also want a virtual host serving Git over HTTP, you can add a
103 virtual host like:
104
105     server {
106       # http-git.example.com
107       listen 80;
108       server_name http-git.example.com;
109
110       access_log /var/log/nginx/http-git.example.com.access_log main;
111       error_log /var/log/nginx/http-git.example.com.error_log info;
112
113       location / {
114         include fastcgi_params;
115         fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend;
116         fastcgi_param GIT_HTTP_EXPORT_ALL "";
117         fastcgi_param GIT_PROJECT_ROOT /var/git;
118         fastcgi_param PATH_INFO $document_uri;
119         fastcgi_pass  unix:/var/run/fcgiwrap.sock-1;
120       }
121     }
122
123 This uses the same FastCGI server we used for gitweb, but this time
124 the backend CGI script is `git-http-backend`.
125
126 Wildcard virtual hosts
127 ======================
128
129 To add support for virual hosts stored under `/var/www/$host`, use:
130
131     server {
132       listen 80;
133       #listen 443 ssl;
134
135       server_name star.example.com *.example.com;
136
137       access_log /var/log/nginx/star.example.com.access_log main;
138       error_log /var/log/nginx/star.example.com.error_log info;
139
140       #ssl_certificate /etc/ssl/nginx/$host.pem;
141       #ssl_certificate_key /etc/ssl/nginx/$host.key;
142
143       root /var/www/$host/htdocs;
144
145       # deny access to .htaccess files
146       location ~ /\.ht {
147         deny all;
148       }
149     }
150
151 Then adding a new host is as simple as creating a new entry in
152 `/var/www/` and updating your [[DNS]] to get the new name pointed at
153 your server.  Unfortunately, [[SSL/TLS|GnuTLS]] doesn't work with this
154 approach.  It appears that certificates and keys are loaded when Nginx
155 starts up, but `$host` is only defined after a request is received.
156 Nginx does support [[SNI]] though, so it will work if you write SSL
157 entries by hand for hosts that need them.
158
159 Main host
160 =========
161
162 The configuration for my main host is more complicated, so I'll
163 intersperse some more comments.  I setup both clear-text and SSL in
164 the same definition using the [SSL module][SSL].  The `_` server name
165 is a special name that matches any requests which haven't already
166 matched and been handled by an earlier `server`.
167
168     server {
169       # catchall virtual host (optional SSL, example.com)
170       listen 80 default_server;
171       listen 443 default_server ssl;
172       server_name _;
173
174       ssl_certificate /etc/ssl/nginx/example.com.pem;
175       ssl_certificate_key /etc/ssl/nginx/example.com-key.pem;
176
177 Nothing special with the logging or root.
178
179       access_log /var/log/nginx/example.com.access_log main;
180       error_log /var/log/nginx/example.com.error_log info;
181
182       root /var/www/example.com/htdocs;
183
184 Turn on [[SSI]], and also use `index.shtml` as index pages.
185
186       index index.html index.shtml;
187       ssi on;
188
189 Use the [proxy module][proxy] to pass requests for `/cookbook/` and
190 subdirectories on to their [[underlying Django app|cookbook]].
191
192       location /cookbook/ {
193         proxy_pass  http://localhost:33333/cookbook/;
194         proxy_set_header  X-Real-IP  $remote_addr;
195       }
196
197 Use the [scgi module][scgi] to pass requests for `/gallery/` and
198 subdirectories on to their [[underlying SCGI app|gallery]].
199
200       location /gallery/ {
201         include scgi_params;
202         scgi_pass localhost:4000;
203       }
204
205 Turn on autoindexing for `/RAD/` and subdirectories using the
206 [autoindex module][autoindex].
207
208       location /RAD/ {
209         autoindex on;
210       }
211
212 Force SSL/TLS for `/tree/` and subdirectories, redirecting plain-text
213 requests to the equivalent HTTPS page.  Use the [auth_basic
214 module][auth_basic] for authentication, the [SSL module][SSL] for
215 `$ssl_protocol`, and the [rewrite module][rewrite] for the
216 redirection.
217
218       location /tree/ {
219         auth_basic "Family Tree";
220         auth_basic_user_file /home/jdoe/htpasswd;
221         if ($ssl_protocol = "") {
222           rewrite ^   https://example.com$request_uri? permanent;
223         }
224       }
225
226 Nothing special with the end of this `server` block.
227
228       # deny access to .htaccess files
229       location ~ /\.ht {
230         deny all;
231       }
232     }
233
234 [Apache]: http://www.apache.org/
235 [Nginx]: http://nginx.org/
236 [modules]: http://wiki.nginx.org/Modules
237 [fcgi]: http://wiki.nginx.org/HttpFcgiModule
238 [SSL]: http://wiki.nginx.org/HttpSslModule
239 [proxy]: http://wiki.nginx.org/HttpProxyModule
240 [scgi]: http://wiki.nginx.org/HttpScgiModule
241 [autoindex]: http://wiki.nginx.org/HttpAutoindexModule
242 [auth_basic]: http://wiki.nginx.org/HttpAuthBasicModule
243 [rewrite]: http://wiki.nginx.org/HttpRewriteModule
244
245 [[!tag tags/tools]]
246 [[!tag tags/web]]