Garbage Collector


The little space of a writer, tinkerer, and a coffee addict

How to start a Podman Container at system startup

How to start a Podman Container at system startup
The Podman logo, license MIT

In my article about containers, I had a few lines regarding Podman. In fact, I use this container tool since more than a year after discovering it on Fedora while searching for installing Docker on it (because, you know, habits).

I’ll maybe write something about Podman one day, but if you wonder why I heavily prefer it instead of Docker, here is a few reasons :

Anyway, let’s go back to the main topic : how to startup a Podman container at system boot ?

In fact, I’ve already answered to this question in my article How to automatically maintain a Linux Server. But let’s get a little more verbose. To resolve this issue, I’ll use systemd to startup the Container as a service.

How systemd services works

I won’t go in the details because systemd is a big software stack (and I won’t go into its controversies, that’s not the topic). Has you may know, systemd has replaced the former SysV init daemon on various Linux distros. The init service is the first started daemon that’s bring up everything else at startup, and will be the last to die when the system shutdown itself.

Unless the former init system, systemd relies on descriptive service files to specify how the daemon should start, stop and its behavior in case of failure or success. Systemd calls these services “Units”.

These service files can be located at various place :

The services file are INI configuration files, here is for example Apache HTTPD service file on Rocky Linux 8 :

[Unit]
Description=The Apache HTTP Server
Wants=httpd-init.service
After=network.target remote-fs.target nss-lookup.target httpd-init.service
Documentation=man:httpd.service(8)

[Service]
Type=notify
Environment=LANG=C

ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
# Send SIGWINCH for graceful stop
KillSignal=SIGWINCH
KillMode=mixed
PrivateTmp=true

[Install]
WantedBy=multi-user.target

You manage these service with systemctl commands :

You can query the logs with the command journalctl.

As systemd load these files in memory, when you modify their content you’ll need to reload the daemon. If you forget about it, it’ll complain anyway.

Warning: The unit file, source configuration file or drop-ins of freshrss.service changed on disk. Run ‘systemctl daemon-reload’ to reload units.

Create a service file for a Container

podman is able to generate systemd services files for a container. By executing the following command on a started container :

$ podman generate systemd --new --name mycontainer

This will return a ready to use service file. You can use by writing it directly into a file :

$ podman generate systemd --new --name mycontainer >> /etc/systemd/system/mycontainer.service

With that, you can start your container at boot with systemctl enable mycontainer.service

Let’s do an example, I’ve run the Fedora image on a container.

$ podman run --rm -it fedora:latest /bin/bash
$ podman container ls
CONTAINER ID  IMAGE                                     COMMAND     CREATED        STATUS            PORTS       NAMES
3d32ed3f2391  registry.fedoraproject.org/fedora:latest  /bin/bash   6 seconds ago  Up 6 seconds ago              confident_liskov

By using the podman generate systemd command I have a service file as a result :

podman generate systemd --new --name 3d32ed3f2391
# container-confident_liskov.service
# autogenerated by Podman 3.4.2
# Wed Jan 12 11:13:31 CET 2022

[Unit]
Description=Podman container-confident_liskov.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d -it fedora:latest /bin/bash
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target default.target

I’ve pasted the content to a dummy service file.

sudo vi /etc/systemd/system/test.service

Then, started this container that’s won’t do anything else to stop itself.

$ systemctl start test
## hanging a little then, nothing
## let's check in the journal
$ sudo journalctl -u test
-- Journal begins at Sun 2020-08-23 08:49:32 CEST, ends at Wed 2022-01-12 11:16:56 CET. --
janv. 12 11:16:36 vidar systemd[1]: /etc/systemd/system/test.service:1: Assignment outside of section. Ignoring.
janv. 12 11:16:39 vidar systemd[1]: /etc/systemd/system/test.service:1: Assignment outside of section. Ignoring.
janv. 12 11:16:39 vidar systemd[1]: Starting Podman container-confident_liskov.service...
janv. 12 11:16:39 vidar podman[826000]: 2022-01-12 11:16:39.806749097 +0100 CET m=+0.311249421 system refresh
janv. 12 11:16:39 vidar podman[826000]: time="2022-01-12T11:16:39+01:00" level=warning msg="The input device is not a TTY. The --tty and --interactive flags might not work properly"
janv. 12 11:16:39 vidar podman[826000]: Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
janv. 12 11:16:39 vidar podman[826000]: Trying to pull registry.fedoraproject.org/fedora:latest...
janv. 12 11:16:41 vidar podman[826000]: Getting image source signatures
janv. 12 11:16:41 vidar podman[826000]: Copying blob sha256:4545346f2a492b62d5a82682efe19b0e8e7583d5c19f75a74c81d62ec536c32d
janv. 12 11:16:41 vidar podman[826000]: Copying blob sha256:4545346f2a492b62d5a82682efe19b0e8e7583d5c19f75a74c81d62ec536c32d
janv. 12 11:16:44 vidar podman[826000]: Copying config sha256:3059bef432ebb91a6a51d8f5cf20b033041dbddb3cab79628c1eb3412cbde0ae
janv. 12 11:16:44 vidar podman[826000]: Writing manifest to image destination
janv. 12 11:16:44 vidar podman[826000]: Storing signatures
janv. 12 11:16:45 vidar podman[826000]: 2022-01-12 11:16:45.024115071 +0100 CET m=+5.528615355 container create be6d44eedd9658b49d9b32e1a1ce4f7682ecd7b97b5c0af5391489893eccaed4 (image=registry.fedoraproject.org/f>
janv. 12 11:16:45 vidar podman[826000]: 2022-01-12 11:16:39.807474988 +0100 CET m=+0.311975282 image pull  fedora:latest
janv. 12 11:16:45 vidar podman[826000]: 2022-01-12 11:16:45.623079986 +0100 CET m=+6.127580260 container init be6d44eedd9658b49d9b32e1a1ce4f7682ecd7b97b5c0af5391489893eccaed4 (image=registry.fedoraproject.org/fed>
janv. 12 11:16:45 vidar systemd[1]: Started Podman container-confident_liskov.service.
janv. 12 11:16:45 vidar podman[826000]: 2022-01-12 11:16:45.632440572 +0100 CET m=+6.136940846 container start be6d44eedd9658b49d9b32e1a1ce4f7682ecd7b97b5c0af5391489893eccaed4 (image=registry.fedoraproject.org/fe>
janv. 12 11:16:45 vidar podman[826000]: be6d44eedd9658b49d9b32e1a1ce4f7682ecd7b97b5c0af5391489893eccaed4

Yep, the service file did its job !

As I’ve put the --rm argument in the command, the container won’t show itself when running podman container ls -a.

Create a service file for a Container Compose

If you use podman-compose, the previous method won’t work with it because the containers are removed when stopping the deployment. So the service file will try to start non existing containers and fail.

However, the following service file can start a podman-compose service and is usually working for me :

[Unit]
Description=MyContainer
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/podman-compose -f /path/to/docker-compose.yml up -d
ExecStop=/usr/bin/podman-compose -f /path/to/docker-compose.yml down

[Install]
WantedBy=multi-user.target

In the same way, just enable the service with systemd.

Just like any other service, you can check it running with the status command.

Enjoy !


📑 Table of Contents

📚 Read my latest book

Follow me on Mastodon

🏷️ All Tags 📄 All Posts 🗺 Sitemap RSS Feed