Introduction
This post shows how to set up a minimal Flask application on Ubuntu 14.04 using Python 3.5 and Apache 2.4 using WSGI to communicate between the Web server and the application. It assumes that a team of developers will be sharing management of the code.As with any configuration task, there are always alternatives. This guide only covers one simple approach and makes no claim to be the best. On the other hand, it does claim to be simple to follow and reasonably complete.
You can follow the steps below in a dumb way if you like – that means copying and pasting the commands into the command line without paying any attention to their meaning. That should get you to a working system; HOWEVER, that is the dumb way – if you want to know how your system works and how to fix things when they go wrong, there is no alternative but to spend some time following through the documentation that is linked with each step.
Overview
Eventually, we will have an Apache Web server which receives all incoming http requests. It will then use the WSGI configuration to pass the request to the Flask application for handling. Each element in the chain needs to be installed and configured.We assume that the following decisions have been taken:
- The application will use a python virtual environment
- The application and the virtual environment will be in a shared location
- A directory /usr/local/env will contain all shared locations
- Application code will be kept separate from the environment code
- The name of the application is myApp
- The fully qualified host name is www.myapp.com
/usr/local/env/myApp |- myApp.wsgi |- app/ |- vmyApp/
myApp.wsgi is the file that Apache will use to communicate with the application
app/ is the directory where the application code goes
vmyApp/ is the directory that contains the virtual Python environment
The conventions being used are:
- The application name is unique on the server
- All similar applications will have an app/ directory for their code
- The name of the Python virtual environment is v + app name. This is to differentiate between environments if there is more than one application
Instructions
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3.5 /usr/bin/python
sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi-py3
sudo mkdir /usr/local/env
sudo mkdir /usr/local/env/myApp
sudo chmod o+w /usr/local/env/myApp
cd /usr/local/env/myApp
virtualenv -p python3 vmyApp
. /usr/local/env/myApp/vmyApp/bin/activate
pip3 install flask
mkdir app
touch app/__init__.py
- Create Hello World app:
Place the code below into the file /usr/local/env/myApp/app/myApp.pyfrom flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "Hello World!" if __name__ == '__main__': app.run() - Create the .wsgi file
Place the code below into the file /usr/local/env/myApp/myApp.wsgiimport sys sys.path.insert(0, '/usr/local/env/myApp/') activate_this = '/usr/local/env/myApp/vmyApp/bin/activate_this.py' with open(activate_this) as file_: exec(file_.read(), dict(__file__=activate_this)) from app.myApp import app as application - Create the site configuration file
Place the code below into the file /etc/apache2/sites-available/myApp.confServerName www.myapp.com WSGIDaemonProcess myApp python-home=/usr/local/envs/myApp/vmyApp threads=5 WSGIScriptAlias / /usr/local/env/myApp/myApp.wsgi WSGIProcessGroup myApp WSGIApplicationGroup %{GLOBAL} Require all granted sudo a2dissite 000-default
sudo a2ensite myApp.conf
sudo service apache2 restart
Notes:
Step 7: This allows all users of the server to write to the shared location which is not a good idea. However, these instructions were prepared for a development server where user and group access was controlled by a central administration service. Because of this, there was no option to create a dummy user account to ‘own’ the code. The assumption is that this is a development server, and that the production configuration would take more account of security.- Step 14: This is the standard Hello World that can be found all over the Web with the additional lines to allow it to work with WSGI
- Step 15: The second line inserts the application root directory into the Python load path. The last line makes reference to the app object in the myApp.py module which is inside the app package.
- Step 16: The WSGIScriptAlias points to the .wsgi file in the application root directory. The