Skip to main content

AWS Deployment Guide

Daniel Farlow
Software Engineer

This post details how to go about deployment on an AWS EC2 instance.

Authorship note

The core of this document was originally written by Margaret ONeill and shared internally at DigitalCrafts as a Google doc (see the original version). What follows is largely a rewrite of that document using markdown in order to make needed modifications easier (e.g., use of issues and pull requests on GitHub), future changes faster to implement, etc. Additional pictures, descriptions, and explanations have also been added.

If you see something that needs fixing or something else that would be useful to add, then please consider submitting a pull request to this repo.

Note about terminal examples

Code samples intended to be run from terminal/Bash on your local machine are prefixed with #BASH:


Code samples intended to be run in your EC2 terminal are prefixed with #EC2 terminal:

#EC2 terminal
ubuntu@ip-xxx-xx-xx-xx:~$ command-to-execute-in-ec2-terminal

Note about the new EC2 console

As noted recently on Reddit (November 21, 2019), AWS recently rolled out a new EC2 console. If you use this new console, then what you encounter and what you see in this guide will likely be somewhat different (only superficially). To ensure you see what is present in this guide (in terms of screenshots and the like), simply toggle the "New EC2 Experience" option in the top left corner of your console:



This blog contains step-by-step instructions for setting up an EC2 instance on Amazon Web Services (AWS). It explains how to do the following:

  • Create an alias to quickly log in to your EC2 terminal.
  • Connect your EC2 instance to a GitHub repo.
  • Pull your source code from your GitHub repo to your EC2 instance.

There are also instructions for installing the following on your server instance:

  • Node
  • PostgreSQL
  • PM2

Once everything described above has been set up, details will be provided to help you accomplish what you are ultimately interested in:

  • Point your personal domain name to your AWS IP address.
  • Set up subdomains.
  • Obtain a free Certbot certificate.
  • Publish your website on your domain for the world to see!

This guide describes a very narrow path, specifically a path students at DigitalCrafts have followed in order to securely publish their projects for everyone to see. This guide does not attempt to explore the full range of AWS options--there are other guides for that. This guide is intended to be tightly focuesed and assumes you have terminal/Bash on your personal computer. (Bash commands will be used for the bulk of the setup.) This process also uses GitHub to upload your files to AWS; hence, a general familiarity (and personal account) with Github is needed.

Thanks are due to Jennifer Johnson who wrote the first post on this subject in 2017. Margaret clarified and expanded Jennifer's process, and I have elaborated on Margaret's process. (Iterative work at its finest!) The true kudos go to Chris Aquino for being a great instructor and giving his students the knowledge to get where they are trying to go.

Create an AWS Account

Go to AWS to create a new account:

Be sure to save your username and password in a safe place. (Seriously, make sure you save your username and password in a safe and easy-to-remember place--AWS can be difficult to deal with when you lose/forget your credentials.)

You will need a credit card. Choose the basic/free plan--we are selecting a free account which will be free for roughly a year. Also note that sometimes, towards the end of a calendar month, you will get an email notification from AWS that you are about to reach your limit (make sure you enable billing alerts):

If you only have one EC2 instance and no other services, then your plan should remain free for a year.

Pick Server Type

Pick a region in the top right--it can be important later with S3 and other available products on AWS that you may want to branch out to. Generally, the region you choose should be the region closest to your physical location.

We are going to create and launch a virtual server. In AWS parlance, the virtual server we will be launching is known as an "Amazon EC2 instance," where "EC2" stands for "Elastic Cloud Compute." For the rest of this guide we will often refer to the Amazon EC2 instance simply as "EC2."

Navigate to the AWS Management Console and, under "All Services -> Compute," click on the EC2 link:

Launch EC2 Instance

Click the "Launch Instance" button:

Then, as the first step in launching your instance, choose an Amazon Machine Image (AMI); that is, select the Ubuntu server that is Free tier eligible:

What is an Amazon Machine Image (AMI)? (click to expand)

From Amazon:

An AMI is a template that contains the software configuration (operating system, application server, and applications) required to launch your instance. You can select an AMI provided by AWS, our user community, or the AWS Marketplace; or you can select one of your own AMIs.

Note about Ubuntu releases

Ubuntu is a Linux operating system (mainly used for desktop or server installations) that releases a new version in April of every even-numbered year; hence, as of the time of this writing, the next release should be April 2020. Select the most current version of Ubuntu (free tier eligible) when you complete this step (i.e., launching an EC2 instance).

Select the "Free tier eligible" hardware choice or instance type (this will specify the size of the memory, CPU, network performance, storage, etc.):

What is an Amazon EC2 instance type?

From Amazon:

Amazon EC2 provides a wide selection of instance types optimized to fit different use cases. Instances are virtual servers that can run applications. They have varying combinations of CPU, memory, storage, and networking capacity, and give you the flexibility to choose the appropriate mix of resources for your applications. Learn more about instance types and how they can meet your computing needs.

Select the "Review and Launch" button pictured in the image above--before you press "Launch" on the next page, however, you will need to click the "Edit security groups" link (this will effectively take us to step 6 of the AWS EC2 configuration process):

Edit Security Groups

This is a set of firewall rules. Two rules need to be added (by clicking the "Add Rule" button):

  1. Add a rule with a type of HTTP. The Port Range should be 80.
  2. Add another rule for HTTPS. Its port range should be 443.

No other configuration is necessary. Your security group configuration should now look as follows:

What is a security group?

From Amazon:

A security group is a set of firewall rules that control the traffic for your instance. On this page, you can add rules to allow specific traffic to reach your instance. For example, if you want to set up a web server and allow Internet traffic to reach your instance, add rules that allow unrestricted access to the HTTP and HTTPS ports. You can create a new security group or select from an existing one below. Learn more about Amazon EC2 security groups.

Finally, click the "Review and Launch" button and subsequently the "Launch" button. When you click the "Launch" button, a popup will appear asking you to select an existing SSH key pair or to create a new SSH key pair--we want to create a new key pair:

Create an SSH Key

Your SSH key will enable you to instantly log in to your EC2 instance and manage it using the terminal.

Provide the popup seen above with a key name that makes sense (e.g., myAwsEc2KeyMonthYear):

Then click the "Download Key Pair" button, then the "Launch Instances" button, and finally the "View Instances" button.

The file downloaded should have file type .pem. (If your downloaded file is of any other type, then you may need to convert it or rename it, a process not covered in these instructions. See AWS support for more details and help.)

Once your file has downloaded, make a note of its name and location on your computer. You may be prompted to add the certificate to your keychain. You do not need to do this and you can click "Cancel" if prompted.

Now check to see if you have an .ssh folder, a folder that is hidden by default but should be located at /Users/YOURUSERNAME/.ssh. Try to navigate to this folder via the terminal:

cd ~/.ssh

If you receive a No such file or directory error (i.e., if the .ssh folder does not exist), then simply create it:

mkdir ~/.ssh

You need to copy your downloaded .pem file and move it into your previously existing or newly created .ssh folder. You can easily do this in the terminal by navigating to the folder where your .pem file was downloaded and moving it in the following manner:

mv YOURFILENAME.pem ~/.ssh

Of course, YOURFILENAME should be what you named your .pem file; for example, this is how I moved the .pem file I generated for this demo:

mv ~/Downloads/demokeypairname.pem ~/.ssh/

Now navigate to your .ssh folder, and change the permissions on your file:

chmod 400 ~/.ssh/[yourFileName].pem
What does chmod 400 actually accomplish?

The chmod calculator explains this well: chmod 400 (chmod a+rwx,u-wx,g-rwx,o-rwx) sets permissions so that, (U)ser / owner can read, can't write and can't execute. (G)roup can't read, can't write and can't execute. (O)thers can't read, can't write and can't execute.

Connect the Instance

Return to the instance management panel of AWS in your browser. (If you ever need to navigate back to this panel, then note that it is accessible from the left navigation pane of the EC2 Dashboard under the "Instances" heading.) Navigate in the following manner from the top navbar in AWS: Services -> EC2 -> Running Instances.

Select the instance you just created upon seeing your running instances. Click the "Connect" button. You will be greeted by a popup window (addressed in the next step).

Create an Alias in Terminal/Bash for Quick Access to Your AWS EC2 Instance

Copy the example line from the popup window you were greeted by at the end of the step above:

Open your .bash_profile using nano, VSCode, or the text editor of your choice:

# Using nano
nano ~/.bash_profile

# Using VSCode
code ~/.bash_profile
Note about Catalina update and Z Shell (zsh)

With the new Mac update (fall 2019) to Catalina, the default terminal is Z Shell. If you are using Z Shell, then you will need to edit ~/.zshrc or ~/.zprofile.

Now paste the line you copied above into your .bash_profile in the following manner:

# Set up your EC2 alias (name it something reasonable such as "ec2" or "demoec2" in the case of this demo)

alias demoec2='ssh -i "~/.ssh/demokeypairname.pem"'

Note from the above that you need to provide the relative path to your .pem file. The new line in your .bash_profile should look as follows (except with your .pem file name and ubuntu@ address):

Quit and restart your Terminal/Bash application in order to test your new alias (quitting and restarting will ensure the application loads the most current version of your .bash_profile):


Your alias should now instantly log you into your EC2 instance in terminal mode. The first time you log in you may be prompted with something like the following:

Respond with yes.

Your terminal prompt should now look something like this: ubuntu@ip-172-31-20-54:~$

If your terminal prompt does not look like this, then ensure your alias was created correctly (spelling mistakes can happen!), that your .bash_profile is in the correct location, and that you have restarted Bash.

Install Ubuntu's Advanced Packaging Tool (APT)

From your EC2 terminal, execute the following:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ sudo apt update && sudo apt upgrade -y
Note about apt

apt is like brew/homebrew; that is, apt is a package manner on Linux that will install packages for you, and it runs on Ubuntu.

The command above makes use of sudo, the "superuser do" command, which is used to install and upgrade packages. The -y flag is shorthand for "yes to all options" (i.e., do not ask for approval, just run the installations/updates).

You may get the following pop-up (if so, select the option to keep the local version):

Reboot once the install has finished for all changes to take effect:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ sudo reboot

Wait a minute (an actual minute ... it will take a moment or two for everything to reboot), and then reconnect to your EC2 instance in your terminal/Bash by using your EC2 alias:

# Reconnect to your EC2 instance once you have rebooted and waited a minute

Install Nginx and Git on Your EC2 Instance

Now install Nginx (web server) and Git (version control) on your EC2 instance:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ sudo apt install nginx git

We installed Git so we can pull our GitHub repositories to the AWS fileserver. This will help us when we eventually want to edit files locally, push our changes up to GitHub, and then pull our GitHub files to the AWS fileserver.

Install Node, NVM, and NPM

Run the following commands to install Node, NVM, and NPM:

#EC2 terminal
# Install npm, node, and nvm
ubuntu@ip-172-31-20-54:~$ curl -o- | bash

# Restart your terminal with your new profile setup
ubuntu@ip-172-31-20-54:~$ source .bashrc

Note that source .bashrc will be different if you are using Z Shell.

Now install the Long Term Support (LTS) version of Node:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ nvm install --lts

Create an SSH Key on GitHub to Connect AWS with Your GitHub Files

We will now create an SSH key on GitHub so that we can connect our AWS account with our GitHub files; that is, we will make it so that GitHub can communicate with our AWS EC2 instance. In order to do this, you need to have a GitHub account (or sign up for one) and at least one repository that you want to deploy to AWS.

Log in to your GitHub account, go to Settings, "SSH and GPG keys," and click the "New SSH key" button for generating SSH keys.

Generate a new SSH key (in your EC2 terminal) using the following command (make sure you use the email associated with your GitHub account within the quotes):

#EC2 terminal
# Use the email associated with your GitHub account
ubuntu@ip-172-31-20-54:~$ ssh-keygen -t rsa -b 4096 -C ""

After running the command above, you will encounter a series of prompts (all of which you should leave empty by simply hitting return or enter), and you should end up with something similar to the following:

Now change into your .ssh directory and view the file with cat

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ cd .ssh
ubuntu@ip-172-31-20-54:~/.ssh$ cat

# Output should look something like the following:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCo4vbnWd7sC4eLxXuDeNJXJs7zKdq5dCp4YD866rs3KppdsuUb2zq3hLcL9hQiveh3i+hqLrYygaI+UXBCP9u6MVP+j7GN4Xp91ub/tGXO563K655HhoF0I2JCtCq8ZBBCUZh6lJ0J4xkEbbfGaxW4I8wbVKjG4o3AUyBeGRpKC7YbG+/ooUqCJ2vZ3zr3wmUDpnJ5pQhbItE1dFwXQ5k3A4RGlKlPbquLjqyoOv4k50LD/wCpz51q32hJSTVTu/gp4T+YPC4PedBA7BOYvbXDk2PoAqcSGswlsWp1zJaa081bVoLOwYMzT6jNmKfz+nSDN428FkenzN1AaowXa+DGVPRAXosiG9qyufxRldXVH1hJ60dIfbGydl2eUMm3fMYgw9VhBKQqtw3/4XvL5VKjvwNAtvQU1S1ir/MrXrp88nEoEJjRfEwjYF/5IVtA3VBMX50p6JL0jtz9zJ/2lVLsh/uE89bMnux2YP8Mo14SLIGT+gvfZXb5R8TR3Ug3wYjkv9RJWUj29yNlqDpRoQ57fBi4nLFVVt38MDLXRiM5seKEw5ksfGgaK3ZWFpkd/+CarbaE8zGd1ldVB/Kh3KD6tDRmsi+DS39aqOfeChIOsTVpBmQuLEFwIuELG7OmswzEUV4Jk48o6O/f2xuEur9mwVi36vSTlrQpSr1Ci0d8Aw==

Copy all of the output text, go back to the GitHub page you left open in your browser (for adding an SSH key), enter a reasonable title for your key (e.g., ec2-aws-instance-2019-11), and then paste your copied text into the key field:

Click the "Add SSH key" button (you will likely be prompted to confirm your GitHub password to complete this step--confirm your password to continue).

Now you can test out your SSH key by navigating to the GitHub repo you want to copy and you can copy the clone link with the SSH parameters:

Then, in your EC2 terminal, you can git clone with your copied link to pull your files down into a new folder (you can subsequently use ls to see the new folder name where your files are; you will need this folder name later):

#EC2 terminal
ubuntu@ip-172-31-20-54: git clone
ubuntu@ip-172-31-20-54:~$ ls # should respond with the git repo you cloned ("aws-demo-project" in this case)
Note about potential "authenticity of host" ' (ip)' error after executing command above

When you execute the git clone command in your EC2 terminal, you may be prompted with something like the following:

The authenticity of host ' (ip)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?

As noted by user VonC on Stack Overflow:

You should simply be able to answer 'yes', which will update your ~/.ssh/known_hosts file.

Additionally, as noted by user Shakil on Stack Overflow:

Since you are attempting to connect to Github using SSH for the first time (no existing entry for Github in ~/.ssh/known_hosts yet), you are being asked to verify the key fingerprint of the remote host. Because, if an intruder host represents itself as a Github server, it's RSA fingerprint will be different from that of a GitHub server fingerprint.

You have two options.

  1. You may just accept, considering you don't care about the authenticity of the remote host (Github in this case), or,

  2. You may verify that you are actually getting connected to a Github server, by matching the RSA fingerprint you are presented to (in the prompt), with GitHub's SSH key fingerprints in base64 format.

The latter option is usually more preferable.

For the purposes of this guide, we will simply respond with 'yes.'

You should now change into your newly created folder (i.e., the folder you created with the git clone command) and you will need to install any npm dependencies your project has:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ cd aws-demo-project/
ubuntu@ip-172-31-20-54:~/aws-demo-project$ npm install

(Optional) Install PostgreSQL

If your project does not use the PostgreSQL open-source relational database management system, then you should skip this step. If, however, you do use PostgreSQL in your project, then you will want to install version 10:

#EC2 terminal
# Install version 10 of PostgreSQL on your AWS EC2 instance
ubuntu@ip-172-31-20-54:~/aws-demo-project$ sudo apt install postgresql-10 -y

# Check the status and make sure it is installed
ubuntu@ip-172-31-20-54:~/aws-demo-project$ sudo service postgresql status

# Type q to get back to ubuntu@ prompt or ⌃c (i.e., control + c) on Mac

# Change to the "postgres" user in order to modify postgresql
ubuntu@ip-172-31-20-54:~/aws-demo-project$ sudo su - postgres

You should now have a prompt that looks something like the following (as above): postgres@ip-172-31-20-54:~$

We will now create a user named "ubuntu" so that it matches your EC2 instance name. This needs to be because Node.js runs as "ubuntu" on your EC2 instance (hence, we have to give "ubuntu" access to the postgres database).

Now execute the following commands (with your prompt as above; and do not forget the semicolons!):

postgres@ip-172-31-20-54:~$ whoami # return the user (should respond with "postgres")
postgres@ip-172-31-20-54:~$ createuser ubuntu; # create the ubuntu user
postgres@ip-172-31-20-54:~$ createdb ubuntu; # create the ubuntu database
postgres@ip-172-31-20-54:~$ psql # gives you a psql prompt
# create a user with a password that can only be accessed from your EC2 login with your SSH key
postgres=# alter user ubuntu with encrypted password 'ubuntu'; # should return "ALTER ROLE"
# set the privileges for this new "ubuntu" user
postgres=# grant all privileges on database ubuntu to ubuntu; # should return "GRANT"
# now add additional permissions
postgres=# alter role ubuntu with superuser; # should return "ALTER ROLE"
postgres=# alter role ubuntu with createdb; # should return "ALTER ROLE"
postgres=# alter role ubuntu with login; # should return "ALTER ROLE"

Now back out of the postgres=# prompt with \q and then exit that shell with exit:

#while inside of the postgres prompt
postgres=# \q # should back you out of the postgres prompt
postgres@ip-172-31-20-54:~$ exit # should exit the shell and return with "logout"
ubuntu@ip-172-31-20-54:~/aws-demo-project$ psql # should give you an ubuntu=# prompt
# psql logs you in to postgres as ubuntu; now "exit" to get out of ubuntu/EC2
ubuntu@ip-172-31-20-54:~/aws-demo-project$ psql # logs you into postgres as ubuntu
ubuntu=# \q # log out from being ubuntu
ubuntu@ip-172-31-20-54:~/aws-demo-project$ # you should now be back in your EC2 terminal

We will now make some modifications, namely changing IPv4 and IPv6 from md5 to trust in the pg_hba.conf file (you will have to scroll down a good ways to reach these lines, and make sure you save the file for your changes to take effect):

#EC2 terminal
ubuntu@ip-172-31-20-54:~/aws-demo-project$ sudo nano /etc/postgresql/10/main/pg_hba.conf

Now restart postgres for the changes to take effect:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ sudo service postgresql restart

(Optional) Install PM2

Note: You can skip this step if your project does not have a backend or use Node.js to run.

Intalling PM2 will allow you to run multiple applications on different ports of your web server. This is a process manager for Node.js. PM2 allows Nginx to run Node.js programs in the background for us.

Execute the following commands to install PM2:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ npm i -g pm2 # install PM2 globally
ubuntu@ip-172-31-20-54:~$ pm2 # start using pm2

We also need to make sure PM2 runs index.js (or whatever the entry point is for your application--if you are using the express generator then this will be bin/www) from within our Node.js application:

#EC2 terminal
ubuntu@ip-172-31-20-54:~/aws-demo-project$ pm2 start bin/www --name ec2-demo-

You should get something that looks like the following:

Note from the above that you can use the --name flag to give your application a name. We will now generate a startup script. As the PM2 docs note:

Restarting PM2 with the processes you manage on server boot/reboot is critical. To solve this, just run this command to generate an active startup script: pm2 startup And to freeze a process list for automatic respawn: pm2 save Read more about startup script generator here.

Hence, if we establish a startup script, PM2 will restart every time that Nginx is restarted. Following the PM2 docs, to create a start up script, we can execute the pm2 startup command and then copy, paste, and execute the command returned to us by PM2 and subsequently freeze a process list for automatic respawn by running pm2 save:

#EC2 terminal
ubuntu@ip-172-31-20-54:~/aws-demo-project$ pm2 startup # generate active startup script
# copy, paste, and execute the startup script generated by PM2 # execute generated startup script
ubuntu@ip-172-31-20-54:~/aws-demo-project$ pm2 save # save/freeze process list for automatic respawn

You should end up with something that looks similar to the following:

See the PM2 quick start guide for other notes about installation, starting an application, managing processes, etc.

(Optional) Point Your Domain Name to Your AWS IP Address

Note: You must have a purchased domain name to do this step. You can buy one from Namecheap, GoDaddy, or a host (ha!) of other domain providers. If you do not have a domain name, then you can still view a single site on your EC2 instance by using the EC2-provided IP address. If, however, you want to set up subdomains, then a domain name is required. If you want to use HTTPS, which is strongly recommended and increasingly necessary, then you will need a certificate, and a domain name is required to use a certificate.

Copy the IP address of your EC2 instance by doing the following:

  • Log in to your AWS account.
  • Visit your EC2 Dashboard.
  • Visit your running instances.
  • Select the instance you have been configuring since the start of this guide.
  • Copy the IPv4 Public IP address ( in this example).

You should end up with something similar to what is shown below:

Now visit the domain provider site where you purchased your domain name. Each site is different, but you will want to manage your Domain Name Server (DNS) and create DNS records. We will create instances of the "A record."

what is a DNS "A record"?

As noted by NS1:

The most common DNS record used, the A record simply points a domain to an IPv4 address, such as To set up an A record on your domain all you’ll need is an IP address to point it to.

A blank record (sometimes seen as the ‘@’ record) points your main domain to a server. You can also set subdomains to point to other IP addresses as well, if you run multiple webservers. Finally, a wildcard record, shown usually as ‘’ or ‘,’ acts as a catch-all record, redirecting every subdomain you haven’t defined elsewhere to an IP address.

AAAA Records operate in the exact same way as A records, except they point to an IPv6 address, which look similar to FE80::0202:B3FF:FE1E:8329.

Start by creating a regular "A record," and then you can also create subdomains as you see fit. Before illustrating this process with a working example, consider the following image from MOZ that illustrates what a domain is:

The example that follows uses Namecheap as the domain provider site and as the root domain.

Our root domain will have the following:

  • Type: A record
  • Host: @
  • Value: The IPv4 address of your EC2 instance that you copied above ( in this example)
  • TTL: 1 minute (the TTL can be anything, but the lower the number the faster the worldwide DNS lookups will be established)

A subdomain will have the following:

  • Type: A record
  • Host: The name you would like prefixed to your domain name (we will create a subdomain example for the purpose of illustration; a user could then visit this subdomain by navigating to
  • Value: The IPv4 address of your EC2 instance
  • TTL: Your desired value (we will use 1 minute in this example)

For our working example we will have the following:

Tell Nginx about Our Server

We will now tell Nginx about our server by editing the sites-available file on our EC2 instance (from the EC2 terminal):

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ sudo nano /etc/nginx/sites-available/default

Comment out the default server block. Essentially, comment out all of the provided lines by prefixing them with #. This process is illustrated below:

You should follow one of three code examples given below depending on your use case:

  1. Static site without custom domain name: Just pointing your IP address to your project folder on your EC2 instance without using a domain name; that is, you will have a frontend only (i.e., static) example with no domain name. In this case, you will only be able to view the one site from your IP address. Change the name of the folder to where your index.html file exists:
server {
root /home/ubuntu/YOUR-FOLDER-NAME;
index index.html index.htm;
  1. Static site with custom domain name: Same as above (i.e., static) but with a custom domain name. Provide the directory location of your site to be served and your custom domain name.

For root domain (this could potentially be a good use case for your online portfolio):

server {
root /home/ubuntu/YOUR-FOLDER-NAME;
index index.html index.htm;

For subdomains:

server {
root /home/ubuntu/YOUR-FOLDER-NAME;
index index.html index.htm;
  1. Non-static sites: For a site running on Node with PM2 (i.e., non-static). You need to provide the correct directory location of your code, the domain that you want to see your site on, and the port number that you specified in your code for your application to listen on. Note that only one service can run on one port. If you have multiple services running, then they must be on different ports.
server {
root /home/ubuntu/YOUR-FOLDER-NAME;
location / {
proxy_pass http://localhost:YOUR-PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;

For the example project we have been working with throughout this guide, the following code was used:

server {
root /home/ubuntu/aws-demo-project;
location / {
proxy_pass http://localhost:4444;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;

You can now test the changes you have made by running sudo nginx -t from within your EC2 terminal:

#EC2 terminal
ubuntu@ip-172-31-20-54:~$ sudo nginx -t

You should hopefully see something like the following:

If you do not get the syntax is ok and test is successful messages, then you need to fix your sites-available file. Make sure all of your curly brackets are matching, words are spelled correctly, semicolons are properly placed, etc.

Get a Certificate from Certbot

Get a new certificate from Certbot. If you already have a certificate, then skip to the "updating certificates" section below. You only need to get a certificate once.

Visit the Certbot site and select Nginx and Ubuntu 18.04 LTS (bionic):

We will now follow the steps provided by Certbot to obtain our certificate (execute each command one by one; that is, do not copy and paste all of the commands and try to execute them all at once).

see the step-by-step instructions we follow below as they appear on the Certbot website

#EC2 terminal
demoec2 # SSH into the server running our HTTP website as a user with sudo privileges
ubuntu@ip-172-31-20-54:~$ sudo apt-get update
ubuntu@ip-172-31-20-54:~$ sudo apt-get install software-properties-common
ubuntu@ip-172-31-20-54:~$ sudo add-apt-repository universe
ubuntu@ip-172-31-20-54:~$ sudo add-apt-repository ppa:certbot/certbot # Press [ENTER]
ubuntu@ip-172-31-20-54:~$ sudo apt-get update
ubuntu@ip-172-31-20-54:~$ sudo apt-get install certbot python-certbot-nginx # Press Y and [ENTER]

If you have already done this, then you can simply update your certificate. Updates need to happen anytime you add a domain or subdomain to the sites-available/default file. Simply SSH into your EC2 server as above and run the following commands:

#EC2 terminal
demoec2 # SSH into the server running our HTTP website as a user with sudo privileges
ubuntu@ip-172-31-20-54:~$ sudo certbot --nginx
<email address>
<2> redirect

For all of the changes to take effect, you may need to restart Nginx:

#EC2 terminal:
ubuntu@ip-172-31-20-54:~$ sudo service nginx restart