We will now take our simple application and run it in a production environment. This includes integrating the application with a production web server (nginx), obtaining a DNS name for our site, and obtaining TLS certificates for it via Let's Encrypt (certbot). In addition, it will be deployed using cloud infrastructure.

From your Linux VM, sign in to Vocareum and go to your AWS Starter Account. Click AWS Console to open the AWS Management console. Make sure the browser does not block the pop-up window.

Find the EC2 service and Launch an EC2 instance.

Use Ubuntu 18.04 LTS (HVM), SSD Volume Type on t2.micro instance type in the us-east-1 region (N.Virginia, which should be the default)

Click on the Next buttons until you get to the Configure Security Group screen. Add rules for HTTP and HTTPS on the appropriate ports.

Select Review and Launch and Launch.

Create a new key pair when you get to the launch screen. Name the key pair awseducate and download it. Restrict the permissions on the key pair with chmod 400 awseducate.pem.

Select Launch Instances, and View Instances from the Launch Status screen. The EC2 instance should be starting and in a pending state. Select it and find the IPv4 Public IP in the Description tab. Copy the IP address and save it for later in the lab.

Our guestbook web site requires a name so we don't have to remember the external IP address to access it. To do so, visit a free DNS registration service and register a name containing cs430-<OdinID> on the VM's external IP address (e.g. cs430-wuchang or cs430-wuchang-aws). 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)




(Note: omit the dash since it is not allowed).



Some services allow you to specify a name that includes an IP address that it resolves to. If you have difficulty with the sites above, then use names from the following xip-based sites.



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.

ssh into the machine using the public IP address that you noted earlier

ssh -i awseducate.pem ubuntu@<public-ip-address>

Clone the repository and change into the source directory

git clone https://github.com/wu4f/cs430-src
cd cs430-src/03_nginx_uwsgi_certbot

If you have gone through the Compute Engine version, skip to the next section. We will now examine the code and configuration of our application.


Examine the file app.ini. This file 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.


Examine wsgi.py. The file is called upon initialization of uwsgi and simply Imports the app from app.py and runs it.


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 18.04. The file configures the startup of the uwsgi daemon and its environment. Uwsgi is executed using the app.ini configuration from the previous step. 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 virtualenv.

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 uwsgi socket and be handled by the Python application while requests to the /static path should be served directly by nginx from the specified directory.


The script used to setup the site is install.sh

The script takes one parameter: the DNS name you set-up earlier (e.g. ./install.sh cs430-wuchang.ipq.co)

The script begins by pulling out first part of the DNS name (e.g. cs430-wuchang) 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, virtualenv, nginx, and certbot. It then creates the virtualenv environment for the web application and installs its packages into it from requirements.txt.

Then, the script sets up systemd startup file for uwsgi 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)

The script changes ownership to allow nginx (via www-data account) to create the domain socket

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

Finally, the script calls certbot to obtain the TLS certificate in non-interactive mode (see TLS slides on Let's Encrypt)

Run the install script to configure your VM and obtain a certificate.

sudo ./install.sh <YourDNSNameHere>

Bring the site up in a browser and note it's valid certificate. Add an entry to the guestbook, then show a screenshot of the site along with its Let's Encrypt certificate.

We don't want to keep our EC2 instance running after this lab.

Go back to the EC2 Management Console where you created the EC2 instance. Find your instance, select it, and select Instance State > Terminate from Actions dropdown menu. When prompted, click to confirm that you would like to terminate the instance.