Loading...
E.G.

Backing Up Home Assistant: the Config Folder Isn't Enough

August 7, 2026
Table of Contents

What my backups were missing

Most Home Assistant backup advice comes down to archiving your config folder, and that's what I did for a long time — on a schedule, with a copy offsite.

At some point I sat down and worked through what would actually happen if the VM died, and the list of things I wouldn't have was longer than I expected. The automations would come back. But the WireGuard setup that lets my phone reach Home Assistant from outside the LAN wasn't in the archive, and neither were the firewall rules. Nor was the cron job that creates the backups in the first place. And I'd long since stopped remembering the exact docker run command that produces a container with the right network mode and the right volume mounts.

So the config archive would have got Home Assistant running again, on a host that couldn't do much.

What goes into the archive

The daily job now packs the following, and each one is there for a reason I ran into:

The database and the YAML files — home-assistant_v2.db, all .yaml files, and the split automations directory.

.storage/ — this is where the dashboards live. Changes made in the Lovelace UI don't end up in your YAML, so without this directory you get a working instance with empty dashboards.

custom_components/ — everything installed via HACS. Without it, a good share of your entities come back as unavailable and you spend an evening working out which integration is missing.

The VPN configuration and its keys — WireGuard in my case. Regenerating keys means reconfiguring every client device by hand, so they're worth keeping.

The firewall rules — a restored host that's reachable and unprotected isn't much of a restore.

The cron directory, including the backup script itself — if the machine that runs your backups is gone, it's useful if the script that makes them isn't gone too.

The docker inspect output as JSON — this one I rarely see mentioned. It records the image, network mode, volumes, restart policy and environment of the running container, which means you can read the right docker run off a file instead of trying to remember it.

Where the copies live

Two destinations: seven daily archives locally on the VM, and a blob storage container offsite that mirrors them.

Measured against 3-2-1 — three copies, two media, one offsite — that passes on a count. It's weaker than the count makes it look, though, because the local copy sits on the same disk as the data it's backing up. If that disk fails, the local archive goes with it and the offsite mirror is the only thing left.

I keep the local copy anyway, because it makes the common case quick. Almost every restore I've actually needed was "I broke a YAML file this morning" rather than a lost machine. The offsite copy is the one that matters for the rare case, so that's the one I check.

No credentials in the backup script

The upload runs under the VM's own managed identity. The cloud provider hands the machine a short-lived token, the storage container grants that identity write access, and the script itself contains no key and no connection string.

That's worth a bit of care in a backup script specifically, because of what it does: it has read access to everything on the host and it regularly talks to somewhere off-site. A long-lived storage key sitting in that file would be a fairly direct route out.

If your host has no managed identity available, a scoped write-only credential with a short expiry does the same job. The account key doesn't.

Restoring it once

I hadn't ever done a full restore, which meant I didn't really know whether the archive was complete. So I ran it on a fresh VM with a stopwatch.

Two steps only showed up by doing it. The machine identity has to be granted again on the new host, and the network security rules have to be attached to the new interface. Neither lives in any backup archive, and both stop the restore until you notice. The script changed after that run.

The whole walkthrough with the timings is its own post. This one is about what needs to be in the archive before that's even worth attempting.

Two related things, in case they're useful. Taking a backup before an update is a different job on a different rhythm, and I wrote that up separately along with how the container rollback works in practice. And all of this runs on Home Assistant in Docker on a cloud VM, which is set up step by step in an earlier post.

Summary

Archive the host rather than just the folder: the VPN keys, the firewall rules, the cron directory, the backup script and the container definition, alongside the config and database. Keep a local copy for speed and an offsite one for the case the local copy won't survive. Then run a restore once while nothing is actually broken.

Related articles