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.