search icon

How to convert any docker-compose.yml to quadlets with Podlet

· 5 min read
Self Hosting
A blue container on the left, a purple container on the right. Original photo by Aron Yigin on Unsplash

If you like the idea of using quadlets to manage your application containers, but everyone and their grandma only provide “compose.yml” files, you can often use Podlet to convert them to quadlets.

First, install Podlet. If you are using Arch Linux, you can just run:

yay -S podlet

Converting a docker run command

Let’s convert the docker run command for DDclient:

docker run -d \
  --name=ddclient \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Etc/UTC \
  -v /path/to/ddclient/config:/config \
  --restart unless-stopped \
  lscr.io/linuxserver/ddclient:latest

We copy the code from run and replace docker with podlet podman:

podlet podman run -d \
  --name=ddclient \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Etc/UTC \
  -v /path/to/ddclient/config:/config \
  --restart unless-stopped \
  lscr.io/linuxserver/ddclient:latest

After pressing enter, it will generate a basic quadlet file:

# ddclient.container  
[Container]  
ContainerName=ddclient  
Environment=PUID=1000 PGID=1000 TZ=Etc/UTC  
Image=lscr.io/linuxserver/ddclient:latest  
Volume=/path/to/ddclient/config:/config  
  
[Service]  
Restart=always

We can now copy the output into “$HOME/.config/containers/systemd/ddclient.container”

Converting a docker-compose.yml file

Podlet is especially useful with more complex compose files.

Let’s convert Ghost’s compose file, as it needs a MySQL container for production setup:

docker-compose.yml
version: '3.1'
 
services:
 
  ghost:
    image: ghost:5-alpine
    restart: always
    ports:
      - 8080:2368
    environment:
      # see https://ghost.org/docs/config/#configuration-options
      database__client: mysql
      database__connection__host: db
      database__connection__user: root
      database__connection__password: example
      database__connection__database: ghost
      # this url value is just an example, and is likely wrong for your environment!
      url: http://localhost:8080
      # contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
      #NODE_ENV: development
    volumes:
      - ghost:/var/lib/ghost/content
 
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - db:/var/lib/mysql
 
volumes:
  ghost:
  db:

Here we can see that:

  • No name: authentik has been specified
  • The application is made of a server and a database
  • Two volumes are created for the server and database persistent storage, but we can also use normal folders through bind mount.

Since no name: ghost has been specified yet, we need to add it at the top level:

docker-compose.yml
name: ghost
 
version: '3.1'
 
services:
 
# ...

Now, we can convert the compose file using Podlet:

podlet compose --pod

The output will be:

# ghost-ghost.container  
[Container]  
Environment=database__client=mysql database__connection__host=db database__connection__user=root database__connection__password=example datab  
ase__connection__database=ghost url=http://localhost:8080  
Image=ghost:5-alpine  
Pod=ghost.pod  
Volume=ghost:/var/lib/ghost/content  
  
[Service]  
Restart=always  
  
---  
  
# ghost-db.container  
[Container]  
Environment=MYSQL_ROOT_PASSWORD=example  
Image=mysql:8.0  
Pod=ghost.pod  
Volume=db:/var/lib/mysql  
  
[Service]  
Restart=always  
  
---  
  
# ghost.pod  
[Pod]  
PublishPort=8080:2368

In this case, remember to split the output into multiple quadlets:

$HOME/.config/containers/systemd/ghost-server.container
$HOME/.config/containers/systemd/ghost-mysql.container
$HOME/.config/containers/systemd/ghost.pod

Adapt the content of these files to your needs. Feel free to use this post as a reference.

Converting compose files with variables

Podlet cannot deal directly with certain compose features, such as variables:

Error:    
  0: error converting compose file  
  1: error reading compose file  
  2: File `docker-compose.yml` is not a valid compose file  
  3: services.server.image: invalid image tag: image tag contains invalid character '/', tags must only contain ASCII letters (a-z, A-Z), di  
gits (0-9), dots (.), underscores (_), and dashes (-) at line 34 column 12  
  
Location:  
  src/cli/compose.rs:203

In these cases, we have to normalize the docker-compose file before processing it with podlet. Podman-compose is a small utility that can help with normalization:

yay -S podman-compose

Let’s normalize Authentik’s compose file, which cannot be handled by Podlet directly:

wget https://goauthentik.io/docker-compose.yml
cat docker-compose.yml

Here we can see that:

  • No name: authentik has been specified
  • The application is made of a server and a worker, and needs a Redis and a PostgreSQL containers to work.
  • The PG_PASS variable must be defined, otherwise the “database password required” error appears. Other variables have a default value, so we don’t have to specify another one.

We can normalize the compose file by running:

PG_PASS=XXXXXX podman-compose --file docker-compose.yml config | tee docker-compose-normalized.yml

Now all variables have been assigned a value, but we are still missing our pod name. We can add it by running

echo "name: authentik" >> docker-compose-normalized.yml

The compose file is finally ready to be converted through Podlet:

podlet compose --pod docker-compose-normalized.yml

You can now paste parts of the output in different quadlets, and adapt them to your needs.

Happy conversion!

Did you enjoy the article?

heart icon

If you have suggestions or opinions, just drop me a message, I'd love to hear from you!

Other posts for you

An airplane cockpit showing gauge and radar indicators
Two seals photographed on grey rocks. Photo by Neil Cooper on Unsplash