Setting up Flask and Apache on AWS EC2 Instance
Quickstart to getting a website running on Amazon Web Services
I create websites on EC2 pretty frequently but every time I do, I inevitably take 30 minutes to an hour with just the setup process. Flask, on its own, tends to be pretty straightforward but there are several other important steps that are less straightforward. Even among the tutorials that I have found online, none of them have worked out of the box and in the rare cases that they do, they do not satisfy all of my requirements.
This quickstart guide will use Python3, virtualenv, and will allow you to keep your project directory anywhere on your instance (I prefer to keep my project in ~/project-name rather than in /var/www/html). This guide is meant to document the process so that I can get through the setup process faster in the future and hopefully, it will help someone else as well.
Launch an EC2 instance
In the EC2 console, select an Ubuntu Server (t2.micro for free tier) and launch. Select an existing key pair
or create a new key pair and save it to your computer. I will save it askeypair.pem
. As for the security
group, add HTTP and HTTPS in the inbound rules section with the source set to Anywhere. Now, once the instance is
running, we can connect to it.
Connect to the EC2 instance
Open a terminal session in the directory where you have saved the key pair. Set permissions on the file.$ chmod 400 keypair.pem
Copy the EC2 Public DNS from the AWS EC2 Instance Description and save it to an environment variable. Something like:
$ export EC2_DNS="ec2-12-34-567-89.compute-1.amazonaws.com"
Connect to the EC2 instance.
$ ssh -i "keypair.pem" ubuntu@$EC2_DNS
Troubleshooting Note: Sometimes, keypair.pem is saved as keypair.pem.txt. Either rename and remove the .txt extension or replace keypair.pem in the instructions with keypair.pem.txt.
Setup Python3 Environment
First, update apt-get.$ sudo apt-get update
Python3 (3.5 at the time of writing) should be already available on EC2 but pip still needs to be installed.
$ sudo apt-get install python3-pip
Get virtualenv.
$ pip3 install virtualenv
Create the project folder or clone the project from your Git repository.
$ mkdir flaskproject
Set up the virtual environment.
$ cd flaskproject
$ python3 -m virtualenv venv
Activate the environment (use deactivate
to exit the environment).
$ . venv/bin/activate
Setup Flask
Install Flask$ pip install Flask
Note: You do not need to use pip3 or python3 within the virtualenv
since it is already a Python3 virtualenv. To be sure, you can run
python
while in the venv and check the version that
it displays.
app.py
$ vi app.py
Paste the following code in.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == "__main__":
app.run()
Setup Apache
Install mod_wsgi, make sure to have '-py3' at the end oflibapache2-mod-wsgi-py3
or the runtime will default to Python2.7
$ sudo apt-get install apache2 libapache2-mod-wsgi-py3
Create a wsgi file.
$ vi app.wsgi
Paste the following code in.
activate_this = '/home/ubuntu/flaskproject/venv/bin/activate_this.py'
with open(activate_this) as f:
exec(f.read(), dict(__file__=activate_this))
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/html/flaskproject/")
from app import app as application
Create a symlink so that the project directory appears in /var/www/html
$ sudo ln -sT ~/flaskproject /var/www/html/flaskproject
Enable wsgi.
$ sudo a2enmod wsgi
Configure apache (you will need to sudo to edit the file)
$ sudo vi /etc/apache2/sites-enabled/000-default.conf
Paste this in right after the line with DocumentRoot /var/www/html
WSGIDaemonProcess flaskproject threads=5
WSGIScriptAlias / /var/www/html/flaskproject/app.wsgi
<Directory flaskproject>
WSGIProcessGroup flaskproject
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
Restart the Server
$ sudo apachectl restart
Open the page in a browser
Get the Public DNS from EC2 or just exit
from EC2 and run
echo $EC2_DNS
to get the DNS. Paste it into a browser and
it should display "Hello, World!". From this point on, refer to
Flask documentation
to build your application.
Debugging
Internal Server ErrorIf anything goes wrong, first check the error logs using:
$ vi /var/log/apache2/error.log
My changes are not showing up. The page still displays "Hello, World"
Try restarting your apache server
$ sudo apachectl restart
I can't get out of vim!!
Sorry, can't help you there.
Trapped
Stack Overflow: Helping One Million Developers Exit Vim
To clear the log, run
sudo bash -c 'echo > /var/log/apache2/error.log'
Mistakes in the guide
If you find any mistakes here or find that something needs an update, feel free to send me an email.