How I Got My Rootless Podman Home Assistant to Persist Across Reboots Without a Docker‑Compatible Registry

Persisting a Rootless Podman Home Assistant Without a Registry

Running Home Assistant in a rootless Podman container feels like a no‑frills, privilege‑minimal setup that sits comfortably in a homelab. The real pain point is making sure the image and its data stick around after a reboot when you don’t want to hit a Docker‑compatible registry. The trick is to treat a small part of the local filesystem as a “registry” and let Podman pull from it every time the system boots.

1. Create a local image cache

# Pull the official Home Assistant image once
podman pull ghcr.io/home-assistant/home-assistant:stable

# Export it to a tarball in a dedicated directory
mkdir -p ~/containers/homeassistant
podman save -o ~/containers/homeassistant/homeassistant.tar ghcr.io/home-assistant/home-assistant:stable

That ~/containers/homeassistant folder is now your private “registry.” Keep it on a filesystem that survives reboots—Btrfs subvolume, an encrypted LUKS partition, or even a simple ext4 on a dedicated disk. I usually drop it on a separate LUKS container so the image never ends up in the clear.

2. Tell Podman where to look

Add a tiny snippet to your per‑user config so Podman knows to check the cache before hitting the network:

cat <<EOF > ~/.config/containers/containers.conf
[engine]
image_store = ["$HOME/containers/homeassistant"]
EOF

From now on, a podman pull ghcr.io/home-assistant/home-assistant:stable will first look in that directory, load the tarball, and skip the download. I’ve seen people waste bandwidth on repeated pulls; this stops that.

3. Persist the container state

Home Assistant keeps its config under /config. Mount that into the container and back it up with a systemd unit.

mkdir -p ~/homeassistant/config

Create /etc/systemd/system/homeassistant.service:

[Unit]
Description=Home Assistant (rootless Podman)
After=network-online.target
Wants=network-online.target

[Service]
User=youruser
Environment=HOME=/home/youruser
ExecStartPre=/usr/bin/podman pull ghcr.io/home-assistant/home-assistant:stable
ExecStart=/usr/bin/podman run --rm \
  -v ~/homeassistant/config:/config \
  -v /run/user/1000/podman:/run/podman \
  --name homeassistant \
  ghcr.io/home-assistant/home-assistant:stable
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=multi-user.target

Enable it:

sudo systemctl enable --now homeassistant.service

Because the container runs with --rm, the image is discarded on shutdown, but the local cache keeps it ready for the next boot. That’s the “rootless” magic: no root‑level image store, just a user‑owned tarball.

4. Security considerations

  • User namespaces – Rootless Podman already isolates the container in a user namespace, so the process can’t escape to the host.
  • Filesystem permissions – Make sure ~/homeassistant/config is owned by you and not world‑writable.
  • Network isolation – By default Podman creates a bridge network. If you need tighter control, add --network host or configure a custom CNI plugin.
  • Automatic updates – Keep Home Assistant fresh with a simple cron job that pulls the latest image, stops the service, and restarts it. The cache will be refreshed automatically.
0 3 * * * youruser /usr/bin/podman pull ghcr.io/home-assistant/home-assistant:stable

5. Troubleshooting

Symptom Likely cause Fix
podman: command not found Podman not installed for the user sudo dnf install podman (or your distro’s package)
Container fails to start Missing config volume Verify the mount path and permissions
Image not found locally Cache directory mis‑named Check containers.conf and the tarball path

6. Optional: Use a lightweight registry

If you really want a true registry interface, install podman-registry on the same host and point Podman to it. That adds a tiny HTTP layer but keeps the workflow identical. For most homelab users, the tarball approach is simpler and avoids exposing an HTTP endpoint.



See also