Flask/Python Deployment Guide
A quick guide on how to deploy your flask server on AWS!
- Server Setup and Initial Deployment
- docker-compose.yml
- Dockerfile
- Test preparation for Docker Web Application using IP for Internet Access
- Final preparation the Docker Web Application using DNS for Internet Access
- Update Deployment
Server Setup and Initial Deployment
Development Operations (DevOps) begins with server setup.
Amazon Web Services (AWS): Electric Cloud Compute (EC2) Setup
- To begin, head to the “Instances” dropdown on AWS and select “Instances.”
- From here, a variety of instances will show up. For this project, depending on which teacher you have, select either “NCS.cf Yeung CSP” or “NCS.gq Mort CSP”
- Then, run
$ sudo docker ps # This allows you to observe the ports that are currently being used
docker-compose.yml
- Next, head to VSCode on your local machine and update the docker-compose.yml and Docker files.
- Select a port that is not used and change the left side of docker-compose.yml port to be an unused port XYZ:8086. The “XYZ” would be the port that you have selected.
- The right side 8086 matches the port you have used in your Docker file in two locations - 8080 is typically used as an internal port.
version: '3'
services:
web:
image: flask_port_v1 # The image name should be unique to your project
build: .
ports:
- "XYZ:8086" # The "XYZ" would be the port that you have selected.
volumes:
- ./volumes:/volumes
- ./instance:/instance
restart: unless-stopped
Dockerfile
- Check that your Dockerfile is the same as below
FROM docker.io/python:3.10
WORKDIR /
# --- [Install python and pip] ---
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y python3 python3-pip git
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install gunicorn
ENV GUNICORN_CMD_ARGS="--workers=3 --bind=0.0.0.0:8080"
EXPOSE 8080
CMD [ "gunicorn", "main:app" ]
- In VSCode, open up your terminal. Run
sudo docker-compose up
and make sure it builds properly. Type localhost:XYZ in your browser (XYZ is the unused port you have selected). Check for any errors occur in the Terminal. If this fails, please be sure to review the previous steps. - If all is well, make sure to commit your changes to docker-compose.yml & Dockerfile
Clone and Change Directory to project location
This command allows you to clone your GitHub repository onto the AWS instance. In this example, the GitHub HTTPs link is: https://github.com/nighthawkcoders/flask_portfolio.git.
- Head back to either the instance “NCS.cf Yeung CSP” or “NCS.gq Mort CSP” on AWS
Note
Your repository should be using the APCSP flask_portfolio as a template
- Once you are in the instance, run
ls # Check the other repository names, make sure that the one the name you select does not match the ones that appear when running this command
- Next, run
$ cd
$ git clone https://github.com/nighthawkcoders/flask_portfolio.git my-unique-name
# Replace "my-unique-name- with your desired name for this repository, it is recommended that your table number and period are featured in this name to avoid confusion among groups
$ cd my-unique-name
- Once you are in your repository, run
docker-compose up -d --build
- To make sure that your application is running, run the following command
curl localhost:XYZ # Replace XYZ with the port you have selected
Test preparation for Docker Web Application using IP for Internet Access
Each student scrum team will perform Nginx test and verify Group Web Project is working on EC2 instance. This step is can only support a single Web Application at a time.
This Step is dependent on…
- EC2 Public IPs: 3.233.212.71
- Docker Port: 8086
Enable Nginx to retrieve default Web Application using IP Address from internet request (Reverse Proxy)!
- Install Nginx on Ubuntu servers
$ sudo apt install nginx
- Go to location of Nginx server configuration files
$ cd /etc/nginx/sites-available
- Open editor to Create your own “Nginx test configuration”.
$ sudo nano my-unique-file # Replace "my-unique-file" with the name you wish to call your nginx file
- Edit your own Nginx server configuration making modifications to:
- IP Address: 3.233.212.71
- docker-compose, proxy pass Port: 8086
Requirements
- A unique name for your file
-
DNS name for server Link to Jeffery F’s DNS Domain Guide
- Change the port in proxy_pass line to the one you have previously selected
server {
listen 80;
listen [::]:80;
server_name 3.233.212.71;
location / {
proxy_pass http://localhost:8086;
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" *;
}
# Preflight requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
}
Activating Nginx configuration
- Activate/enabled Nginx server configuration:
- nginx configuration file: test
$ sudo ln -s /etc/nginx/sites-available/my-unique-file /etc/nginx/sites-enabled # Replace "my-unique-file" with the name of your nginx file $ sudo nginx -t
- nginx configuration file: test
- If there are errors, something is wrong…
- Perhaps you are missing semicolon at the end of server)name or proxy_pass lines.
- Perhaps link to file in sites-enabled is bad as a result of bad syntax in
ln -a
command.- There are two directories
/etc/nginx/sites-available
and/etc/nginx/sites-enabled
. - The 1st is for preliminary editing, the second is for activation. Perform
ls
in/etc/nginx/sites-enabled
and make sure all the names look correct. - Correct by
rm
of mistake in/etc/nginx/sites-enabled
without deleting original file in/etc/nginx/sites-available
. Then repeatln -s
command.
- There are two directories
- If there are no errors, restart NGINX so the server to activate
/etc/nginx/sites-enabled
files:$ sudo systemctl restart nginx
- Check that your server is running on the browser using the domain using http://mydomain
- Replace “mydomain” with the domain you have previously selected
Final preparation the Docker Web Application using DNS for Internet Access
There are additional steps to this preparation. We need to direct the internet to the AWS server running the Web Application, this is done using Domain Name Service (DNS). After being directed to the Web Server, the server needs to respond to the HTTP (Hyper Text Transfer Protocol) request. The proxy of HTTP to your Web Application is manged by Nginx. Finally, we will Secure HTTP (HTTPS), with a utility called Certbot.
Certbot configuration
Each student scrum team will learn Certbot on on AWS EC2 test server, establish working https web application. The final configuration will be on AWS server managed by Teachers or Student DevOps Engineers.
$ sudo certbot --nginx
- Make sure that your domain appears on the list of names to activate HTTPS…
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: coolcodersjava.pw
2: www.coolcodersjava.pw
3: ajarcade.duckdns.org
4: flowhealth.duckdns.org
5: goatedgroup.duckdns.org
6: jasj-inventory.duckdns.org
7: recipies.duckdns.org
8: ssvgcars.duckdns.org
9: userapi.duckdns.org
10: fr0st.ml
11: www.fr0st.ml
12: agenda.nighthawkcodescrums.gq
13: coolcoders.nighthawkcodescrums.gq
14: escaperoom.nighthawkcodescrums.gq
15: frost.nighthawkcodescrums.gq
16: jame.nighthawkcodescrums.gq
17: lawnmowers.nighthawkcodescrums.gq
18: loopholegames.nighthawkcodescrums.gq
19: musicmania.nighthawkcodescrums.gq
20: nba.nighthawkcodescrums.gq
21: sadv.nighthawkcodescrums.gq
22: ssjn.nighthawkcodescrums.gq
23: stocks.nighthawkcodescrums.gq
24: striver.nighthawkcodescrums.gq
25: tngc.nighthawkcodescrums.gq
26: white.nighthawkcodescrums.gq
27: workwatch.nighthawkcodescrums.gq
28: cars.nighthawkcodingsociety.com
29: dolphin.nighthawkcodingsociety.com
30: saakd.nighthawkcodingsociety.com
31: pythonalflask.tk
32: www.pythonalflask.tk
33: teambrobro.tk
34: www.teambrobro.tk
35: teamcheeseatimetime.tk
36: www.teamcheeseatimetime.tk
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): # ENTER YOUR CORRESPONDING NUMBER
Cert not yet due for renewal
You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/nighthawkcodingsociety.com-0001.conf)
What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Attempt to reinstall this existing certificate
2: Renew & replace the cert (limit ~5 per 7 days)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for nighthawkcodingsociety.com
http-01 challenge for csa.nighthawkcodingsociety.com
http-01 challenge for cso.nighthawkcodingsociety.com
http-01 challenge for flm.nighthawkcodingsociety.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/nighthawk_society
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/nighthawk_csa
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/nighthawk_csp
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/nighthawk_flm
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Traffic on port 80 already redirecting to ssl in /etc/nginx/sites-enabled/nighthawk_society
Traffic on port 80 already redirecting to ssl in /etc/nginx/sites-enabled/nighthawk_csa
Traffic on port 80 already redirecting to ssl in /etc/nginx/sites-enabled/nighthawk_csp
Traffic on port 80 already redirecting to ssl in /etc/nginx/sites-enabled/nighthawk_flm
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Your existing certificate has been successfully renewed, and the new certificate
has been installed.
The new certificate covers the following domains:
https://nighthawkcodingsociety.com,
https://csa.nighthawkcodingsociety.com,
https://csp.nighthawkcodingsociety.com, and
https://flm.nighthawkcodingsociety.com,
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=nighthawkcodingsociety.com
https://www.ssllabs.com/ssltest/analyze.html?d=csa.nighthawkcodingsociety.com
https://www.ssllabs.com/ssltest/analyze.html?d=csp.nighthawkcodingsociety.com
https://www.ssllabs.com/ssltest/analyze.html?d=flm.nighthawkcodingsociety.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/nighthawkcodingsociety.com-0001/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/nighthawkcodingsociety.com-0001/privkey.pem
Your cert will expire on 2022-03-06. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
- Conclude this process by running
sudo certbot --nginx
and testing https://mydomain - Replace “mydomain” with the domain you have previously selected
Update Deployment
- To update your code, run
$ sudo docker-compose kill
Killing flask_portfolio_web_1 ... done
- From here, the server should be down and displaying a 502 error
$ git pull # This allows you to update your code
- Then, rebuild your container by running…
$ sudo docker-compose build --no-cache
Note
-
This step can take a few minutes
-
Finally, run…
$ sudo docker-compose up -d
Recreating flask_portfolio_web_1 ... done
- If all of the steps have been completed properly, the server should be back up with the applied changes/updates