Sunday, March 11, 2018

Setting up the server for a team Flask project

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
We should end up with the following directory structure:

/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

  1. sudo rm /usr/bin/python
  2. sudo ln -s /usr/bin/python3.5 /usr/bin/python
  3. sudo apt-get install apache2
  4. sudo apt-get install libapache2-mod-wsgi-py3
  5. sudo mkdir /usr/local/env
  6. sudo mkdir /usr/local/env/myApp
  7. sudo chmod o+w /usr/local/env/myApp
  8. cd /usr/local/env/myApp
  9. virtualenv -p python3 vmyApp
  10. . /usr/local/env/myApp/vmyApp/bin/activate
  11. pip3 install flask
  12. mkdir app
  13. touch app/__init__.py
  14. Create Hello World app:

    Place the code below into the file /usr/local/env/myApp/app/myApp.py
    from flask import Flask
    app = Flask(__name__)
    
    
    @app.route('/')
    def hello():
        return "Hello World!"
    
    if __name__ == '__main__':
        app.run()
  15. Create the .wsgi file

    Place the code below into the file /usr/local/env/myApp/myApp.wsgi
    import 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
  16. Create the site configuration file

    Place the code below into the file /etc/apache2/sites-available/myApp.conf
    
        ServerName 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
        
    
  17. sudo a2dissite 000-default
  18. sudo a2ensite myApp.conf
  19. sudo service apache2 restart

  20. 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 directive points to the application root directory and ensures that all subdirectories are accessible to the Web server.




No comments: