sysadmin · July 22, 2026 · 15 min read

Containers at boot.
systemd units, linger, and pods.

Yesterday’s containers vanished after a reboot. Wrap them as systemd user units so they auto-start even when nobody is logged in, and build a three-container pod for the API stack.

// what we’re getting into
  1. The ticket
  2. Concept review. Linger, units, and pods.
  3. Enable linger and recreate the containers
  4. Generate and enable systemd units
  5. Build the api-stack pod
  6. Systemd units for the pod
  7. The reboot test
  8. Exam questions
  9. Final checklist: confirm everything works

cuser2 rebooted the box and the containers from yesterday simply did not come back. That is not a bug, it is the default: rootless containers are tied to the user’s session and go away with it. cuser2 needs them starting at boot whether or not anyone is logged in, and while we are in there, the API stack, app plus redis plus postgres, wired together as a single podman pod so it can be managed as one thing.

Two facts explain both the disappearance and the fix. A rootless user’s services die at logout unless enable-linger keeps their manager running, and a generated systemd unit that points at a container by ID breaks the instant you recreate that container. enable-linger plus the —new flag, which makes the unit rebuild the container from its spec, are the whole answer.

The ticket

bash
id cuser2
sudo loginctl enable-linger cuser2
sudo -iu cuser2
podman --version

Concept review. Linger, units, and pods.

bash
man podman-generate-systemd
man podman-pod
man loginctl

By default systemd stops a user’s services at logout, so a rootless container dies with them. enable-linger keeps the user’s manager running independently, so units start at boot and survive logout. A pod is a group of containers that share a network namespace, like a Kubernetes pod, reachable from each other over localhost, with a single set of port mappings defined on the pod.

podman generate systemd flags
--new                 unit recreates the container from its spec at start
--name NAME           generate for one container or pod
--files               write .service files instead of stdout
--restart-policy=always   restart on failure

Enable linger and recreate the containers

bash
sudo loginctl enable-linger cuser2
loginctl show-user cuser2 | grep -i linger    # Linger=yes
mkdir -p ~/.config/systemd/user ~/webcontent ~/redis-data
echo "<h1>cuser2 web</h1>" > ~/webcontent/index.html

podman run -d --name dev-web -p 8081:80 \
    -v ~/webcontent:/usr/share/nginx/html:ro,Z nginx:latest
podman run -d --name dev-cache -p 6380:6379 \
    -v ~/redis-data:/data:Z redis:latest

Generate and enable systemd units

Generate a portable unit for each container, then, and this is the step people miss, stop and remove the manually started container before enabling the unit, or systemd hits a name conflict trying to start its own copy.

bash
cd ~/.config/systemd/user
podman generate systemd --new --name dev-web --files --restart-policy=always
podman generate systemd --new --name dev-cache --files --restart-policy=always

podman stop dev-web dev-cache
podman rm dev-web dev-cache

systemctl --user daemon-reload
systemctl --user enable --now container-dev-web.service
systemctl --user enable --now container-dev-cache.service
podman ps

Build the api-stack pod

Create the pod with its port mappings, then add each container with —pod. The containers reach each other over localhost inside the pod.

bash
podman pod create --name api-stack -p 8082:8080 -p 5433:5432
mkdir -p ~/postgres-data

podman run -d --pod api-stack --name api-db \
    -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=apiuser -e POSTGRES_DB=apidb \
    -v ~/postgres-data:/var/lib/postgresql/data:Z postgres:latest
podman run -d --pod api-stack --name api-redis redis:latest
podman run -d --pod api-stack --name api-app \
    -v ~/webcontent:/usr/share/nginx/html:ro,Z nginx:latest

podman pod ps
podman ps --pod

Systemd units for the pod

Generating from the pod name writes a unit for the pod and one for each container, and the pod unit pulls in the container units. Stop the manual pod first, then enable.

bash
cd ~/.config/systemd/user
podman generate systemd --new --name api-stack --files --restart-policy=always
ls pod-* container-api-*

podman pod stop api-stack
podman pod rm api-stack

systemctl --user daemon-reload
systemctl --user enable --now pod-api-stack.service
podman pod ps; podman ps

The reboot test

The real proof. Reboot, and because linger is on, everything should come back without anyone logging in.

bash
exit
sudo systemctl reboot

# after reboot, without logging in as cuser2:
sudo -iu cuser2 podman ps    # all five containers up
systemctl --user status pod-api-stack.service

Exam questions

Write the command first.

Q1. Display all systemd user services for the current user.

Q2. Generate a systemd unit for an existing container webserver that recreates it at start, saved to the user’s config directory.

Q3. Configure a rootless container mycache to start at boot and survive logout. Show every step.

Answers.

bash
# A1
systemctl --user list-units --type=service | grep container-
# A2
cd ~/.config/systemd/user
podman generate systemd --new --name webserver --files --restart-policy=always
systemctl --user daemon-reload
# A3 (order matters)
sudo loginctl enable-linger $(whoami)
podman run -d --name mycache redis:latest
podman generate systemd --new --name mycache --files
podman stop mycache && podman rm mycache
systemctl --user daemon-reload
systemctl --user enable --now container-mycache.service

Final checklist: confirm everything works

If every check passes, the ticket is done.

bash
# 1. cuser2 linger enabled
loginctl show-user cuser2 | grep -i linger

# 2. dev-web and dev-cache as enabled user units
systemctl --user list-units --type=service | grep container-dev

# 3. api-stack pod has app, db, redis and auto-starts
podman pod ps

# 4. after a reboot all five containers return without login
# 5. all three exam commands written from scratch
# 6. tracker entry checked off

Reply to cuser2: boot persistence solved. dev-web and dev-cache are systemd user units, the api-stack pod runs app, db, and redis as one managed unit, and the reboot test passed. Everything returns without an active login thanks to enable-linger.

next post
Stratis pools, filesystems, and snapshots