How to Run Podman and Docker-Compose on Windows

Written by raffaeleflorio | Published 2022/06/02
Tech Story Tags: linux | linode | linux-writing-contest | podman | docker-compose | docker | container | windows | web-monetization

TLDROne of the most common tool to develop software is container. This guide helps you to configure correctly podman and docker-compose on Windows using WLS2. Coarse-grained steps are: 1. Install WSL2 2. Install OpenSUSE Tumbleweed 3. Install podman, docker-compose and the ensnare plugin 4. Configure podman to be used in WSL2via the TL;DR App

As you know containers are a Linux thing. Microsoft introduced its solution but I’ve never seen them used.

To use containers we have mainly two alternatives: docker and podman. I prefer the latter for two reasons. Because it has a daemonless architecture and because it doesn’t need root permission. But using it with docker-compose on Windows is tough. That’s why I decided to write and share this story.

Motivation

I think using Docker Desktop on Windows is the fastest way to use containers. It configures everything by itself. But, excluding the architectural preference, I found two other motivations to avoid it:

  1. License issue. Docker Desktop requires a per-user license for commercial use in large companies.
  2. You don’t need it. For example, I’ve never used its GUI. Probably because I’m so accustomed to using it on Linux from cli.

Prerequisites

Using podman on Windows is feasible thanks WSL2. Microsoft provides instructions according your Windows version. You can find them here: https://docs.microsoft.com/en-us/windows/wsl/install.

Podman supports docker-compose from version 3.0.0.

TL;DR

The below paragraphs are about the issues I found on Debian and Ubuntu. So, why we need OpenSUSE Tumbleweed as Linux distribution. For this reason, I summarised in the Conclusion paragraph only the needed steps.

Linux distributions

On the Microsoft Store there are multiple Linux distributions. And that’s where started my journey.

Common solutions about distributions are in the Troubleshooting section

Debian

The current stable distribution of Debian is version 11. It’s codenamed bullseye and it’s the first one I tried to use.

The first thing to check is if podman is in the official repository. Fortunately it is and it’s currently at the version 3.0.1. So, it should work with docker-compose.

So, I updated the system and I installed podman and docker-compose:

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install podman docker-compose

Then I configured podman to avoid using systemd. On WSL2 we cannot rely on it because the init system is a custom Microsoft solution.

To do this I copied /usr/share/containers/containers.conf to $HOME/.config/containers. Then I changed the latter. Specifically, I set cgroup_manager to cgroupfs and events_logger to file :

...
[engine]
...
cgroup_manager = "cgroupfs"
...
events_logger = "file"
...

I found this tips on https://www.redhat.com/sysadmin/podman-windows-wsl2.

Then I tried to run a simple container:

$ docker run -dp 8080:80 docker.io/httpd

But I got: Error: Error initialising source docker … x509: certificate signed by unkown authority. To resolve this issue I installed ca-certificates. Then I tried to run the container again:

$ sudo apt install ca-certificates
$ docker-run -dp 8080:80 docker.io/httpd

This time it worked! And the host can reach the container.

So, I tried a simple docker-compose to test the communication between two containers:

version: "3.7"

services:
  db:
    image: docker.io/mariadb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password

  phpmyadmin:
    image: docker.io/phpmyadmin
    restart: always
    ports:
      - 8080:80
    environment:
      - PMA_ARBITRARY=1

But I got this error:

$ docker-compose up
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?

If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

Obviously it’s not running. So, I checked the podman documentation and we need to start the podman socket manually. We should do it manually because we cannot rely on a systemd service. Then we should indicated the socket location to docker-compose.

$ podman system service --time=0 unix:///home/user/podman.sock &
[1] <a number>
$ docker-compose -H unix:///home/user/podman.sock up
Pulling images...
Creating images...
ERROR: for <service name> network connect is not enabled for rootless containers
ERROR: for <service name> network connect is not enabled for rootless containers

I searched the error and I found a GitHub issue about podman. It seems this is a bug fixed in the version 3.2.

So, I searched other supported Linux distributions in the hope to find a newer podman version.

Ubuntu

Currently there are three Ubuntu versions:

  • 18.04.5 LTS
  • 20.04.4 LTS
  • 22.04 LTS

But, as Debian, they doesn't support latest Podman version. For this reason, I didn’t try them at all. And at this moment I was a bit unmotivated. I would have appreciated a rolling distribution. And that’s when I see OpenSUSE Tumbleweed in the Microsoft Store…

OpenSUSE Tumbleweed

OpenSUSE Tumbleweed is a rolling distribution. This means it supports the latest versions of packages. Indeed, the current podman version is the 4.0.3. Another good news is that I used Tumbleweed for some years, and it was great!

So, I updated the system and installed podman and docker-compose:

$ sudo zypper update
$ sudo zypper install podman docker-compose

At this point I configured podman to not use systemd, as Debian.

I tried to run a simple container exposing a port. And it worked.

So, I started the podman socket. Then I launched docker-compose with the same file. And the two containers started!

But, when I tried to connect to the database from phpmyadmin I received the following error:

getaddrinfo failed: Name or service not known

I investigated a bit and I found that containers were unable to communicate through DNS name.

For this reason I researched about networking in Podman 4.x and I found that they changed the network stack. But it should also supports DNS resolution.

Yet, podman continues to support the old network stack (i.e. cni) for compatibility reason. So, I checked what’s the enabled stack and it was the old one. So, I research about it and DNS resolution and I found an official article. The old stack supports plugins and one of them regards DNS name resolution: dnsname.

So, I searched it on the Tumbleweed repository and it was there. So, I installed it:

$ sudo zypper install cni-plugin-dnsname

And this time the containers communicated correctly.

Furthermore, I forced the old stack in podman adding to $HOME/.config/containers/containers.conf:

...
[network]
network_backedn = "cni"
...

Troubleshooting

Unable to resolve DNS in WSL2

On each distribution I was unable to resolve domain names. For example, I got errors like:

  • Temporary failure resolving ‘<a domain name>’
  • W: Failed to fetch <a URL>
  • Error message: Could not resolve host: <a host name>'

So, I read the /etc/resolv.conf file and there was a bad DNS server. Fortunately Microsoft added a hint:

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false

nameserver <BAD_NAMESERVER>

So, I wrote the /etc/wsl.conf file:

[network]
generateResolvConf = false

Then, I removed the /etc/resolv.conf file (it was a link) and I created the correct one:

nameserver <GOOD_NAMESERVER_IP>

Conclusion

As you can see running podman with docker-compose on Window was a journey. We covered a lot of steps. So, to simplify and have them better organised I wrote again here:

  1. Install WSL2
  2. Install OpenSUSE Tumbleweed as Linux distribution
  3. Correct /etc/resolv.conf, if unable to resolve DNS name in the distribution
  4. Update the distribution
  5. Install podman, docker-compose and cni-plugin-dnsname
  6. Configure podman to not use systemd
  7. Configure podman to use the cni as network backend
  8. Launch podman socket
  9. Profit

At this point, you can customize your experience to simplify your workflow. For example command aliases or adding commands at boot.


Written by raffaeleflorio | 🪐 Abstractions explorer in love with OOP | 🧭 Software Architect | ☕ Java Developer
Published by HackerNoon on 2022/06/02