:title: Configuring Nginx :description: How to include your own Nginx configuration at the root of your dotCloud application. :keywords: dotCloud documentation, quick start guide, Nginx configuration, rewrite rules, error pages, caveats, Apache, syntax 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: .. code-block:: nginx 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 ``;`` (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: .. code-block:: nginx 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: .. code-block:: nginx location /admin/htpasswd { deny all; } You can also match against a regular expression by using ``~``: .. code-block:: nginx 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 in 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 in nginx.conf like this: .. code-block:: nginx # 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: .. code-block:: nginx 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: .. code-block:: nginx 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 file, 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 file 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 s. 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: .. code-block:: nginx client_max_body_size 10m; Note that our HTTP gateways enforce a limit of 100 MB. 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: .. code-block:: nginx 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 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``; * you can also 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 contains a location block on ".+\\.php". 502 and 504 Errors ~~~~~~~~~~~~~~~~~~ Your application actually lives behind a 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 gateway implies two important things: - bugs in your application that raise a 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 `_.