Wherever I can, I avoid compiling applications from source or packaging up my own versions of things that exist in popular repositories. I recently needed to run a Python 3 application via uWSGI on CentOS 7 and was frustrated at how many search results were recommending building uWSGI from source when it’s available in EPEL. I’ve only deployed a handful of Python applications, and was not interested in keeping up with source-compiled dependencies to support this small project over time. We’ll discuss a couple of different ways to run these programs together with minimal customization.
In CentOS 7, you can run Python 3.4 alongside Python 2.7 as it is available in EPEL.
1 2 3
If you want to install pip, simply
yum install python34-pip and it will install at
/usr/bin/pip alone as that is part of the
python2-pip package. This was only available recently (late 2016); previously you had to manually install and deal with
/usr/bin/pip being overwritten.
Since 3.3, Python supports creating virtual environments without an external module like
pyvenv was the “recommended tool” for this initially, though it is deprecated in Python 3.6. As such, to lean into the preferred Python nomenclature, you can use the venv module directly to create Python 3.4 virtual environments:
1 2 3
If you like using virtualenv, you’ll be disappointed to see that there is no
python34-virtualenv package available in EPEL. While you could
pip3 install virtualenv, that would install at
/usr/bin/virtualenv, potentially overwriting the same file provided by the
python-virtualenv package. But, if you do, consider the following:
1 2 3 4 5 6 7 8 9 10 11
Unless you have a compelling reason for
virtualenv on your servers, use the built-in
venv module. I don’t like to overwrite files provided by packages, and we should use recommended upstream tools where possible.
Since uWSGI is provided by EPEL, there is no need to install it with
This will install the Python 3.4 uWSGI plugin to
/usr/lib64/uwsgi/python3_plugin.so. Be sure to include the directive
plugin = python3 in your uWSGI definition and proceed as normal (beyond the scope of this post).
Python 3.5 Software Collection
I love Software Collections. With Python 2.7 being the default version of Python with CentOS 7, I find it much better to keep another version in a completely separate directory structure than integrating with
/usr and such. We’ll use a rebuild of the Red Hat SCL for Python 3.5, and everything will be installed to
1 2 3
You’ll quickly notice that the newly-installed Python 3.5 binary is not in your
$PATH; it’s in
/opt/rh/rh-python35/root/bin. You have a few options:
Launch a new instance of bash:
Alternatively, you can modify your existing session by running one of the following manually, or add to
1 2 3 4 5
After installing, you can use
You can use the built-in method:
Or, you can use
virtualenv (though, see the 3.4 section for the rationale I recommend against this):
1 2 3
While there is a
uwsgi-plugin-python3 RPM, it’s for the aforementioned
python34 package. This is where you will have to compile something manually; so carefully consider the pros and cons of using a Software Collection. (Later, I may add to this post where you can use a yum post-install or post-upgrade action to ensure the compiled plugin is kept up to date.)
This is a helpful exercise to learn how you can integrate packages that install to default paths and a Software Collection which is kept away from default paths.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
After completing, your resulting uWSGI file will need to contain:
Which should you use?
If you need Python 3 but want to reduce the amount of customization that you need to do, I recommend installing
python34 from EPEL. You can use it with uWSGI with no compiling from source.
If Python 3.4 is too old and/or you need 3.5+ functionality, the Software Collection can be an alternative to compiling Python from source and knowing that you’re getting quality packages designed by Red Hat and rebuilt by CentOS.
If you need Python 3.6, or a newer release of 3.4 or 3.5 not provided quickly enough by the package maintainers, and you don’t want to deal with all of the pain of
./configure && make && sudo make install, I would suggest looking at pyenv to meet your needs.
Please let me know if I missed something or should add anything. I’m cumulatively green with running Python in production but wanted to share my learnings as I was frustrated by the lack of good information for my needs. Feedback is welcome.