Different Python versions under the same uwsgi Emperor?
Well, since I wasn't exactly overwhelmed by responses, here is the solution I came up with myself:
First, I created a new virtualenv with a Python 3 interpreter:
mkvirtualenv -p /usr/bin/python3 python3env
Then I installed the stock uwsgi from Pypi, which gets compiled automatically with a Python 3 interpreter:
pip install uwsgi
I created a configuration directory
/etc/uwsgi-python3 that contains the emperor.ini and a subdirectory vassals, containing vassal.ini. Finally, I added the following line to
/home/user/.virtualenvs/python3env/bin/uwsgi --ini /etc/uwsgi-python3/emperor.ini
Now there's an uwsgi Emperor running that uses the Python 3 interpreter for its vassals. It doesn't interfere with another uwsgi Emperor that was already running and uses the Python 2.7 interpreter.
I know it's not optimal, because I'm not using the pluggable interpreter architecture that's explained in the documentation (thanks roberto! I don't know how I could've overlooked that). However, it runs flawlessly and I didn't have to touch my existing uwsgi installation that's serving a bunch of production apps.
Under osx i made like this. I unistalled all uwsgi on my system (from brew from pip etc).
After that i downloaded under /usr/local the source code
wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz tar zxvf uwsgi-latest.tar.gz
cd uwsgi-2.0.17 make PROFILE=nolang
In this way i created an executable without plugins for python.
After that i made each plugin for each version on my system:
PYTHON=python3.6 ./uwsgi --build-plugin "plugins/python python36" PYTHON=python2.7 ./uwsgi --build-plugin "plugins/python python27" PYTHON=python2.6 ./uwsgi --build-plugin "plugins/python python26"
Now i have 3 plugins.
In my ini files for the emperor i specified the plugins dir and the plugin version for each file
[uwsgi] plugins-dir = /usr/local/uwsgi-2.0.17 plugin = python36 [uwsgi] plugins-dir = /usr/local/uwsgi-2.0.17 plugin = python27 [uwsgi] plugins-dir = /usr/local/uwsgi-2.0.17 plugin = python26 ...
I symlinked the uwsgi binary in my /usr/local folder
ln -s /usr/local/uwsgi-2.0.17/uwsgi /usr/local/bin/uwsgi
And after run the emperor
uwsgi --emperor /PATH/TO/INI/FILES/FOLDER/
And voila now i can run python26, python27 and python36 project simultaneously
Another possible solution is to reuse the system-wide "emperor", and only substitute the vassal with the new version. This way you don't need to invent any new folders under
/etc nor launch new services to
pipinto a virtualenv.
- Remove the
plugins=...line (because pip-compiled
uwsgidoes not support plugins).
Add the line:
unprivileged-binary-patch = /path/to/your/venv/bin/uwsgi
This will force the uWSGI emperor launch your own
uwsgibinary as the vassal.
- Remove the
Reload your app in the emperor
service uwsgi restart your-app.
The last step somewhy reports a failure to restart the server:
* Starting app server(s) uwsgi ...fail!
However, in reality, the new vassal starts fine as well as all the other apps. I did not find the time to debug this.