Run Django Python 2 and Python 3 apps with uWSGI and nginx on same server?

March 28, 2016 2k views
Django Python Nginx Ubuntu

How do I run multiple django apps using uwsgi and nginx on ubuntu 14.04 where one of them is on python 3 and the rest are on python 2?

This was originally asked by kimstacks in reference to the tutorial: "How To Serve Django Applications with uWSGI and Nginx on Ubuntu 14.04" - But I thought it would be useful to others so I reposted the Q&A here

2 Answers

You will probably have to have multiple emperor processes in this case. Usually, uWSGI is built against a particular version of Python. However, it is apparently possible to "stack" emperors so that a master emperor process can call individual Python version-specific emperor processes, which can then spawn your Django projects. I see that you've already found this StackOverflow thread on the subject.

I just tried this for the first time personally and was able to get it to work. The process is still very new to me, but I'll try to explain.

Start off by going through the tutorial as usual. For your Python 3 site, you'll want to create the virtual environment like this:

  • mkvirtualenv --python=/usr/bin/python3 python3projectname

If you run through the guide, you will have uWSGI built against Python 2 installed, and will be able to serve your Python 2 sites. To get the Python3 version working, you'll have to first install the development files through apt:

  • sudo apt-get update
  • sudo apt-get install python3-dev

Make a new virtual environment for the Python 3 version of uWSGI (you could just install this in your Python 3 virtual environment, but this allows for a more explicit separation so that it's obvious that it could run any number of Python 3 sites):

  • mkvirtualenv --python=/usr/bin/python3 python3uwsgi

Within this new virtual environment, install uWSGI. This will be built against Python 3:

  • pip install uwsgi

Deactivate the virtual environment when you are finished:

  • deactivate

The next change will be in the uWSGI structure. Since the system's uWSGI is built against Python 2, you can keep the Python 2 sites in the /etc/uwsgi/sites directory as normal. Make a new directory that will hold all of the uWSGI configs for your Python 3 sites:

  • sudo mkdir /etc/uwsgi/sites_python3

Move the uWSGI configurations for the Python 3 site(s) into this new directory:

  • sudo mv /etc/uwsgi/sites/python3projectname.ini /etc/uwsgi/sites_python3

We then need to add an additional uWSGI configuration file to the /etc/uwsgi/sites directory.

  • sudo nano /etc/uwsgi/sites/spawn_python3.ini

This .ini file will spawn another uWSGI emperor process, this time using the Python 3 version of uWSGI that we installed in the virtual environment. This emperor process will read the uWSGI configuration files within the /etc/uwsgi/sites_python3 directory:

project = python3uwsgi
base = /home/user

privileged-binary-patch-arg = %(base)/Env/%(project)/bin/uwsgi --emperor /etc/uwsgi/sites_python3

Now, when you start the Python 2 version of uWSGI (using the upstart file from this guide), it will, in turn, spawn an additional Python 3 emperor to handle your Python 3 sites.

  • sudo start uwsgi

I figured this out once and validated it a second time, but it's still a completely new process for me, so take the above as a starting point. Hopefully that helps though!

Perhaps not the approach you're looking for, but I would like to suggest you look at Docker for running multiple, different applications on a single host. You could start here for an example:

[disclaimer, I created that example]

Have another answer? Share your knowledge.