Solving conflicting dependencies in Linux/Unix

This is a comment I made on Reddit regarding a post about flatpak and thought an expanded version might make a good post here.

Problem

You want to run a program and the program depends on multiple programs. If two programs depend on different versions of another program, there is a conflict.

Solutions

There are different levels of solutions to this problem and each solution has its own advantages and disadvantages. We have to choose the solution that best suits our use case.

1. You do everything.

You install the program (usually compile as well). You install every dependency. You update the program and its dependencies manually. When the two programs depend two versions of another program, you resolve that conflict by installing two versions and pointing right programs to right versions. Most common scenario where you will do this is when you are running a low level distribution such as Gentoo or compile your own Linux distribution from scratch.

2. Package management

You install a package manager, you install the program through package manager. The PM takes care of installing and updating dependencies and resolving conflicts. By doing this, you are delegating most of the heavy lifting to a package manager and only keep the ability to making hard decisions for yourself. In the event of hard conflicts, you usually have to pick a version of a dependency to keep and pick software to update. This usually results in running slightly outdated software but is very very convenient and has almost no extra overhead. Most common scenario is when you are running a standard, established linux distribution such as Arch Linux, Fedora, Debian, RHEL etc.

3. Portable deployment

You install flatpack/snap (portable deployment manager) and install a deployment of the program inside it. The deployment has all the dependencies inside it i.e. every flatpak/snap has its own version of the dependency. Sometimes these deployments even run in a sandbox. This ensures that there are no conflicts but the whole thing eats loads of disk space. It also compromises some security since you have to trust each flatpack/snap to update dependencies so that your system is secure. If one of the flatpack/snap messes up, it can cause problems to your system. This is common in user friendly distributions of Linux such as Ubuntu, elementaryOS, PopOS etc.

4. Containerisation

You install a container engine (docker) and you install and run every program inside a separate container along with its dependencies. Ideally you have a repository of images of containers running different versions of software and use them in combination with others. This is similar to running small virtual computers inside your operating system. This results in even less conflicts and is also very secure since if your program misbehaves it does not takes down the entire operating system (just the container). The downsides are that making programs talk to each other requires more effort and running these programs takes more ram and processing power a.k.a overheads. Most common scenario is where you have a server and you want to run multiple small programs in it (micro services), you can run different versions, start and stop multiple instances depending on demand etc.

5. Virtualisation

You install a hypervisor (VMware/VirtualBox), create multiple virtual machines and install one program in each virtual machine. This is similar to the container engine but the difference is that the virtualisation happens at the hardware level and each program can run on different versions of Operating systems. There is literally 0 conflicts and the programs are super secure as they are almost as if running in different computers. They cannot mess with the host operating system and the setup is super secure. But the overheads are very large (as we are emulating hardware) and it takes a long time to switch them on and off. This sort of solution is used in large scale hardware deployment such as server farms where the main concern is security and redundancy.

6. Hardware Isolation

You just get multiple computers and install one program per computer. It is very very secure and there is no chance of any conflicts (even in the future). Though this set up sounds ridiculous, there are cases where this makes sense. For example, Journalists under hostile regimes can use one tailsOS stick for each aspect of their lives (personal, research, posting articles etc) so that they don’t get exposed. Amazon in early days used to have seperate hardware to store consumer credit cards and have a person walk between them with disks to validate purchases to make things secure. As you can see, this is very very inconvenient but gives the best possible security you can get.

Leave a Reply