Installation | Maintenance | Beyond Lino

Our nginx cheat sheet


An nginx config file. All config files are in /etc/nginx/sites-available and must be named with the suffix .conf.

To actually activate them, you must also create a symbolic link to each of them in /etc/nginx/sites-enabled. This Debian-specific convention is okay for us. It has the advantage that we can easily disable individual sites or do temporary magics.

Our additional convention is to name them xxx.conf, where xxx matches the subdomain they serve.

Static websites

The main website serves at two subdomains and When somebody types just (without www) in their browser, we permanently redirect them to the canonical Here is a template for a typical www.conf file:

server {
  if ($host = { return 301 https://www.$host$request_uri; }
  root /path/to/www;
  index index.html;
  listen 80;

For additional subdomains the .conf file is even shorter:

server {
  root /path/to/foo;
  index index.html;
  listen 80;

How to add a new subdomain

You have already a website and now want to have another website

$ sudo nano /etc/nginx/sites-available/bar.conf

Paste content from above templates and edit as needed:

$ sudo su
# cd /etc/nginx/sites-enabled
# ln -s /etc/nginx/sites-available/bar.conf .
# service nginx restart
# certbot --nginx -d

Note that the first filename given to ln -s should be the full path.

Invalid HTTP_HOST header

Problem: A new production server is sending lots of emails to ADMINS saying [mysite] ERROR (EXTERNAL IP): Invalid HTTP_HOST header: ‘’. You may need to add ‘’ to ALLOWED_HOSTS.

Explanation: there are robots called IP port scanners, both legitimate and suspicious, that try to get an answer from every IP address. The problem comes when nginx lets them pass though until Lino. Lino should not get bothered with such requests. But Lino is getting bothered because we haven’t defined any default server. These requests have no Host header.

The solution (found here) is to define a default server in your prod.conf file. Something like this:

server {
   listen      80 default_server;
   listen 443  default_server ssl;
   server_name "";
   ssl_certificate /etc/letsencrypt/live/; # managed by Certbot
   ssl_certificate_key /etc/letsencrypt/live/; # managed by Certbot
   return      444;