Rootless Podman Container Drops Its Persistent Volume After a Reboot: A Quick Fix for My HomeLab 🚀

Running containers without root is a lifesaver, but I hit a snag the other night. I had a small database container that wrote data to a named volume, and the next time I rebooted my machine the data was gone. Turns out the volume directory was being created under a transient mount that didn’t survive shutdown.

Why the Volume Vanishes

In rootless mode Podman keeps everything under ~/.local/share/containers/storage. When you do podman volume create, it records the mount point in a JSON file there. On reboot the user‑session systemd instance that owns the rootless runtime comes back up, but systemd doesn’t automatically remount the user‑created volumes unless you tell it to. The result? The container starts, and the volume looks like a fresh empty directory.

The Quick Fix: A Systemd User Unit

The cleanest way to make the volume stick is to let systemd mount it before the container starts. Podman can generate a unit for you, and you just add an ExecStartPre that mounts the volume. Here’s how I did it:

# 1. Create the volume (if you haven’t already)
podman volume create --name dbdata

# 2. Generate a systemd unit for the container
podman generate systemd --name mydb --files
# This creates mydb.service in the current directory

# 3. Edit the unit to mount the volume before the container runs
sed -i '/^ExecStart=/i ExecStartPre=/usr/bin/mount -t tmpfs -o rw,mode=1777 tmpfs $HOME/.local/share/containers/storage/volumes/dbdata/_data' mydb.service

# 4. Move the unit to the user systemd directory
mkdir -p ~/.config/systemd/user
mv mydb.service ~/.config/systemd/user/

# 5. Reload systemd, enable, and start
systemctl --user daemon-reload
systemctl --user enable --now mydb.service

That ExecStartPre line mounts a tmpfs into the volume’s data directory, guaranteeing the mount point exists every boot. If you want a persistent disk instead of RAM, swap the tmpfs line for a bind mount to a directory under /home/<user>/data:

ExecStartPre=/usr/bin/mount --bind /home/<user>/data/dbdata $HOME/.local/share/containers/storage/volumes/dbdata/_data

Security Considerations

Because the container runs as your UID/GID, the volume mount is owned by you, so no privilege escalation here. Still, if you bind‑mount a directory that holds sensitive data, double‑check the permissions (chmod 700). Adding --userns=keep-id to the podman run command—or to the unit file—keeps the UID mapping consistent across reboots.

Quick Checklist

Step Command Note
Create volume podman volume create dbdata Persist data across containers
Generate unit podman generate systemd --name mydb --files Produces a systemd service
Mount pre‑start ExecStartPre=... Guarantees volume mount
Enable unit systemctl --user enable --now mydb.service Auto‑start on login

With this setup the volume survives reboots, and the container boots up cleanly every time. If you’re using a different storage backend (e.g., Btrfs subvolumes), just tweak the mount options accordingly.

Happy homelabbing!


See also