In this lab, we'll be setting up a web server running on a virtual machine, obtaining a DNS name that points to its IP address, and then installing a web application on it. We'll then obtain a TLS certificate for the site via the Let's Encrypt service so that a web client can bring the site up over HTTPS.

Connect to EC2

  1. Start your Learner Lab and access the AWS console.
  2. Search for the EC2 service

Create instance

Launch an instance with following configuration:

When it comes up, note its Public IPv4 address.

You will be using this address in subsequent steps.

Our guestbook web site requires a name so we don't have to remember the Public IPv4 address to access it. To do so, visit a free DNS registration service and register a name on the VM's external IP address.

Example services include

Note that if you get a rate-limit error on Let's Encrypt via one service, you will need to use the alternate ones. This is a result of Let's Encrypt being abused by malicious actors to create web sites with valid certificates that look legitimate. (This, of course, won't be an issue with our janky web application)

duckDNS

freeDNS

We will now set up our guestbook web site on the EC2 VM and use the name from the prior step to obtain a TLS certificate.

Connect from your terminal

ssh admin@<Public IPv4>

Change permissions

Once connected to the VM, change the permissions for your home directory to add execute permissions for others to it. This will allow the web server, which runs with group www-data, to access resources we set up for it.

chmod o+X .

Install git

sudo apt-get update
sudo apt-get install git

Get the code

Clone the repository and change into the source directory

git clone https://github.com/bfritscher/guestbook-src.git
cd guestbook-src/03_nginx_gunicorn_certbot

We will now examine the code and configuration of our application.

etc/systemd.template

The repository contains template files for configuring the server and nginx to run the Guestbook code. These templates will generate corresponding files in /etc, the directory where Linux configuration files are stored. The first template is etc/systemd.template. systemd is the default service manager for Ubuntu. The file configures the startup of the gunicorn daemon and its environment. In addition, the working directory is set to PROJECT_DIR, which will be replaced on installation with your directory. The PATH environment variable is set to the location where the Python environment's binaries will eventually be installed via a subsequent venv. The last command configures the entry point for the Python application, sets the number of processes to use for it, and specifies the domain socket that will be used by the nginx web server to communicate with the web application.

The other template is etc/nginx.template which configures nginx with the server's DNS name (setup from the prior step) and the path to the root directory for the server. It also specifies that requests to the top-level path (/) should go through the gunicorn socket and be handled by the Python application while requests to the /static path should be served directly by nginx from the specified directory.


install.sh

The script used to setup the site is install.sh

The script takes one parameters: the DNS name you set-up earlier (e.g. ./install.sh mygb.duckdns.org)

The script begins by pulling out the first part of the DNS name (e.g. mygb) and eliminating the first period and all subsequent characters. The name is used to label the systemd service for the site.

Then, the script installs python3, venv, nginx, and certbot. It then creates the venv environment for the web application and installs its packages into it from requirements.txt.

Then, the script sets up a systemd startup file for the web site from its template using sed to replace the PROJECT_DIR with the current working directory ($PWD) and PROJECT_USER with the current user ($SUDO_USER). It will then name the systemd service using the $SITE label above.

The script then sets up the nginx configuration file from its template using sed. Similar substitutions are made as well as a substitution for PROJECT_HOST using the fully-qualified domain name (FQDN) of the site (registered earlier). It also sets up nginx to add the site (via adding config file to /etc/nginx/sites-available and a link in /etc/nginx/sites-enabled to it)

It then starts systemd service for the site, enables it by default (on startup), and restarts nginx for changes to take hold.

Run the script. Fill in Your_FQDN_Here (fully-qualified domain name) with the name you registered (example: abc.duckdns.org)

sudo ./install.sh Your_FQDN_Here

Bring up a web browser and navigate to the application running on the instance over HTTP to ensure that you're able to access the Guestbook application that is running on it.

http://<Your_FQDN_Here>

Then, fill in the command below with your email to run certbot in order to obtain a TLS certificate for the web site from Let's Encrypt.

sudo certbot --nginx -d Your_FQDN_Here -n -m YourEmailAdresse --agree-tos --redirect

Wait for your certificate

Bring the site up in a browser and note its valid certificate. Add an entry to the guestbook.

Task Progress Check

Go to the console of EC2, find the VM in "instances" and select Instance state > Terminate (delete) instance.

When prompted, confirm that you would like to delete the VM.