In this guide, you’ll work through the process of
- purchasing a domain name,
- configuring that domain name to point to a server,
- setting up a server, and
- configuring HTTPS.
This process will take some time, make sure to budget at least 1 hour.
- Domain Registrar - A domain registrar is a company that has been granted permission by ICANN (the Internet Standards body) to lease domain names to an end user for a yearly fee. You can get 1
.me
domain name for free through the Github Education Student Developer Pack. If you prefer.com
or.org
, this will require a yearly fee of around $15 for each year you wish the domain to be active. - Domain Name Service (DNS) - DNS is the phonebook of the internet. It allows you to tell a browser when a person visits google.com, where the server that runs google.com lives.
- Elastic Compute 2 (EC2) - EC2 is Amazon Web Service’s (AWS) virtual server hosting service.
- SystemD - SystemD is a modern service standard for servers that allows application servers to run as background servers so they automatically start when the server boots, and they can easily be restarted.
- Target Group - AWS Target Groups are the intermediary between load balancers (which receive internet traffic) and EC2 instances which run the web application.
- Elastic Load Balancer (ELB) - ELBs are AWS’s primary internet traffic receipt mechanism. They can receive traffic from external sources (users) and forward that traffic to any internal source.
This guide will make use of Namecheap as the Domain Registrar and Cloudflare as the DNS provider. You are welcome to use others as desired.
We’ll start at the bottom with the server, then work our way up to the domain.
- Sign up for an account on AWS using their Free Tier.
Warning: The free tier lasts for one year (12 calendar months) after which payment is required for the services used.
- Once you have logged into the Console, use the search bar at the top to search for EC2, then click the service.
- Under Resources, you'll see a yellow button labeled
Launch Instance
. Go ahead and click it.- Under Names and Tags, give your server a good name like
Web Server
. - Under Application and OS Images, change the image type to
Ubuntu
then pick the most recent LTS from the AMI dropdown. - Under Instance Type, leave
t2.micro
selected. - Under Key Pair, click
Create new key pair
. Enter a name likeWeb Server
, but leave all other settings as their default. Ensure the downloaded file when you click create is stored somewhere safe. If you lose this, you lose access to your server. - Under Network Settings, use the default settings.
- Under Configure Storage, use the default settings.
- Click Launch Instance to the right.
- Under Names and Tags, give your server a good name like
- Click on the link to return to the instances screen and wait a few moments while your server boots.
- Once your server has an ip address, attempt to connect to it with:
ssh -i "<Login Key>.pem" ubuntu@<ip address>
(ex:ssh -i "Web Server.pem" [email protected]
). Note: you may receive a warning on your first server connection, asking if you trust the key, typeyes
then hit enter. If you receive a permissions warning strengthen the permissions withchmod 0600 "<Login Key>.pem"
. - Once logged into the server, run security updates:
sudo apt-get update && sudo apt-get upgrade -y
- Now install python:
sudo apt-get install -y python3-pip
- Type
exit
to leave the server and return to your machine.
Congratulations! You have a server running in the cloud, but it has nothing on it. Let's fix that.
- Login to your server again:
ssh -i "<Login Key>.pem" ubuntu@<ip address>
. - Create a directory to house your web application
mkdir flask-app
. - Exit the server.
- Download this repository, extract the zip, then
cd
into the extracted folder. - Let's copy the
flask_app.py
file to the folder you just made on the server.scp -i "<Login Key>.pem" flask_app.py ubuntu@<ip address>:~/flask-app/
- Do the same with the
requirements.txt
:scp -i "<Login Key>.pem" requirements.txt ubuntu@<ip address>:~/flask-app/
Note: As you move forward with your project, any changes you make to either file on your local machine will need to be copied to the server with the same commands. Ditto goes for any new files.
- Finally, copy the
flask-app.service
files:scp -i "<Login Key>.pem" flask-app.service ubuntu@<ip address>:~/
- Log back into the server, then
cd flask-app
. Runls
to see that theflask_app.py
andrequirements.txt
were copied successfully. If you don't see the files, stop here and reattempt the above or seek help until they are present. - Let's setup flask and try the server.
sudo pip3 install --break-system-packages -r requirements.txt
python3 flask_app.py
You should see a message that the app is running.
- Stop the app with
<crtl> + c
thencd ..
. Runls
to see the service file you copied earlier. If you don't see the file, stop here and reattempt the above or seek help until it is present. - Let's install the service.
sudo cp flask-app.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable flask-app
sudo service flask-app start
- Now if you run
sudo service flask-app status
you should be able to see the service running. - NIf you need to change the service you can stop it with
sudo service flask-app stop
or restart it withsudo service flask-app restart
.
All right, our service is running but isn't accessible at all to users, which means its kinda pointless, let's fix that.
- In the AWS Console, using the search bar, search for
Security Groups
. - There should be two security groups, a
default
and alaunch wizard
. We are not going to touch thedefault
group. - Name the
launch wizard
group toweb-server-tg
. - Make another security group named
load-balancer-sg
. - Under Inbound Rules, add two rules.
- Copy the security group id of your new group.
- Edit the inbound rules of your
launch wizard
group. Add a new rule. - In AWS Console, using the search bar, search for Target Groups.
- Create a new target group.
- In AWS Console, using the search bar, search for Load Balancers (the ec2 one).
- Create a new load balancer.
- Pick Application Load Balancer for the type.
- Name the load balancer
web-server-lb
. - Check all the boxes under Network Mapping.
- Under security groups, remove default, and select your
load-balancer-sg
group. - Under Listenders and Routing, change the target group to
web-server-tg
. - Click create load balancer.
- On the next screen, wait until your load balancer is provisioned, then copy / paste the DNS name into a browser. Your website should appear (Note: You may have to wait until 2 hours).
The website works! And other folks can access it, but that domain name isn't very nice. Let's get a nicer domain name and set it up.
Note: I assume at this point you have created Namecheap and Cloudflare accounts. I also assume you have acquired a domain name either through Namecheap's Github Education Pack deal, or by purchasing one yourself. The domain I will use as an example is
https://ethantmcgee.me
- Login to your Namecheap Dashboard, then go to Domains and click Manage beside the domain we are setting up.
- In another tab, login to your Cloudflare dashboard, then click Add Site.
- Back on Namecheap. Find the Nameservers section, change to Custom DNS, and paste in the two nameservers Cloudflare provided, then click the green check.
- Close the Namecheap tab.
- Back on Cloudflare.
- Click Continue.
- On the next screen, enable automatic HTTPS Rewrites, enable Always Use HTTPS, disable brotli (if you are not offered this option, ignore as this is a setting Cloudflare plans to soon deprecate.)
- Click Finish.
- Click the DNS button in the corner.
- Click Add Record.
- For the type use CNAME, for the Name use
@
and for the value, use AWS's Domain Name for the load balancer. - Click Save.
- Repeat this process, but change the name to
www
. - Click Save.
- Wait 1-2 hours, then visit your domain (i.e.
https://ethantmcgee.me
) in a browser. It should work.
Our site is "secure" but not as much as it should be. The following part is optional but will allow you to increase your security so that communication to your site is end to end encrypted, which is signifigantly safer.
- Login to Cloudflare, then go to your domain.
- In the side bar on the left, click SSL / TLS > Origin Certificates.
- Click Create an origin certificate.
- Whem prompted, make sure to use PEM. (Do not close this page yet).
- In a new tag, go to AWS, and open your load balancer. Click Actions > Add Listener.
- For this listener, use HTTPS, and forward traffic to
web-server-tg
like we did before. - Under the secure listener settings, choose import certificate, and paste the values from the cloudflare tab (warning, they are in backwards order!)
- Save, then edit your HTTP:80, listener, change this to redirect to a url and set the redirect port to 443, then save.
- Back on Cloudflare, click ok, then go to SSL / TLS > Overview.
- Finally, change the mode to Full (Strict)
That's it! Your site may be unavailable for a few moments while the security changes take effect, this is normal.
Note: the certificate here is only valid for 15 years, so if your site is still running then, you'll need to repeat this process. There are ways to automate the renewal, but those are beyond the scope of this guide.