How I got my docker-compose YML to work switching to podman-compose

Dale Bingham
5 min readDec 2, 2022

It took me a bit to get my underlying REL 8.7 VM working. But once I did, I got my docker-compose.yml file to work with podman-compose, persisted volumes, shared volumes, with just 1 specific change only: quotes around single ports listed. Read on to see what else I had to add for podman, podman-compose, directory permissions, utils, and images per user space. I hope it saves you time and frustration!

podman use instead of docker, with podman-compose included

Just replace `docker` with `podman`??

I am experienced enough to know this is closer to marketing than 100% truth. Especially since I use docker-compose with a lot of my applications, including our OpenRMF Professional application if running on a local server/VM/laptop. However, I knew there were benefits and this was probably valid to a point. Also, those customers I have now that are going to REL 8.x want to use this.

So I have been tracking podman since version 3.x and the podman-compose application to help me along. This was difficult for me to get working when I tried it about 8 or so months ago in early 2022. And I just could not focus on it as a priority at the time. And I trusted the community would make it better over time and easier to use. And they did not fail us!

The few steps below are what I did to make my REL 8.7 image have podman, use my docker-compose YML files almost in tact, persist data, and work exactly as they did with docker and docker-compose (or the newer “docker compose”).

Install podman 4.x and podman-compose

First things first, I installed podman in my REL 8.x new VM and ran all the sudo yum update commands to get the latest. What I have as of December 1, 2022, is below.

podman version
Client: Podman Engine
Version: 4.2.0
API Version: 4.2.0
Go Version: go1.18.7
Built: Wed Oct 26 15:23:47 2022
OS/Arch: linux/amd64

Then I ran yum install python3-pip and pip3 install podman-compose to get that installed with the version below.

podman-compose version
['podman', '--version', '']
using podman version: 4.2.0
podman-composer version 1.0.3
podman --version
podman version 4.2.0

EZ PZ right? So now all should work in my YML files I already use under the docker compose -f xxxxxxxx.yml up -d type of commands right?

No. I had to do a few more things.

Managing ports correctly in your YML file

When I first ran a simple YML from my collection to do MySQL and Wordpress with an internal MySQL port only, I immediately received an error trying out podman-compose -f ./wordpress.yml up and it had to do with ports. podman expects single ports in quotes, those running internally but not exposed out to the host.

So any port running just internally to the podman network to allow communication across pods needs to be in quotes. Any that are mapped like 8080:80 are still AOK as-is. So that was the first fix after installing the correct podman and podman-compose executables. An example MongoDB internal-only port is below.

ports:
- "27017"

Ok, that took a little digging (i.e. googling) but no worries. I fixed those in a few YML files and all was good.

So all is working now, right?

Install podman-plugins and dnsmasq

Not really.

I kept getting “could not resolve name” type errors when one pod had to talk to another pod, like Wordpress talking to MySQL or Keycloak talking to Postgres. In “docker compose” terms, one image could not talk to the other image inside the docker network even using the name you gave the container to use. This worked 100% using docker and docker compose. So this was the next frustrating point to me.

If you read here you will see the DNS name resolution inside a podman network does not appear to be there by default. So me naming all my database and messaging containers inside my YML for access did not work out of the gate. Of course, if all containers were run inside the same pod, this worked fine. But jamming a bunch of containers into a single pod for a complicated YML file just did not seem correct.

This frustrated me until I re-read the information a few times and found the dnsmasqthing noted in the link just above. That helps you manage DNS inside a podman network when you create a specific network for your applications.

When I ran yum install podman-plugins it included the dnsmasq for DNS resolution inside the podman network. This was my second fix after installing the 2 executables. So basically I had 4 things to do.

I recommend stopping all podman containers if any are running, removing any podman networks you find withpodman network ls, and then rebooting to get everything refreshed after you do all of this.

All is now working!!

With those fixes and added utilities, I rebooted and tried my application as-is (after the “port” thing) and viola!! It worked great and acted exactly like my docker and docker compose methods did.

All of my start scripts with docker compose -f xxxxxxxx.yml up -d scripts worked great with podman-compose -f xxxxxxxx.yml up -d from then on including making my network and seeing the DNS configuration automatically in my configuration as below.

{
"cniVersion": "0.4.0",
"name": "cni-bridge-network",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
...
}
},
{
"type": "dnsname",
"domainName": "foobar.com",
"capabilities": {
"aliases": true
}
}
]
}

Something else to watch

My only caveat here is I am using Hashicorp Vault in my one project. And it wants the IPC_LOCK set to not swap sensitive memory to disk. To do this, I had to run sudo to make them work. At least for now until I test otherwise.

Doing this I also noticed that the podman images listing was not the same as sudo podman images listing. It saves the images you download per user space, at least the way I set it up by default. So I removed the images I ran as other users with podman rmi xxxxxxxx:1.0.0, and just used the images I needed for the user in question.

I was used to the docker images being the same whether I ran as sudo, user1, user2, etc. but that is not the case necessarily. Keep that in mind as well.

Also, I ran this on a vanilla REL 8.7 VM without any hardcore security profile such as the DISA hardened profile. You may have to find the exact match on security if you are doing SELinux, a hardened or “STIG’d” profile on your server, and need to use named volumes or share out local files to your setup.

Hope this helps you all to have this all in one spot! I had a massive list of notes in VSCode while doing this, and synthesized it down to these steps in my .md file.

And now here!

--

--

Dale Bingham

CEO of Soteria Software. Developer on OpenRMF. Software Geek by trade. Father of three daughters. Husband. Love new tech where it fits. Follow at @soteriasoft