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/flaskapp.py

flaskapp.py
#!/usr/bin/myenv python
#-*- coding: UTF-8 -*-
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello from Flask!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', 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 flaskapp.py, 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.

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

site.addsitedir('/usr/bin/myenv/lib64/python3.4/site-packages')
sys.path.append('/var/www/html/flaskapp')
activate_this = '/usr/bin/myenv/bin/activate_this.py'
with open(activate_this) as file_:
    exec(file_.read(), 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 __init__.py 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.py
│   ├── flaskapp.wsgi
│   └── __init__.py
└── 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/mod_wsgi.so
WSGISocketPrefix /var/run/wsgi
WSGIPythonHome /usr/bin/myenv
WSGIPythonPath /usr/bin/myenv/lib64/python3.4/site-packages
<VirtualHost *:80>
    ServerAdmin mycustom20160623@localhost
    ServerName example.com
    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
    </Directory>
</VirtualHost>



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


5. Restart apache

Execute
$ 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


Bibliography

コメント