Ubuntu Server Setup Part 4 - Setup Nginx Web Server
08 Aug 2018- Part 1 - Logging In
- Part 2 - Securing Login
- Part 3 - Installing a Firewall
- Part 5 - Install Git, Ruby and Jekyll
- Part 6 - HTTPS With Let’s Encrypt
- Part 7 - Email Forwarding with Postfix
- Part 8 - Sending Email Through Gmail
- Part 9 - Setup a Reverse Proxy with Nginx
- Part 10 - Install Docker and Docker Compose
Serving web pages is one of the most common and useful use cases of a cloud server. Nginx is popular and handles some of the largest sites on the web. It’s configuration is simplistic but very powerful and Nginx can often use less resources than an equivalent Apache server.
Install Nginx
Nginx is available in the default Ubuntu repositories, so installation is simple through apt
:
$ sudo apt update
$ sudo apt install nginx
That’s all you need to do for the base install of Nginx. By default, the service is started and Nginx includes a simple default landing page (located in /var/www/html
) which you should now be able to access via the web.
Access through the Web
First, make sure that Nginx is running on your system. If using a modern Ubuntu server installation, you can do this via systemd
:
$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
...
If Nginx is not already running, use the following to start the service:
$ sudo systemctl start nginx
# other useful commands
$ sudo systemctl stop nginx
$ sudo systemctl restart nginx
$ sudo systemctl reload nginx # reload config without dropping connections
$ sudo systemctl disable nginx # don't start nginx on boot
$ sudo systemctl enable nginx # do start nginx on boot
Also check that your firewall (if any) is setup to allow connections on port 80 (for HTTP
). Refer to the previous part in this series for instructions using ufw
.
Now you can check that everything is working correctly by accessing your web server through the internet. If you don’t already know the external IP for you server, run the following command:
$ dig +short myip.opendns.com @resolver1.opendns.com
When you have your server’s IP address, enter it into your browser’s address bar. You should see the default Nginx landing page.
http://your_server_ip
Customise Nginx Config
All of the Nginx configuration files are stored within /etc/nginx/
and it is laid out similarly to an Apache installation.
To create a new configuration - server block
in Nginx, virtual host
in Apache - first create a file within /etc/nginx/sites-available
. It is good convention to use the domain name as the filename:
$ sudo nano /etc/nginx/sites-available/yourdomain.com
Within this file, create a new server block structure:
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name yourdomain.com www.yourdomain.com;
location / {
try_files $uri $uri/ =404;
}
}
This server block will listen to requests on port 80 (HTTP
requests) and will serve resources from the default /var/www/html
directory. This can be changed as necessary - ideally a dedicated root directory per server block. The server_name
is set to the domain name(s) you wish to serve. This is useful if you want to add HTTPS
via Let’s Encrypt later on.
Next, this server needs to be enabled by creating a symlink within the /etc/nginx/sites-enabled
directory:
$ sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
You may also wish to delete the default configuration file unless you want to fall back to the defaults:
$ sudo rm /etc/nginx/sites-enabled/default
As we have added additional server names (our domains), it is good to correct the hash bucket size for server names to avoid potential conflicts later on:
$ sudo nano /etc/nginx/nginx.conf
Find the server_names_hash_bucket_size
directive and remove the #
symbol to uncomment the line:
...
http {
...
server_names_hash_bucket_size 64;
...
}
...
Finally, it’s time to restart Nginx in order to reload our config. But first, you can see if there are any syntax errors in your files:
$ sudo nginx -t
If there aren’t any problems, restart Nginx to enable the changes:
$ sudo systemctl restart nginx
Nginx will now serve requests for yourdomain.com
(assuming you have set up an A
DNS record pointing to your server). Navigate to http://yourdomain.com
and you should see the same landing page as before. Any new files added to /var/www/html
will also be served by Nginx under your domain.
Enable HTTPS
If you already have SSL
certificates for your domain names, you can easily setup Nginx to handle HTTPS
requests. Makes sure that your firewall is setup to allow connections on port 443 first:
server {
listen 443 ssl;
listen [::]:443 ssl;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name yourdomain.com www.yourdomain.com;
location / {
try_files $uri $uri/ =404;
}
ssl_certificate /etc/ssl/certs/example-cert.pem;
ssl_certificate_key /etc/ssl/private/example.key;
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";
}
The above uses the same configuration as Let’s Encrypt to set strong ciphers and disable old versions of SSL. This should get you an A in SSLTest. I will also add a post on setting up Let’s Encrypt with Nginx to automate the process of using free SSL certificates for your site.
Custom Error Pages
By default, Nginx will display it’s own error pages in the event of a 404/50x
error etc. If you have your own versions, you can use the error_pages
directive to specify a new path. Open up your server block config and add the following:
server {
...
error_page 404 /custom_404.html;
error_page 500 502 503 504 /custom_50x.html;
...
}
If required, you can also specify a completely new location (not in the main root
directory of the server block) for your error pages by providing a location
block which resolves the specified error page path:
server {
...
error_page 404 /custom_404.html;
location = /custom_404.html {
root /var/html/custom;
internal;
}
...
}
Log File Locations
/var/log/nginx/access.log
: Every request to your web server is recorded in this log file unless Nginx is configured to do otherwise./var/log/nginx/error.log
: Any Nginx errors will be recorded in this log file.