How to Start a Container on Boot with Podman and Systemd

Use Linux’s service manager to start your containers at boot time and keep them running

Podman is the super handy tool for running containers on Linux. Whatever you’re using containers for, you can handle it with Podman. But did you know that Podman also has a really cool feature to help you manage your container apps with Systemd (the system and service manager for Linux)?

When you run your containers as units in Systemd, you can treat them just like any other service.

This means that you can control containers using systemctl start and stop commands. And it also lets you ensure that the containers are started whenever your server reboots.

This is mega-handy for containers which you want to run, and ensure that they keep running.

So how do you set it up? Let’s take a look.

Start a container on boot with Podman and Systemd

Start the container

Let’s start with a container. I’m going to use MongoDB as an example, because a database is the kind of service which you might want to keep running all the time, and restart it if it crashes.

By the way, this tutorial assumes that you’ve got SELinux enabled (which you should do!)

Let’s first create a directory, so that MongoDB can store its data:

mkdir /var/lib/mongo

(Your application might not need storage, but I’m including this step here, so that you can see how to run containers which store persistent data.)

Next, we’ll start a container from the official MongoDB image.

We also tell the container where it should store its data. In this case, we mount a volume which points to /var/lib/mongo:

podman run --rm --detach \
    --name toms-mongo \
    --volume /var/lib/mongo:/data/db:Z \
    docker.io/library/mongo

Did you notice the :Z label? It tells adds a security label to the directory, so that SELinux will allow the container user to write to it.

Now the container should be running. We can check this by running podman ps, which shows us all of the running containers:

$ podman ps
CONTAINER ID  IMAGE                    COMMAND  CREATED        STATUS            PORTS   NAMES
d3c69e928bf8  docker.io/library/mongo  mongod   4 seconds ago  Up 4 seconds ago          toms-mongo

This all seems good so far!

So how do we make sure that this MongoDB container restarts automatically, whenever the server reboots? To do that, we add it to systemd.

Add the container to systemd

Next, we want to create a systemd service for the container.

Systemd is a service management tool that’s constantly working in the background for you. It takes care of the programs that you want to run in the background on a Linux server.

About Podman’s systemd feature

Podman includes a command called podman generate systemd, which outputs a valid systemd configuration file (called a unit) for the container.

When you run podman generate systemd... it will produce something like this:

$ podman generate systemd --new --name toms-mongo 
# container-toms-mongo.service
# autogenerated by Podman 3.0.0-dev
# Mon Mar  8 17:59:37 UTC 2021

[Unit]
Description=Podman container-toms-mongo.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/container-toms-mongo.pid %t/container-toms-mongo.ctr-id
ExecStart=/usr/bin/podman run --conmon-pidfile %t/container-toms-mongo.pid --cidfile %t/container-toms-mongo.ctr-id --cgroups=no-conmon --replace --rm --name toms-mongo -v /var/lib/mongo:/data/db:Z --detach docker.io/library/mongo
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/container-toms-mongo.ctr-id -t 10
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/container-toms-mongo.ctr-id
PIDFile=%t/container-toms-mongo.pid
Type=forking

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

To register a unit with systemd, this file needs to go in /etc/systemd/system/.

Generate the unit file

So let’s run the podman generate systemd command, give it the name of our MongoDB container, and redirect the output from this command to a file in the /etc/systemd/system directory. This generates the unit file, and writes it, all in one command:

podman generate systemd \
    --new --name toms-mongo \
    > /etc/systemd/system/toms-mongo.service

This should have created a file. Let’s check:

$ ls -al /etc/systemd/system/toms-mongo.service
-rw-r--r--. 1 root root 918 Mar  8 18:16 /etc/systemd/system/toms-mongo.service

We can also use the command systemctl list-unit-files. This will show all the unit files that systemd is aware of:

$ systemctl list-unit-files | grep tom
proc-sys-fs-binfmt_misc.automount                                static         
toms-mongo.service                                               disabled       

Enable and start the service

The final step is to enable the service, and start it:

systemctl enable toms-mongo
systemctl start toms-mongo

Enabling the service ensures that it will start on the next boot. Starting the service starts it immediately.

And now our container should be running as a system service, with Podman and Systemd!

We can check, using systemctl status toms-mongo:

$ systemctl status toms-mongo
● toms-mongo.service - Podman container-toms-mongo.service
  Loaded: loaded (/etc/systemd/system/toms-mongo.service; enabled; vendor preset: disabled)
  Active: active (running) since Mon 2021-03-08 18:16:32 UTC; 3s ago
    Docs: man:podman-generate-systemd(1)
 Process: 17683 ExecStart=/usr/bin/podman run --conmon-pidfile /run/container-toms-mongo.pid --cidfile /run/container-toms-mongo.ctr-id --cgr>
 Process: 17681 ExecStartPre=/bin/rm -f /run/container-toms-mongo.pid /run/container-toms-mongo.ctr-id (code=exited, status=0/SUCCESS)
Main PID: 17817 (conmon)
   Tasks: 2 (limit: 11401)
   Memory: 1.8M
   CGroup: /system.slice/toms-mongo.service
           └─17817 /usr/bin/conmon --api-version 1 -c 79bf80ca6176aa84d5d577d01f9fed17bea7e042b81ed11373a726fa27e11b76 -u 79bf80ca6176aa84d5d5>

Mar 08 18:16:31 li1513-130.members.linode.com systemd[1]: Starting Podman container-toms-mongo.service...
Mar 08 18:16:31 li1513-130.members.linode.com podman[17683]: d3c69e928bf8c1c5b469c7a931eb0cd023712834cceb024fa2e56346cb766dd7
Mar 08 18:16:32 li1513-130.members.linode.com podman[17683]: 79bf80ca6176aa84d5d577d01f9fed17bea7e042b81ed11373a726fa27e11b76
Mar 08 18:16:32 li1513-130.members.linode.com systemd[1]: Started Podman container-toms-mongo.service.

Yaaasssssss.

Will it survive a reboot of the server?

Here’s…. the Moment of Truth.

Let’s see if systemd will restart the container, when the server gets rebooted.

Let’s reboot nooowww……..

shutdown -r now

And a few minutes later, I log in again…. (Look at all those pesky h4ck3rs trying to get into my box)

Last failed login: Mon Mar  8 18:20:01 UTC 2021 from 149.19.6.147 on ssh:notty
There were 17 failed login attempts since the last successful login.
Last login: Mon Mar  8 18:09:53 2021 from 51.4.51.52

Is the container running again? Let’s check it with podman ps:

# podman ps
CONTAINER ID  IMAGE                    COMMAND  CREATED             STATUS                 PORTS   NAMES
ff31eeddf640  docker.io/library/mongo  mongod   About a minute ago  Up About a minute ago          toms-mongo

That’s a yes! Woohoo!

And now you know how to use Podman and Systemd to run and manage containers on your Linux server.

Now it’s over to you. Enjoy working with containers!

Try creating and running containers with systemd on your own Linux server. If you don’t have a server to play with, then you can sign up with Linode today, and get some free cloud credits to get you started.