easy_install/pip or apt-get

As noted in the Ubuntu wiki page on Rails it is recommended that gems manages your Rails/Ruby dependencies.

What is the best practise with Python packages like Django? Should I install them through apt-get or should I let easy_install/pip fetch them from PyPi?


Solution 1:

There are several arguments:

  1. Use Repositories/PPAs because they will keep you both stable and up to date with security fixes.

    This is mostly true. If, for example, you install python-django as I have, you get security updates. This is good because you only have to keep on top of apt but you still have to test things before you push updates (although testing should be fine each time).

    You could argue that if you used pip, you might never check for updates.

  2. Use pip so you can use the proper "stable" versions.

    There's no doubt about it: The repos lag behind the real world. Django is 2.0 but the repos for the LTS version of Ubuntu (that a lot of people stick with for servers) you only get 1.8 on Ubuntu 16.4 lts with Python 2 but still get security updates on it.

    pip gives you the latest all the time. You just have to update them yourself.

  3. Upgrading a repo-used Python install can be a nightmare

    When you dist-upgrade Ubuntu to the next version, it upgrades a lot of packages. Lots of things change. I know in Django this means you have to take care to watch out for code-incompatibilities, deprecations... But the same applies to all other Python code.

    The same is true for pip but with pip you get to do one thing at a time. You know what causes the problems so you know where to look to find the fix.

  4. pip+virtualenv lets you keep things separate

    virtualenv lets you have portable, little Python environments. This allows you to have several different Python environments running alongside each other on the same machine.

    The obvious boon seems to be for maintenance as you can manage the environment in the same way as you manage the code. Even store the environment in the VCS too... but you should remember that having twelve different virtualenvs means twelve environments you need to check on and update.


Edit: After a horrible series of upgrades on a server to get it from Lucid to Precise, I've switched from a mixed Apt+pip (nr 1 and 2) to a pure pip+virtualenv (nr. 4) situation. Instead of having one virtualenv per site, I've got one shared one between a dozen-or-so sites. This is working for now.

I've also had to write a little script that checks the status of packages installed with pip. If there are updates I have to apply them manually (which is good because I test them locally, in a local virtualenv). This is all still a little more painful than it was originally but much better in the long run.

Solution 2:

  • Packages from the repositories

    These should be installed whenever your application is in some way specific to Ubuntu. They guarantee you a stable version that you can install across Ubuntu machines, they are supported and sometimes more mature than the one's you get via pip. If you deploy a bunch of ubuntu servers, or if you're writing an Ubuntu applications, use these, if available.

    They also sometimes contain Ubuntu-specific modifications.

  • pip vs easy_install

    Theres not much to say about those, as Django hacker James Bennett put it:

    Please, for the love of Guido, stop using setuptools and easy_install, and use distutils and pip instead.

    For an in-depth discussion on the differences, see On packaging by James Bennett (of django) and A Few Corrections To “On Packaging” by Ian Bicking (of mozilla).

If you want to be safe, try out your pip deployments using virtualenv. This gives you an isolated python environment, so you can be sure that your app will run on any machine.

Wait a bit though, I trust some people will disagree with me.