How to use docker-compose with Podman in Linux
Podman is a free and open source alternative to Docker developed by Red Hat. While Docker is widely known and has become synonymous with containerization, Podman implements a number of technical advantages that make it a worthy competitor. Unlike Docker, which requires a daemon to manage containers, Podman was originally designed as a daemonless solution. It doesn't need a constant background process to run, making it more secure and flexible in a Linux environment. In addition, Podman supports running containers without the need for root access, which greatly increases system security.Another important aspect of Podman is its deep integration with Linux-based operating systems. But one of the reasons why many users are slow to migrate from Docker to Podman is the lack of a full analog for docker-compose, a tool that is used to manage multi-container applications.
To solve this problem, the Podman developers have thought of a compatibility layer that allows docker-compose to be used as a native Podman tool. Users can now run docker-compose commands from Podman as if it were Docker.
Installing packages
To ensure compatibility between Docker and Podman - you need to install the podman-docker package. It plays a key role by creating a command line interface similar to Docker, but executing Podman commands in the background.On Fedora distributions and other Red Hat-based systems, install the package using the following command:
dnf install podman podman-docker
For users of Debian and distributions based on it (Ubuntu), the installation is done with the command:apt install podman podman-docker
Selecting and configuring the version
There are two main versions of docker-compose:- The first v1 is the original one, written in Python, which is now considered deprecated.
- The second v2 - written in Go, is actively developed and presented as a Docker plugin in the official repositories.
Installing docker-compose v1
Most modern Linux distributions provide the ability to install docker-compose through standard repositories that include a Python version. For example, to install docker-compose in Fedora, you need to run the following command:dnf install docker-compose
If you are using RHEL or its clones (CentOS) - docker-compose is not available in the repositories by default. Also, it cannot be installed from the EPEL repository. In this situation you need to use pip, the Python package manager.Since using pip as root is not recommended, especially in productive environments, we can install docker-compose v1 in an isolated virtual environment acting as the default user. We then create a symbolic link to the executable so that it can be run from the command line. Alternatively, pipx can be used.
The example below assumes that the `~/.local/bin` directory already exists and has been added to the PATH:
python3 -m venv virtualenv
virtualenv/bin/pip install docker-compose
ln -s "${PWD}/virtualenv/bin/docker-compose" ~/.local/bin/docker-compose
In Debian-based distributions, the installation process of docker-compose v1 is much simpler and does not require the creation of a virtual environment. You can install it with the following command:apt install docker-compose
Installing docker-compose v2
The second version, docker-compose v2, is the officially supported version. There are several options available for installing it.Installation by loading a pre-compiled binary file
In the example, we download the latest version (2.27) for the Linux x86_64 architecture:curl -LO https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64
Once the file is downloaded, it should be made executable and then moved to the directory that is in the PATH. If you want to install it only for the current user - the file can be moved to `~/.local/bin`. For a system-wide installation, it can be sent to `/usr/local/bin`:chmod +x docker-compose-linux-x86_64
mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
Installation via official Docker repositories
Another way to install docker-compose v2 is to use the official Docker repositories. To do this, first add the Docker repository to your system, then install the docker-compose-plugin package:dnf install docker-compose-plugin
This method involves using docker-compose as a Docker containerization plugin rather than a separate binary. To use it as a separate application, you can create a symbolic link in the directory that is in the PATH:ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose
Enabling and starting Podman socket
One of the key differences between Podman and Docker is the architectural approach.Docker uses a client-server model: the daemon runs in the background and requires root access (although recent versions of Docker have the ability to work with containers at the user level without root access).
Podman uses a “fork-exec” approach, where each container runs as a separate Podman child process.
Since docker-compose was originally designed to work with Docker, it expects the Docker daemon to be running. To overcome this restriction Podman provides a system module called “podman.socket”. To run it on systemd-enabled systems, just run the following command:
systemctl enable --now podman.socket
If you plan to use Podman without root access - you will need to enable and start a socket instance at the user level:systemctl --user enable --now podman.socket
After that, you need to configure the DOCKER_HOST environment variable to tell docker-compose to use the Podman socket instead of the standard Docker socket. Add the following line to a shell configuration file such as ~/.bash_profile or ~/.profile:export DOCKER_HOST=unix:///run/user/1000/docker.sockFor the changes to take effect immediately - apply the settings in the current shell session:
source ~/.bash_profile
System socket and Podman service - what is it?
Besides the previously activated socket /usr/lib/systemd/system/podman.socket, the Podman package also includes the systemd service module (/usr/lib/systemd/system/system/podman.service). What role does this service play and why do we activate the socket and not the service itself?To understand what systemd does when Podman starts, let's look inside the module. We are interested in the ExecStart parameter in the Service section:
ExecStart=/usr/bin/podman $LOGGING system service
The line shows that when systemd runs the “podman system service” command, it creates a service that responds to Podman-related API requests. In this way, Podman, although it does not require a daemon, can emulate the Docker interface by responding to requests via the API.But why do we prefer to use the socket module instead of starting the service directly? It's because of the way systemd works when activating services via sockets. The socket is configured to listen for incoming connections and start the corresponding service only when needed. This allows you to use system resources sparingly: the service does not run in the background all the time, but only starts when it is invoked.
Thus, by activating the Podman socket module, we not only ensure compatibility with docker-compose, but also optimize the use of system resources, allowing Podman to run as efficiently as possible.
Conclusion
Originally docker-compose was designed to interoperate with Docker, which uses a client-server architecture different from the Podman model. But by activating the Podman socket and installing the podman-docker package, we create a compatibility layer that allows docker-compose to be used with Podman as easily and transparently as it is with Docker, greatly enhancing the container management capabilities of the system.26 Aug 2024, 19:59:55