You rebooted and the container is gone
You configured a database container for your local stack. You mapped the ports, mounted the data volume, and verified the service works. You rebooted the laptop to apply a kernel update. When the desktop returned, the container was missing. Your application crashed because the backend is down. You have to manually run the container again. This happens every time you restart. You need the container to survive reboots and start automatically without manual intervention.
What systemd and Podman are doing
Fedora uses systemd to manage the lifecycle of all services. When you type podman run in a terminal, the container process lives inside your shell session. If the shell closes or the system reboots, the process dies. systemd runs in the background and starts services when the system reaches a specific target. You need to tell systemd about your container so it can manage the lifecycle.
Podman provides a bridge between container commands and systemd units. The bridge is the podman generate systemd command. It inspects a running container and creates a unit file that systemd understands. The unit file contains the exact command to start the container, the restart policy, and the dependencies. Once the unit file exists, systemd can start the container at boot, restart it on failure, and stop it cleanly on shutdown.
The generated unit lives in your user directory by default. This ties the container to your user session. You do not need root privileges to manage user-level units. This is the standard pattern for development containers and personal services.
Reboot before you trust the unit. A successful start in the terminal does not guarantee a successful start from systemd.
Generate and enable the unit file
Start with a running container. The generate command needs a live container to inspect. If the container is stopped, start it first with podman start <name>.
Here is how to generate the unit file and save it to the correct directory.
# Generate the systemd unit file for the running container.
# --new tells Podman to create a unit that starts the container if it is stopped.
# Without --new, the unit only restarts an existing container, which fails on a fresh boot.
# --name targets the specific container instance you want to manage.
# Output goes to the user systemd directory so you do not need root privileges.
# The file extension .container signals to systemd that this is a Podman-managed unit.
podman generate systemd --new --name my-web-app > ~/.config/systemd/user/my-web-app.container
The command writes the unit file to ~/.config/systemd/user/. This directory is the standard location for user-level systemd units. The file contains ExecStartPre commands to create the container if it does not exist, followed by ExecStart to run it.
systemd caches the list of unit files in memory. Adding a new file requires a reload so the manager sees the change.
# systemd caches the list of unit files in memory.
# Adding a new file requires a reload so the manager sees the change.
# --user targets the user instance of systemd, not the system-wide daemon.
# This command is safe to run multiple times and has no side effects if nothing changed.
systemctl --user daemon-reload
Enable the unit to register it for automatic start. This creates a symlink in the systemd wants directory.
# Enable creates a symlink in the systemd wants directory.
# This registers the unit to start when the user session begins.
# The .container suffix matches the file extension generated by Podman.
# Enable does not start the unit immediately. It only configures boot behavior.
systemctl --user enable my-web-app.container
Start the unit immediately to test the configuration. This simulates what happens at boot without waiting for a restart.
# Start the unit immediately to test the configuration.
# This simulates what happens at boot without waiting for a restart.
# If the container is already running, systemd checks the state and skips the start.
# This command is idempotent and safe to run repeatedly.
systemctl --user start my-web-app.container
Run systemctl --user status my-web-app.container to check the state. You should see active (running). If you see failed, check the logs. Use journalctl -xeu my-web-app.container to see the error. The x flag adds explanation, and e jumps to the end. This is faster than scrolling through raw logs.
Check the journal before you guess. systemd logs the exact reason for failure.
Verify persistence and handle logout
Reboot the machine. Log in. Run podman ps. The container should be listed. If it is, the unit is working. You can also check systemctl --user list-units --type=service | grep my-web-app to see the unit state.
There is a common trap with user-level units. When you log out of the desktop, the user systemd instance stops. This kills all user services, including your container. If the container must survive logout, you need to enable linger.
Linger keeps the user systemd instance alive after the last session ends. The container continues running even when no user is logged in.
# Enable linger for your user account.
# This keeps the user systemd instance running after logout.
# Containers managed by user units will persist across logouts.
# This command requires your user password and modifies PAM configuration.
loginctl enable-linger
Verify linger is active with loginctl show-user <username> | grep Linger. The output should show Linger=yes.
Enable linger if the container must survive logout. User sessions end, services should not.
Common pitfalls and error patterns
The --new flag is the most frequent source of confusion. If you omit --new, the generated unit expects the container to already exist. On a fresh boot, the container does not exist. systemd tries to start the unit, Podman finds no container, and the unit fails. The error looks like Error: no container with name or ID "my-web-app" found. Always use --new for auto-start scenarios.
User-level units run with your user permissions. If the container needs to bind to a port below 1024, it will fail. Ports below 1024 require root privileges. Use ports above 1024 for user containers, or switch to a system-level unit. System-level units require root and placing files in /etc/systemd/system/.
Volume paths must be absolute and stable. If your container mounts a volume from a path that changes between reboots, systemd might fail to start the container. Ensure volume paths are fixed. Relative paths in podman run are resolved at runtime, but the generated unit file captures the resolved path. If the source directory moves, the unit breaks.
Podman generates the unit based on the current state of the container. If you modify the container configuration after generating the unit, the unit file becomes stale. Regenerate the unit file after any significant change to the container. Run podman generate systemd --new --name <name> > ~/.config/systemd/user/<name>.container and reload systemd.
Trust the package manager. Manual file edits drift, snapshots stay. Regenerate the unit when the container changes.
When to use this approach
Use podman generate systemd when you have a running container and need a quick unit file without writing YAML or TOML.
Use Podman Quadlet when you want declarative configuration that survives container recreation and matches the upstream Kubernetes style.
Use system-level units when the container must run independently of any user login session and serve external clients.
Use --new in the generate command when you want the container to start from scratch on boot.
Stay on user-level units when the container supports your personal workflow and does not require root privileges.