Start root container on boot

Basically everything is in the title,
I’ve a root container created with distrobox for libvirt (I don’t want to layer it) and I need to start it on boot. I’ve looked into Quadlet but it seems to me that it will create a new container every time and not start an already existing one.

How can I do it?

Podman is systemd friendly so you can use a systemd.service file. If you check the podman site https://podman.io/ you will find their documentation is very detailed in spelling out how to.

It appears that the default behavior for Quadlet systemd units is to remove the container after the systemd service has stopped. For example, a simple /etc/containers/systemd/date.container file that contains the following:

[Unit]
Description=A date container

[Container]
Image=registry.fedoraproject.org/fedora:39
ContainerName=date
Exec=date

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

…creates the following date.service unit:

[Unit]
Description=A date container
SourcePath=/etc/containers/systemd/date.container
RequiresMountsFor=%t/containers

[X-Container]
Image=registry.fedoraproject.org/fedora:39
ContainerName=date
Exec=date

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

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
KillMode=mixed
ExecStop=/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
ExecStopPost=-/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
Delegate=yes
Type=notify
NotifyAccess=all
SyslogIdentifier=%N
ExecStart=/usr/bin/podman run --name=date --cidfile=%t/%N.cid --replace --rm --cgroups=split --sdnotify=conmon -d registry.fedoraproject.org/fedora:39 date

Note the ExecStartPost line where the container is removed.

You may want to explore a custom script that checks for the existence of the container you want to start and using the correct command (i.e. podman run or podman start). Then you would run that script as a systemd unit.

1 Like

Any reason why it’s an issue to create a new container every time? Any state files that need to be preserved should be stored in a volume which will persist between containers. I believe that’s best practice.

Wouldn’t starting a new container lose all data contained in the previous one? (Maybe is a stupid question but I’ve just started learning about containers in general)

From a storage perspective, containers have a significant flaw: they are ephemeral. Container images are read-only and consist of different layers that include anything added during the build phase. To allow writing files, a read-write layer is put on top of the container image when you start a container from an image. The problem here is that this read-write layer is lost when the container is stopped or deleted. Just like the memory of your computer gets erased when you shut it down. To persist data, you need to write it to your disk.

If a container needs to persist data on a host, a volume can be used to achieve that. The concept and technology for that is quite simple: instead of isolating the whole filesystem of a process, directories that reside on the host are passed through into the container filesystem. When container volumes are used, you effectively give access to the host filesystem.

1 Like

Ok so using a volume is a way to have persistent storage. But that doesn’t happens by default when you create a container? If you restart it without deleting it you have all software installed into it

A container with a mounted volume can be created using:

podman container run --detach --volume webvol:/webdata myapp:latest

The above command would create on the host system a volume in the Podman working directory and mount it on the container at the /webdata mount point.

A bind mount can be achieved with:

podman container run --detach --volume /mnt/webvol:/webdata myapp:latest

It mounts the host’s /mnt/webvol directory to the /webdata mount point on the container as it is being started.

As @jakfrost suggested for more info you can look podman-volume — Podman documentation, podman-run — Podman documentation and Mounting External Volumes — Podman documentation.

Thank you. Yes I’m reading the documentation but it’s a lot and I’m still wrapping my head around it

If there are no Volumes defined when the container is run, then starting a new container will only contain what is in the Image that it is based on.

Looking back at your original post, I’m guessing that you created a Distrobox container (say Ubuntu) then went inside that container and ran apt install libvirt, etc. And now you have a container that has everything you want in it?

What you should do is create an Image (define a Containerfile/Dockerfile, and feed it into podman build) which will contain the “clean state” that you want - this includes libvirt and any other software you want. See image below.

After that, you can run your custom image, and define just the parts of that filesystem you want to persist (e.g. /var/lib/libvirt/images)and assign them Volumes.

[1]


  1. ↩︎

3 Likes

As I am also studying the subject, I would recommend the LinuxFoundationX: Introduction to Cloud Infrastructure Technologies as part of this 3-Course program. They are free and one of the best sources of information on the topic that I know of.

2 Likes

There’s podman generate systemd but it’s now deprecated which is disappointing because it worked quite well and I learned about it about 3 months ago.

It seems the podman maintainers are moving towards Kubernetes compatible compose files, which is great, I see why, but that’s not a direct replacement.

I just found this by googling but haven’t had a chance to try it: