If you have looked for alternatives to Docker, Podman might have attracted your attention.
One thing that Podman does not yet have is the ability to automatically pull appropriate images and start the containers based on a compose file.
There exists a tool called
podman-compose that is an alternative to
docker-compose tool and it works with Podman, as you would expect. So let us see how to use this tool.
What is podman-compose?
Docker provides the functionality to specify all the necessary details like the container name, image used, restart policy, volumes, bind mounts, ports, labels, etc inside a single file. This file is usually called the
This functionality is missing from Podman. Hence we need to use the
podman-compose tool to achieve this functionality.
The podman-compose tool does this by adhering to the Compose specification. This is the same specification that Docker adheres to, making it compatible with an existing
docker-compose.yml file. (There may be some pedantic differences like enclosing values between double quotes (
"), etc but those can be easily solved by looking at the errors.)
Installing the podman-compose tool
Since the podman-compose tool is a relatively new tool, your stable/LTS Linux distribition might not have it in the first party repositories. But nonetheless, let us see what your options are and how to install it.
On Ubuntu 22.10 (Kinetic Kudu) and later and Debian 12 (Bookworm) and later, you can install it using the
apt package manager like so:
sudo apt install podman-compose
Users of Fedora 36 and later (the package version on Fedora 35 is
0.1.7-6.git) can use the
dnf package manager to install podman-compose like so:
sudo dnf install podman-compose
OpenSUSE Tumbleweed or Leap 15 and later can install the podman-compose tool like so:
sudo zypper install podman-compose
If you are a proud Arch Linux user, you do not need my help. But below is the installation command nonetheless ;)
sudo pacman -Syu podman-compose
Verify the installation
To ensure that the podman-compose utility is either installed or its path is included in the
PATH environment variable, you can check it like so:
This should also list your Podman version.
On my Fedora 36 machine, I get the following output:
$ podman-compose --version ['podman', '--version', ''] using podman version: 4.3.1 podman-composer version 1.0.3 podman --version podman version 4.3.1 exit code: 0
Basics of the podman-compose tool
For the sake of keeping this tutorial short, sweet and digestable, I will not cover the structure of a compose file. But fret not! We already have a quick guide to using
For the sake of convenience, below is the compose file that I am using:
version: 3.7 services: reverse-proxy: image: docker.io/library/caddy:alpine container_name: caddy-vishwambhar command: caddy run --config /etc/caddy/Caddyfile restart: always ports: - "8080:80" - "8443:443" volumes: - /docker-volumes/caddy/Caddyfile:/etc/caddy/Caddyfile:Z - /docker-volumes/caddy/site:/srv:Z - /docker-volumes/caddy/caddy_data:/data:Z - /docker-volumes/caddy/caddy_config:/config:Z - /docker-volumes/caddy/ssl:/etc/ssl:Z labels: - io.containers.autoupdate=registry - pratham.container.category=proxy environment: - TZ=Asia/Kolkata depends_on: - gitea-web gitea-web: image: docker.io/gitea/gitea:latest container_name: gitea-govinda restart: always ports: - "8010:3000" - "8011:22" volumes: - /docker-volumes/gitea/web:/data:Z - /docker-volumes/gitea/ssh:/data/git/.ssh:Z - /etc/localtime:/etc/localtime:ro labels: - io.containers.autoupdate=registry - pratham.container.category=gitea environment: - RUN_MODE=prod - DISABLE_SSH=false - START_SSH_SERVER=true - SSH_PORT=22 - SSH_LISTEN_PORT=22 - ROOT_URL=https://git.mydomain.com - DOMAIN=git.mydomain.com - SSH_DOMAIN=git.mydomain.com - GITEA__database__DB_TYPE=postgres - GITEA__database__HOST=gitea-db:5432 - GITEA__database__NAME=gitea - GITEA__database__USER=gitea - GITEA__database__PASSWD=/run/secrets/gitea_database_user_password - GITEA__service__DISABLE_REGISTRATION=true - TZ=Asia/Kolkata depends_on: - gitea-db secrets: - gitea_database_user_password gitea-db: image: docker.io/library/postgres:14-alpine container_name: gitea-chitragupta restart: always volumes: - /docker-volumes/gitea/database:/var/lib/postgresql/data:Z labels: - io.containers.autoupdate=registry - pratham.container.category=gitea environment: - POSTGRES_USER=gitea - POSTGRES_PASSWORD=/run/secrets/gitea_database_user_password - POSTGRES_DB=gitea - TZ=Asia/Kolkata secrets: - gitea_database_user_password secrets: gitea_database_user_password: external: true
Let us now start with the basic commands.
Starting all containers from the compose file
up command, we can create and start the services described in our compose file (
You can simply use the
up command and start all the specified containers/services that are listed in the compose file like so:
podman-compose up -d
Running the above command will perform all the necessary actions needed to start the services/containers listed in the compose file. That includes steps like the folloiwng:
- Pull all the images that are not available locally
- Create the containers with all the specified options (ports, volumes, secrets, networks, etc)
- Start the containers in a specific order (defined by constraints like
If you looked closely at the above example, you might have noticed a new option; the
-d option. This option starts the container in the background, detaching it from the current shell.
Once the containers are up and running, you can verify that by running the
podman ps command:
$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d7b7f91c03aa docker.io/library/caddy:alpine caddy run --confi... 4 hours ago Up 4 hours ago 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp caddy-vishwambhar 1cfcc6efc0d0 docker.io/library/postgres:14-alpine postgres 4 hours ago Up 4 hours ago gitea-chitragupta 531be3df06d0 docker.io/gitea/gitea:latest /bin/s6-svscan /e... 4 hours ago Up 4 hours ago 0.0.0.0:8010->3000/tcp, 0.0.0.0:8011->22/tcp gitea-govinda
Stop all containers from the compose file
To stop all the containers specified in the compose file, use the
Additionally, you can give a timeout so the containers can shut themselves down safely. This is done using either of the following options:
podman-compose down -t TIMEOUT_IN_SECONDS podman-compose down --timeout TIMEOUT_IN_SECONDS
Please note that the
down command only stops the container(s). If you want to delete containers, that will need to be done manually.
Start, stop or specific services
If you are iterating through multiple configurations like ports, volumes, environment variables, etc, you might be using the
podman-compose up and the
podman-compose down command repeatedly.
This will start and stop all services, respectively. Meaning, if you only have one service to start/stop, you now have to wait for all the services listed in a compose file to start and shut down. That's no good!
To solve this, we can use the
stop commands to start or stop individual services. There is even a
restart command. This does exactly what it says :)
Below is a demonstration where I start the
gitea-db service, stop it and then restart it, just for you ;)
$ podman-comopse start gitea-db $ podman-compose stop gitea-db $ podman-compose restart gitea-db
Pull all necessary images at once
Let's say that you specified 10 different services in your compose file. What if waiting once is okay to you, but not when you want to start the contiainers--for whatever reason?
If that is the case, all you have to do is use the
pull command like so:
Running the above command will pull all the images that are specified in the compose file.
Use a different name for your compose file
Now, I do not know why you might do this. There are several reasons for you to do this. Maybe keeping the compose file's name as
docker-comopse.yml triggers you to type
docker instead of
Whatever the reason might be, you can use either of the following flags to specify the name of the comopse file, like so:
podman-compose -f COMPOSE_FILE_NAME podman-compose --file COMPOSE_FILE_NAME
Let's assume my compose file is not named
docker-compose.yml, but is instead named
my-compose-file.yml. To use this compose file, I will run the following command:
podman-compose --file my-compose-file.yml
Running the above command will inform the
podman-compose tool that the compose file is named
my-compose-file.yml instead of
Podman is an amaizng container orchestration tool; and along with the
podman-compose tool, creating multiple containers with your specified details become easier! I recommend that you try out the
podman-compose tool and let us know about your experience.