We removed our free Sandbox April 25th.
You can read more on our blog.

Configuring Nginx

You can include your own Nginx configuration (e.g rewrite rules, access control, authentication...) in a file called nginx.conf at the root of your application. If you are more familiar with Apache, think of nginx.conf as a global .htaccess.

Note

Your Nginx configuration is included almost on the top of the server block. That means that you can override most of our Nginx configuration if you don’t like it.

Rewrite Rules

Rewrite rules are very straightforward in Nginx: they are always available (you don’t need to enable mod_rewrite or specify RewriteEngine on), and they are often easier to use than their Apache counterparts. You can actually define conditions with real if constructs instead of RewriteCond statements featuring obscure flags. Regarding regular expressions, both Apache and Nginx use Perl Compatible Regular Expression (PCRE) syntax.

The main rewrite configuration directive is rewrite; for example:

rewrite ^/users/(.+)$ /profile.php?user=$1;

Note

The ; simply ends the Nginx statement, it is not a part of the rewrite rule. All statements in Nginx ends with a ; (like in e.g. C or PHP).

You can also use rewrite rules to make temporary and permanent HTTP redirections. For example, the next snippet checks if the user is browsing the website using HTTPS, and permanently redirects him if it’s not the case:

if ($http_x_forwarded_proto != "https") {
    rewrite ^ https://$host$uri permanent;
}

Temporary redirections use the redirect keyword instead of permanent.

Restricting Access

Restricting access to some files is very easy:

location /admin/htpasswd {
    deny all;
}

You can also match against a regular expression by using ~:

location ~ /system/.* {
    deny all;
}

Setting Up Error Pages

Nginx on dotCloud is usually configured to serve error pages from a directory called static in your application. One notable exception is for python apps where you must define the static location your own nginx.conf. To know for certain if you must define static or not, please look in /etc/nginx/sites-enabled/default in your service container. If there is no location definition for static then you should define your own nginx.conf like this:

# choose an alias location that suits your code tree.
location /static/ {
   alias /home/dotcloud/current/static/;
}

The custom error pages should be named 404.html, 500.html, and so on.

If you don’t want to follow this convention you can also configure your error page location:

location @404 {
    rewrite ^ /application/errors/error_404.php;
}

location @500 {
    rewrite ^ /application/errors/error_500.php;
}

# And so on...

Maintenance Mode

Sometimes, it can be useful to completely disable the access to your website, and show your visitors a banner or “curtain” page. This is particularly handy when you need to perform e.g. a lengthy maintenance or upgrade operation on the site or its database.

By convention, DotCloud looks for a file named maintenance at the root of your application. If this file exists, the request processing stops immediately, and Nginx triggers a HTTP 503 “Service Unavailable” error.

This will display your custom 503 error page, if you have one.

Authentication

Setting up basic HTTP authentication is not so different from Apache:

location /admin/ {
    auth_basic           "Admin Realm";
    auth_basic_user_file /home/dotcloud/current/admin/htpasswd;
}

The admin/htpasswd file uses the same format as Apache’s htpasswd file. Therefore, you can use your existing password files, and the htpasswd command to generate and update them.

Note

The version of Nginx currently running on most stacks is only compatible with “old-style” DES crypted passwords (as opposed to MD5/SHA hashes and their salted variants). Therefore, you should make sure that your htpasswd files contain such passwords; as generated by e.g. htpasswd -cdb myhtpasswdfile mylogin mypassword (note the -c to force DES crypt). Since the DES crypt only operates on the first 8 characters of the password, if you need something secure, you should make sure that you use a good mix of digits, upper- and lower-case letters, and the occasional symbol. Forthcoming versions of the services will use an updated Nginx, which will allow safer hashes.

Increase HTTP POST Max Size

By default, HTTP POST requests are limited to a body size of 1 MiB.

You can configure it using the following directive:

client_max_body_size 10m;

Note that our HTTP gateways enforce a limit of 100 MiB.

Combining Conditions

Nginx supports conditions with the if directive. However, it doesn’t support logical operators like and, or... So if you need to combine conditions, you can artificially do it with a snippet like the following one, which will force use of HTTPS only for some URLs:

set $redirect_to_https X;
if ($http_x_forwarded_port != 443) {
  set $redirect_to_https X$redirect_to_https;
}
if ($request_uri ~ /secure/.*) {
  set $redirect_to_https X$redirect_to_https;
}
if ($redirect_to_https = XXX) {
  rewrite ^ https://$http_host$request_uri;
}

This snippet will redirect everything under /secure/ to HTTPS (unless it’s already over HTTPS, of course, otherwise it would be creating a redirect loop).

Caveats

Order of Location Blocks

If several location blocks match a request, the first one in the Nginx configuration file is used. However, there are multiple levels of override:

  • by default, plain string matches like location /images are used;
  • but you can override it with a regex match like location ~ /images;
  • but you can override the previous one with a “forced” string match like location ^~ /images (you can imagine that the ^~ stands for “above ~”, i.e. “above regexes”);
  • and you can always override with an exact match like location = /images which will match only the specified location.

For example, if you want to override a location that contains php files you will have to use a regular expression in your location block, because the configuration, obviously, already contain a location block on ”.+\.php”.

502 And 504 Errors

Your application actually lives behind an HTTP gateway, gateway.dotcloud.com. This HTTP gateway routes the requests to your service, and if your service is scaled, it load balances the requests on the backends. It also detects failed backends for high availability scenarios.

This extra gateways implies two important things:

  • bugs in your application that raise an HTTP 500 error will be returned by the gateway as 502 “Bad Gateway” errors;
  • if your application times out and never replies to a request, the gateway will signal that as a 504 “Gateway Timeout” error.

Nginx Reference Documentation

If you want to learn more about Nginx and its internal, we encourage you to check the Nginx wiki.