Setting up a website is a good first task for anyone looking to get into server administration. it requires a basic grasp of Linux concepts like package management, system services, and how to edit configuration files. This guide will walk you through installing nginx on Ubuntu or Fedora and securing it with certbot for HTTPS.

Installing Nginx and Certbot

The first step will be installing nginx. There are several ways to go about this, so I'll run through them from easiest to hardest.

The easiest way to install nginx will be to use the official packages. This can be done with apt install nginx on Ubuntu and Debian or dnf install nginx on Fedora. However, official repositories are normally a few versions behind. While this isn't necessarily bad, some people (myself included) like using the newest version for some features that won't be touched on in this guide.

The easiest way to install the latest version of nginx will be to use packages I build and maintain. However, this only works on Ubuntu 18+. To get started, first add my GPG key to apt and then add the package repository I maintain to your apt sources. The easiest way to do this is to run curl -sSL https://packages.galenguyer.com/bootstrap.sh | sh, though if you're hesitant to pipe from curl to bash, you can download and run the script normally. Finally, install the package you want. Five are provided, with various feature sets. Mainline packages are the latest version of nginx, whereas stable packages use the nginx stable branch, which is slightly behind mainline. Packages with "quiche" in the name have experimental HTTP/3 support enabled, which I don't reccomend unless you're familiar with nginx and ready to debug it. I would suggest installing the edgeinx-mainline package for the best mix of features and stability. This can be done by simply running apt install edgeinx-mainline. Any time you update your system with apt update or upgrade, it will update this package if a newer version is found as well.

The last way to install nginx is build it from source yourself. If you want to do this, I reccomend using this script, which was originally written by Seednode. You can edit it to change the version of nginx you install and change what features are installed as well. It will also set up default config files and a systemd service for you. I last tested it on Ubuntu 18.04, but it should work on all modern versions of Debian, Ubuntu, and Fedora. Be warned, it will take a long time to run if you don't have a relatively powerful CPU.

The final thing you'll want to install is certbot-auto. I've found it the easiest way to interact with Let'sEncrypt for certificates. You can install it by running the following commands:

sudo curl -sSL https://dl.eff.org/certbot-auto -o /usr/local/bin/certbot-auto
sudo chmod a+x /usr/local/bin/certbot-auto

Configuring Nginx for plain HTTP

Now that nginx is installed, let's complete the basic setup. Before doing this, make sure you have a domain set up that resolves to the public IP address of your server.

To configure nginx, enter the /etc/nginx directory on your server. You'll need root permissions to edit or create any files here. It will be populated with a few basic config files as well as default versions for all of them, which you can choose to keep or remove with rm *default

First, create two directories in which to store your configuration files using the following command:

# mkdir -p /etc/nginx/{sites,ssl}

Now that those directories exist, modify your nginx.conf file to include any configuration files we put in the /etc/nginx/sites directory. An example configuration file is available here: nginx.conf.

Next, create the file /etc/nginx/ssl/params.conf, where you'll configure HTTPS. You won't use these yet, but we'll get back to them. An example file with comments is available here: ssl/params.conf.

You'll also want to generate a dhparam.pem file. Here is a good explanation of what they're used for, though understanding that isn't required. Use the following command to generate the file:

# touch /etc/nginx/ssl/dhparam.pem && openssl dhparam --out /etc/nginx/ssl/dhparam.pem 4096

Now that your basic HTTPS configuration is done, let's tell nginx to listen for requests over HTTP for your website and serve files. This will also let us set up HTTPS.

In the /etc/nginx/sites directory, create a file ending with .conf. The actual name isn't important, but I find it useful to follow the pattern of [domain].conf, so I know which file controls which site. An example plain HTTP configuration file can be found here: sites/example.com.nohttps.conf, but you won't need more than the following four lines. Whichever configuration you go with, make sure to update the server_name and root options.

# /etc/nginx/sites/example.com.conf

server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    root /var/www/example.com;
}

Now that all your configuration files are in place, run sudo nginx -t to test your configuration. If there are any errors, it will tell you, otherwise, you're good to apply the configuration! To do that, simply run sudo systemctl restart nginx, and you should be able to navigate to your website and see any pages you have!

Setting up HTTPS with LetsEncrypt

Now that you can access your website, it's time to get a certificate for HTTPS. Use the following command, making sure to update the -w and -d options appropriately:

# certbot-auto certonly --webroot -w /var/www/example.com/ -d example.com -d www.example.com --rsa-key-size 4096

Once this completes, you will have the certificates in /etc/letsencrypt/live/example.com. You'll have to renew them using the same command or certbot-auto renew every 90 days.

Finally, modify your configuration to use the certificate you just generated. You can use the example file at the following link, making sure to change from example.com to your domain! sites/example.com.conf

Once you've modified the configuration file, test it with sudo nginx -t again, and if everything is good, apply it with sudo systemctl reload nginx. Now, when you visit your site, it should redirect you to the HTTPS version. Just repeat this process to add any more domains!

A couple notes

All example configuration files can be found at https://git.galenguyer.com/chef/nginx-demo/

You might have noticed some blocks for php in the example config files. If you want to use PHP, install it (the command for Ubuntu is sudo apt install php7.2-fpm) and uncomment the lines as shown in this config file. You may need to change the socket path. If you are missing any of the other php config files, you can find in this git repo.