The article provides a step-by-step guide on deploying a Python Flask API on an Apache web server using an Amazon EC2 instance.
Abstract
The article, "Build a Web Server with Flask and AWS," is a comprehensive tutorial on setting up a scripted Apache web server with a Python Flask API on Amazon Web Services (AWS). It walks readers through the process of launching an EC2 instance, selecting the appropriate Amazon Machine Image (AMI), configuring instance details, adding storage, and setting up security groups to allow HTTP traffic. The author emphasizes the use of the AWS free tier for those engaging in hobby projects or research and development. A key feature of the setup is the use of "User data" to execute a script that automates the installation and configuration of the necessary software, including Flask and Apache. The guide also touches on the importance of assigning a public IP address, creating a swap file, and using a Python virtual environment. The article concludes with the successful deployment of the web server, demonstrated by a "Hello world!" message served by both the Flask application and the Apache server.
Opinions
The author believes that the "User data" functionality in AWS EC2 is underrated and highly beneficial for automating server setup.
The guide assumes that readers may be new to AWS or server setup, as it explains basic concepts and the significance of the free tier.
The author suggests that using a t2.medium instance type would be a realistic minimum for a production environment, indicating a preference for performance and reliability over cost for serious applications.
By including the option to open TCP port 5000, the author acknowledges the usefulness of testing the Flask server independently from Apache, which can be beneficial for troubleshooting and development.
The article implies that the setup process, although automated, requires patience as it may take up to 10 minutes for the instance to be fully provisioned and ready.
The author encourages readers to engage with the content by following them on Medium and LinkedIn, suggesting a desire to build a community or readership around their technical content.
There is an implicit endorsement of using SSL/TLS for a secure web server, although it is noted to be out of scope for the current article.
Build a Web Server with Flask and AWS
How to Build a Scripted Apache server with a Python flask API in AWS
I’m going to walk you through deploying a scripted Apache web server with a Python flask API in minutes. This will be done with an Amazon EC2 instance.
The first step is to log into the Amazon AWS console. Search for “EC2” in the search or click on “EC2” in the “Recently visited services” if it is there.
The EC2 console should look something like this. Click on “Launch instances” to launch a new instance.
I’m going to assume you want to use the free tier. Most of the AWS services provide a free tier which is great for hobby projects or research and development.
Please select “Red Hat Enterprise Linux 8 (MVM), SSD Volume Type” in the list below. You will see it says “Free tier eligible” below it.
For this demonstration please select “t2.micro”, which is also “Free tier eligible”. If you are planning on using this in production and happy to pay for this then you can select a more appropriate option below. I would normally say “t2.medium” would be the realistic minimum if you were paying for this.
This is arguably the most important screen in this walkthrough. Make sure you set “Auto-assign Public IP” to “Enable”. You can also keep this disabled and deploy a load balancer or use an Elastic IP as an alternative but this is out of scope. For the purpose of this walkthrough we are going to auto assign a public IP. Please be aware that this public IP will change every time the instance is started, it’s not permanent!
The most important part here is the “User data” under “Advanced Details”. This is such underrated functionality but it really is amazing. This allows you to provide a script to be run after the instance is provisioned. I’ve created a public Gist with the script you need to include in the “User data” section.
This will do the following:
Update the system using the yum package manager
Install the necessary packages using yum
Upgrade the Python package manager (PIP)
Install Flask using PIP
Set Apache to start on system boot
Create a swap file
Pull down the Flask files I created for you
Create a Python virtual environment
Restart Apache
The next part is to select the storage. Just accept the default size.
You can accept the default settings for the tags. I normally like to add at least “Name” and “Project” tags as they are good for general administration and billing but for the purposed of this walkthrough it’s not necessary.
This next part is important as well, so pay attention. We will be giving our instance a public IP address but this does not mean it’s visible to the outside world. In fact, by default, it won’t be. Create yourself a new security group, and give it a name. Something like “acl-web-in” may be an appropriate name. You need to allow TCP 80 (HTTP) for a basic unencrypted web server. SSL/TLS is out of scope of this article. For the purposes of this walkthrough you can just open up TCP 80 to the outside world. You may wonder what that custom TCP 5000 is there for. This is optional, and allows you to test flask on its own without Apache. I’m including it here for your information. You can either leave it in until everything is working or omit it now, it’s up to you.
The next page is the final review before launch. We should be good to go, so just click “Launch”.
When you click “Launch” it will ask you if you want to create a new key pair or use an existing key pair. I have a key already, so I will use mine. If you don’t have a key already, create one, and download it. It will be a .pem file.
When we click “Launch Instance” it will initiate the build. This will include the script from “User data”. This is a completely automated process to please allow for 10 (give or take) minutes to complete fully.
Select “Instances” from the side menu and click on the instance being provisioned. As you can see below my “Instance state” is “Pending”. What we want to extract here is the “Public IPv4 address”. Please make a note of yours, for this build mine is 18.203.85.109.
That that’s it folks!
In roughly 10 minutes, a completely automated build of an Apache web server running Python flask will compete. You will be able to browse to your web server using the IP address extracted above.
What is serving that “Hello world!” as that’s not basic HTML.
I can demonstrate this by logging into my EC2 instance.
.ssh % ssh -i AWSPersonal.pem ec2-user@18.203.85.109
The authenticity of host '18.203.85.109 (18.203.85.109)' can't be established.
ECDSA key fingerprint is SHA256:oew0XcqG8QRYr2aK+qOmbXqBhQ56apX+xcrswCHZnUc.
Are you sure you want tocontinue connecting (yes/no/[fingerprint])? yes
I sudo to root.
[ec2-user@ip-172-31-28-79 ~]# sudo su -
[root@ip-172-31-28-79 ~]#
I browse to the web root.
[root@ip-172-31-28-79 ~]# cd /var/www/html
[root@ip-172-31-28-79 html]#
(html) [root@ip-172-31-28-79 html]# export FLASK_APP=run.py
(html) [root@ip-172-31-28-79 html]# flask run --host=0.0.0.0
* Serving Flask app 'run.py' (lazy loading)
* Environment: production
WARNING: This is a development server. Donot use it in a production deployment.
Use a production WSGI serverinstead.
* Debug mode: off
* Running onall addresses.
WARNING: This is a development server. Donot use it in a production deployment.
* Running on http://172.31.28.79:5000/ (Press CTRL+C to quit)
<removed> - - [20/Aug/202108:44:15] "GET / HTTP/1.1" 200 -
<removed> - - [20/Aug/202108:44:15] "GET /favicon.ico HTTP/1.1" 404 -
If I open, “http://18.203.85.109:5000” in my browser I still see the “Hello world!” message but it’s being served by the flask server and not Apache. This is an optional step but useful for testing and troubleshooting purposes.
For interest sake the “Hello world!” is being served with a REST GET call using the Apache “mod_wsgi.so” module in Apache. The file being loaded is, “app/__init__.py”.
If you found this useful please don’t forget to let me know in the comments, and follow me on Medium.