Server Setup

Do not run pip as root

by , , revisited on

We have by far the largest RPM repository with NGINX module packages and VMODs for Varnish. If you want to install NGINX, Varnish, and lots of useful performance/security software with smooth yum upgrades for production use, this is the repository for you.
Active subscription is required.

It is quite unfortunate that there is very little stating on the web of the quite obvious thing to be aware of.
In plain text, with big loud characters, I’ll put it here for everyone to remember:

Do not ever run pip as root

Here, I’m going to touch on why not to run pip as root, give some examples on how it’s going to break things miserably, and what to do instead.
Let’s go.

Python and your system

Each Linux/GNU distro is unique in some way. But their common feature is the package management system.
For Debian-based systems, that is apt. For CentOS/RHEL/Fedora, it’s yum or dnf, and this is what we’ll touch in our examples.

You will find that many Python modules are available through the yum repositories as RPM packages, e.g.:

  • python2-requests
  • python2-tqdm
  • etc, etc.

You can simply install them as any other package, for example:

sudo yum install python2-requests

Python modules that are available through yum (dnf) often serve as a base for the core OS functions like yum itself.

Not even that. All the packaged software that depends on Python modules in one way or the other, will depend on the system-packaged Python modules.


Now, pip is the installer/manager for Python modules available via PyPI.
But it has no idea whatsoever about your package manager.
It has no idea about RPM format either, nor about what you already have installed through the system (yum) packages.

So when you invoke pip as root, it will more than likely overwrite Python modules that were installed via system packages.

The result of running pip as root, would be a dirty mix of Python modules installed via yum package management, and pip installed Python modules.

Example of breakage

For the illustration, I’m going to install the certbot package. It is a program for generating free TLS certificates:

sudo yum -y install epel-release
sudo yum install certbot
sudo certbot register # works fine

Now say you have the itch to install the latest and greatest version of a Python app that is not available via yum.
You went to its GitHub project package that wants you to install via pip.
And so you run pip install ... as root. Little did you know that the app required a newer requests Python module.

The installation went through just fine, fetching and installing the newest version of the requests Python library.

Which would be equivalent to (attention, do not run! example only):

sudo pip install -U requests

What now? Your great new app is working fine, but the certbot IS BROKEN with an error message:

ImportError: ‘pyOpenSSL’ module missing required functionality. Try upgrading to v0.14 or newer.

Why that is? Because we’ve brought in a newer version of the requests library that requires newer pyOpenSSL.

We’ve created a mess of the machine by mixing Python modules from pip with Python modules/apps installed via system RPM packages.
You’ll have a hard time restoring things to a working state.

This is an easy example because there is an obvious failure in running certbot now.

But in other cases, you may not even notice the breakage, and things will just work in a weird way.

Remember. What makes CentOS a Community Enterprise OS? It is packaging, of course!

When you install the software in a way that mixes custom installation methods on top of the system one, you’re asking for trouble!

What to do instead

Software that is not available through the system packages (read, RPM) should either be packaged as such, or installed in a directory where it won’t tamper with the system packages function.

Python has a great concept of virtual environments. Essentially you can create a directory that holds all the Python modules for a Python app to run.

It is, however, not an easy concept for some folks. So a simple thing you can do to leverage Python virtualenvs in a user-friendly way is to use pip-safe.

The pip-safe will allow you to install the newest Python apps without damaging your system packages.

Install pip-safe

pip-safe itself is available via system packages, on CentOS/RHEL 7 or 8, and recent Fedora Linux releases.

sudo yum install https://extras.getpagespeed.com/release-latest.rpm
sudo yum install pip-safe

Install a Python app

pip-safe install lastversion

We’ve just installed the lastversion CLI utility from PyPi. Wen can now run it simply as lastversion linux and get the latest Linux kernel version.

How it works, behind the scenes

It installs each program into its own virtualenv at ~/.virtualenvs/<pypi-name>, and symlinks whichever executables it has over to ~/.local/bin/<cli-name>.
Simple and easy! Each program lives in its own virtual environment, so it can have whatever required Python module versions for it.
All without touching your system Python modules.

Install a Python app, for all users

You can also install a Python app from PyPi system-wide, passing in the --system switch:

pip-safe --system install lastversion

How it works, behind the scenes

Similar to user install, a program is installed into a virtualenv of its own.
The only difference is that system-wide Python apps are installed to /opt/pip-safe and their binaries are symlinked to /usr/local/bin/.

Manage Python apps, the safe way

Of course, pip-safe allows also listing and removing installed Python apps.

List installed Python packages/apps

pip-safe list

Remove a Python app

pip-safe remove <name>

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: