setup of Amazon EC2 + Apache2 + WSGI + flask

This article shows how to create simple Flask application on ec2 with mod_WSGI, Apache2 in virtualenv of Python 3.4. Apache is a web server. Flask is framework to build fancy website easily and quickly. mod_WSGI let them talk.

Apache2 <=> mod_WSGI <=>Flask or Django in virtualenv

My environments:
  • Python3.4
  • ec2.nano in Oregon
  • virtualenv in ec2:  /usr/bin/myenv

 1. install Flask, WSGI and Apache2

To install wsgi and apache2, Do
yum search wsgi
Find an appropriate plubin containing WSGI and Apache2. For me,
sudo yum install mod24_wsgi-python34.x86_64
To install Flask in virtualenv,
sudo /usr/bin/myenv/bin/pip3 install flask
To install more libraries, read through my previous article

2. Create Flask File

Create Directory, /var/www/html/flaskapp (/var/www/html should have been created already by Apache). Create simple flask file in it,  /var/www/html/flaskapp/
#!/usr/bin/myenv python
#-*- coding: UTF-8 -*-
from flask import Flask
app = Flask(__name__)

def hello_world():
    return 'Hello from Flask!'

if __name__ == '__main__':'', port=5000, debug=True)

3. Create WSGI File

Create python file, /var/www/html/flaskapp/flaskapp.wsgi
We want to activate the virtual environment, but, I don't know why, libraries in the virtual environment cannot be imported. So, you may need site.toaddsitedir(your/venv/site-packages). To import, we insert the path (which may not needed as they are in the same folder). WSGI need app to be named "application, as you see the last line.

#!/usr/bin/myenv python
# -*- coding: UTF-8 -*-
import site
import sys

activate_this = '/usr/bin/myenv/bin/'
with open(activate_this) as file_:
    exec(, dict(__file__=activate_this))
import sys
sys.path.insert(0, '/var/www/html/flaskapp')

from flaskapp import app as application

Then, create an empty file in the same folder. Now your tree should be like (I have php file not used in this article).

[ec2-user@ip-xxx-xx-xx-xxx html]$ tree
├── flaskapp
│   ├──
│   ├── flaskapp.wsgi
│   └──
└── phpinfo.php

4. Apache setting

in /etc/httpd/conf/httpd.conf, I inserted followings just after DocumentRoot:

DocumentRoot "/var/www/html"
LoadModule wsgi_module modules/
WSGISocketPrefix /var/run/wsgi
WSGIPythonHome /usr/bin/myenv
WSGIPythonPath /usr/bin/myenv/lib64/python3.4/site-packages
<VirtualHost *:80>
    ServerAdmin mycustom20160623@localhost
    DocumentRoot "/var/www/html"
    WSGIDaemonProcess flaskapp threads=5 python-path=/usr/bin/myenv/lib64/python3.4/site-packages python-home=/usr/bin/myenv
    WSGIScriptAlias / /var/www/html/flaskapp/flaskapp.wsgi
    <Directory /var/www/html/flaskapp>
        Options +ExecCGI
        WSGIScriptReloading On
        WSGIProcessGroup flaskapp
        WSGIApplicationGroup %{GLOBAL}
        Require all granted

If you use older version of Apache, You may edit /etc/apache2/sites-enabled/000-default.conf

5. Restart apache

$ sudo service httpd restart

6. Access your website

type your public DNS in the browser.

Where is Error log?

$ cat /var/log/httpd/error_log

Why do you get Fatal Python error: Py_Initialize: Unable to get the locale encoding ?

When you find following in /var/log/httpd/error_log
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encoding' 

Your WSGIPythonPath (python-path) or WSGIPythonHome (python-home) is incorrect. WSGIPythonPath is where your modules are loaded. Activate virtualenv, import something, and see where it's from. For example,
>>> import numpy
>>> print(numpy.__file__)
For me, it was /usr/bin/myenv/lib64/python3.4/site-packages

WSGIPythonHome is where your python is. See by
>>> import sys
>>> sys.prefix
For me, it was /usr/bin/myenv. If your out of the virtual environment, it will be /usr
Also, python home should be in the first line of your .py file, like 
#!/usr/bin/myenv python