CentOS 8 Stream: Systemd Integration with Podman Containers
0 reputation · 26 Aug 2022, 09:28 UTC
0 reputation · 26 Aug 2022, 09:28 UTC
To have a Podman container automatically start, stop, and restart on boot using a systemd unit file generated by podman generate systemd on CentOS 8 Stream.
The generated unit must include proper ExecStart and ExecStop directives, and optional resilience settings like Restart=always. The container may require additional systemd options (e.g., CapabilityBoundingSet) if privileged. Conflicts can arise if podman system service is also running.
podman generate systemd output correctly configures the unit to restart the container after a reboot?systemd and podman system service are enabled, how can I prevent resource conflicts and ensure only one orchestration mechanism controls the container?34775 reputation · 26 Aug 2022, 10:38 UTC
First, verify that the unit file generated by podman generate systemd will restart the container after a reboot. Then add security‑focused systemd directives for privileged containers, and finally avoid conflicts with the podman system service socket.
myapp with your container name or ID):
podman generate systemd --new --name myapp > /etc/systemd/system/myapp.service
# /etc/systemd/system/myapp.service
[Unit]
Description=myapp container
After=network-online.target
Wants=network-online.target
[Service]
Restart=always
ExecStart=/usr/bin/podman start -a myapp
ExecStop=/usr/bin/podman stop -t 10 myapp
KillMode=none
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now myapp.service
systemctl stop myapp.service # simulates container stop
systemctl start myapp.service # should start the container again
podman ps -a | grep myapp
systemctl status myapp.service
systemctl reboot in a test VM, then verify systemctl is-active myapp.service returns active.If the container requires extra capabilities (e.g., --privileged or specific --cap-add flags), limit the attack surface with systemd sandboxing options. Add these to the [Service] section of the unit:
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_NET_RAW – retain only the capabilities the container truly needs.AmbientCapabilities= – clear any inherited ambient capabilities.PrivateDevices=yes – block access to host device nodes.ProtectSystem=full – make /usr, /boot, /etc read‑only.ProtectHome=read-only – prevent writes to home directories.NoNewPrivileges=yes – stop the container from gaining new privileges via setuid binaries.PrivateTmp=yes, ProtectKernelTunables=yes, ProtectKernelModules=yes, RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX – further kernel‑level hardening.Example snippet:
[Service]
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_NET_RAW
AmbientCapabilities=
PrivateDevices=yes
ProtectSystem=full
ProtectHome=read-only
NoNewPrivileges=yes
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
...
podman system serviceThe podman.socket unit provides an API socket that podman system service consumes. If you rely on custom ExecStart=/usr/bin/podman start lines, the socket is unnecessary and can cause double‑management.
systemctl status podman.socket
systemctl disable --now podman.socket
systemctl mask podman.socket
ExecStart=/usr/bin/podman run that contacts the socket). The --new flag to podman generate systemd creates a unit that talks directly to podman binaries, avoiding the socket.podman ps -a # shows container state
systemctl list-units --type=service | grep myapp
Both should agree; if the container appears twice or shows conflicting states, re‑examine whether both the socket unit and your custom unit are trying to start/stop it.To give a definitive recommendation about lingering permissions, please confirm whether you are using rootful or rootless podman. Rootless operation requires loginctl enable-linger $USER for the unit to start after a user logout.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 26 Aug 2022, 20:00 UTC
The unit file produced by podman generate systemd behaves differently depending on whether you include the --new flag. Without --new, the generated service starts an existing container via podman start; with --new, it creates the container on first start using podman run. Importantly, neither variant automatically adds a Restart= directive. To ensure the container is restarted after a reboot or failure, you must either add --restart-policy=always (or on-failure) when generating the unit, which inserts Restart=always into the [Service] section, or manually edit the file to include that directive. Verifying the presence of Restart=always after generation (e.g., grep Restart= /etc/systemd/system/myapp.service) confirms that systemd will restart the container as intended.