Using Conda environments with Flask and Apache

With the advent of ABlooper, we’ve recently introduced OpenMM as a new dependency for the SAbDab-SAbPred antibody modelling platform. By far the easiest way to install the OpenMM Python API is via Conda, so we’ve moved to Conda environments for the entire platform. This has made installation of the platform much easier, but introduces complications when it comes to running its web applications under Apache. In this post, I’ll briefly explain the reason for this, and provide a basic guide for running Flask apps using Conda environments under Apache.

Anybody who knows me knows I’m a big advocate of using Conda for research code to help with installation and reproducibility. When it comes to using Python web frameworks like Flask and Django under Apache, however, I’m not quite so evangelical. The reason is simple: web frameworks in Python use the WSGI specification to interface between servers and applications, and Apache has its own module, mod_wsgi, that it uses to run WSGI applications. The mod_wsgi module needs to be compiled against the version of Python that will be used to run the apps, which can get messy when you have a shared python interpreter on the system and a user Conda installation. This is compounded by Apache running apps under a unique user, typically called ‘www-user’. This user has its own set of environment variables which, if not set correctly, will result in even more problems when trying to use a Conda environment to run an application. In short, Conda and mod_wsgi do not play nicely out of the box.

Fortunately, the mod_wsgi developers have provided a solution that makes it easy to point Apache to a version of mod_wsgi compiled for your conda installation using a tool called mod_wsgi-express. Here I’ll give an example from a Ubuntu virtual machine. First, in your base environment:

# Install mod_wsgi
$ pip install mod_wsgi

# Get the path to the mod_wsgi-express packaged with your mod_wsgi
$ which mod_wsgi-express
> /home/vagrant/miniconda3/bin/mod_wsgi-express

# Get the information needed to configure Apache to use this mod_wsgi
$ sudo /home/vagrant/miniconda3/bin/mod_wsgi-express install-module

> LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so"
> WSGIPythonHome "/home/vagrant/miniconda3"

The two lines of output from mod_wsgi-express are what we need to tell Apache where to find 1. the mod_wsgi module and 2. the corresponding Python environment. We now need to update the Apache configuration files using this information. There are two files to modify as root:

  1. wsgi.load
  2. wsgi.conf

First, open /etc/apache2/mods-available/wsgi.load and add the first line of the mod_wsgi-express output. Comment out any other LoadModule directives.

LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so"

Next, open /etc/apache2/mods-available/wsgi.conf and add the second line of the mod_wsgi-express output:

<IfModule mod_wsgi.c>
    WSGIPythonHome "/home/vagrant/miniconda3"
</IfModule>

These two changes will register your mod_wsgi module with Apache and tell it to use your conda environment as its default python while mod_wsgi is enabled. You can still set up process groups using different python environments within this conda installation.

With the correct mod_wsgi now available to Apache, we can now create daemon processes for our applications using conda environments by editing the configuration file in sites-available. For example, to set up a simple flask app using the default config file and the base conda environment, we can add the following to /etc/apache2/sites-available/000-default.conf

WSGIDaemonProcess flaskapp python-home="/home/vagrant/miniconda3" python-path="/data/apps/flask"
WSGIScriptAlias / /data/apps/flask/main.wsgi
<Directory /data/apps/flask>
    WSGIProcessGroup flaskapp
    WSGIApplicationGroup %{GLOBAL}
    Require all granted
</Directory>

To use other conda environments, simply add the required WSGIDaemonProcess directives pointing to the environment you wish to use.

Author