11 KiB
Home Assistant Upgrade Plan: 2024.5.4 → 2026.5.0 (revised)
Direct jump (no intermediate version stops). Two structural compose changes are folded into this upgrade: bump the image: tag, and swap the healthcheck endpoint to one that doesn't require auth on modern HA.
Current versions
- Core:
2024.5.4 - Frontend:
20240501.1
Target versions (as of May 2026)
- Core:
2026.5.0(released May 6, 2026) - Frontend:
20260325.6(stable) — bundled inside the core image, no separate action needed
Scope
The Home Assistant instance runs as a Docker container defined in docker-compose.yml, pinned to homeassistant/home-assistant:2024.5.4. The config is volume-mounted at /home/padriano/projects/ha/config.
1. Pre-flight checks (read-only)
Before touching anything, gather facts and confirm assumptions:
-
Architecture:
uname -m— confirmx86_64(the official HA image supports it;armhfwas dropped in 2025). -
Custom components / HACS:
ls /home/padriano/projects/ha/config/custom_components 2>/dev/null— currently empty, good. If anything appears, abort and check each integration's HA 2026.5 compatibility first. -
USB device passthrough: confirm no
devices:mapping indocker-compose.yml(none today — no Z-Wave/Zigbee radios at risk). -
Recorder DB size:
du -sh /home/padriano/projects/ha/config/home-assistant_v2.db*— record this. The bigger it is, the longer the first-boot schema migration will take. -
Free disk:
df -h /home/padriano/projects/ha— already 405 GB free, plenty for backup + image pull. -
Current version (auth-free):
docker exec homeassistant python -c "from homeassistant.const import __version__; print(__version__)" # expected: 2024.5.4(The old
curl /api/ | grep versionis unreliable and won't work post-upgrade because/api/requires auth on modern HA.) -
Current container health:
docker inspect --format '{{.State.Health.Status}}' homeassistant # expected: healthy -
Reverse-proxy reachability:
curl -fsS -o /dev/null -w "%{http_code}\n" https://ha-padriano.duckdns.org # record current status code so we can compare post-upgrade
2. Backups
2a. Record image digest and pin a local rollback tag
docker inspect --format '{{.Image}}' homeassistant > /home/padriano/projects/ha/image-digest-2024.5.4.txt
docker tag "$(cat /home/padriano/projects/ha/image-digest-2024.5.4.txt)" homeassistant/home-assistant:2024.5.4-rollback
The local :2024.5.4-rollback tag guarantees the exact previous image stays resolvable even if the upstream :2024.5.4 tag is ever repushed or GC'd.
2b. Create a HA backup from within Home Assistant
Open Home Assistant UI → Settings → System → Backups → Create backup (full backup). This captures integrations state, .storage/, and all config managed by HA. Download the .tar file.
2c. Off-host copy of the HA backup
The backup from 2b lands in /home/padriano/projects/ha/config/backups/ (HA writes it inside /config, same disk). Copy it off to /home/padriano/share/ so we don't only rely on a same-disk copy:
cp /home/padriano/projects/ha/config/backups/*.tar /home/padriano/share/ha-backup-2024.5.4.tar
2d. Filesystem backup of the config directory
Stop the container first to get a consistent SQLite snapshot — otherwise home-assistant_v2.db-wal may be mid-write and the copy may be inconsistent.
docker compose stop homeassistant
cp -a /home/padriano/projects/ha/config /home/padriano/projects/ha/config.bak-2024.5.4
diff -rq /home/padriano/projects/ha/config /home/padriano/projects/ha/config.bak-2024.5.4 && echo "Backup OK" || echo "Backup MISMATCH"
(The container will be restarted in step 5; you can also docker compose up -d homeassistant here briefly if you want HA running while you do step 3.)
3. Review breaking changes
Read the "Backward-incompatible changes" section for each monthly release between 2024.6 and 2026.5:
- https://www.home-assistant.io/changelogs/core-2024.6/
- https://www.home-assistant.io/changelogs/core-2024.7/
- https://www.home-assistant.io/changelogs/core-2024.8/
- https://www.home-assistant.io/changelogs/core-2024.9/
- https://www.home-assistant.io/changelogs/core-2024.10/
- https://www.home-assistant.io/changelogs/core-2024.11/
- https://www.home-assistant.io/changelogs/core-2024.12/
- https://www.home-assistant.io/changelogs/core-2025.1/
- https://www.home-assistant.io/changelogs/core-2025.2/
- https://www.home-assistant.io/changelogs/core-2025.3/
- https://www.home-assistant.io/changelogs/core-2025.4/
- https://www.home-assistant.io/changelogs/core-2025.5/
- https://www.home-assistant.io/changelogs/core-2025.6/
- https://www.home-assistant.io/changelogs/core-2025.7/
- https://www.home-assistant.io/changelogs/core-2025.8/
- https://www.home-assistant.io/changelogs/core-2025.9/
- https://www.home-assistant.io/changelogs/core-2025.10/
- https://www.home-assistant.io/changelogs/core-2025.11/
- https://www.home-assistant.io/changelogs/core-2025.12/
- https://www.home-assistant.io/changelogs/core-2026.1/
- https://www.home-assistant.io/changelogs/core-2026.2/
- https://www.home-assistant.io/changelogs/core-2026.3/
- https://www.home-assistant.io/changelogs/core-2026.4/
- https://www.home-assistant.io/changelogs/core-2026.5/
High-impact themes across this window:
- 2024.6: AlarmDecoder entities renamed with
alarmdecoder_prefix; Ping integrationdisconnected→unavailable. - 2024.7–2024.12: many YAML-only integration configs removed in favor of UI config flow.
- 2025.x: SQLAlchemy / recorder schema bumps (long first-boot migration expected);
legacy_templatesremoval; tightenedhttp:/trusted_proxiesvalidation. - 2026.x: skim release notes the day of upgrade for any last-minute regressions/hotfixes.
Grep /home/padriano/projects/ha/config for any deprecated YAML keys flagged by the changelogs before proceeding.
4. Edit docker-compose.yml
Two changes to the homeassistant service:
homeassistant:
image: homeassistant/home-assistant:2026.5.0 # was 2024.5.4
...
healthcheck:
test: ["CMD", "curl", "-fsSL", "http://localhost:8123/manifest.json"] # was /api/ (now requires auth)
interval: 30s
timeout: 10s
retries: 5
start_period: 30m # was 60s — first-boot recorder schema migration can take a long time
Rationale for start_period: 30m: during start_period, failing health checks don't mark the container unhealthy. The first-boot recorder schema migration can run for many minutes, and a stock 60s start_period would flip the container to unhealthy mid-migration. Note this is cosmetic/observability — plain Docker does not kill or restart an unhealthy-but-running container (restart: unless-stopped only acts on container exit), and nothing here gates on HA's health (caddy's depends_on has no condition: service_healthy). So the only real risk of a too-short start_period is a misleading unhealthy status and noisy monitoring during migration. 30 min gives headroom; revert to a shorter value in a follow-up once we've measured the real first-boot time.
Validate before applying:
cd /home/padriano/projects/composer
docker compose config
5. Pull and start
cd /home/padriano/projects/composer
docker compose pull homeassistant
docker compose up -d homeassistant
pull only fetches the homeassistant image; duckdns, caddy, forgejo, samba, timemachine are untouched (intended).
6. Verify
-
Watch the HA log (where migration detail actually goes —
docker compose logsonly shows stdout):tail -F /home/padriano/projects/ha/config/home-assistant.logLook for
Database upgrade in progress, thenSetup of domain X took …, finallyHome Assistant initialized in …. -
Container health:
docker inspect --format '{{.State.Health.Status}}' homeassistant # wait until: healthy -
Version (auth-free):
docker exec homeassistant python -c "from homeassistant.const import __version__; print(__version__)" # expected: 2026.5.0 -
Local HTTP:
curl -fsS -o /dev/null -w "%{http_code}\n" http://localhost:8123/manifest.json # expected: 200 -
Reverse proxy (validates
trusted_proxiesstill works against modern HAhttp:validation):curl -fsS -o /dev/null -w "%{http_code}\n" https://ha-padriano.duckdns.org # expected: same status code as recorded in step 1 -
UI: open Home Assistant → Settings → Repairs and address any flagged migration items.
7. Rollback
Decide which option by where the upgrade failed. Once 2026.5.0 has booted successfully it migrates the recorder DB schema and .storage/ to the new format, and HA does not support schema downgrade. So whether reverting the image tag alone is safe depends entirely on whether migration started — check the HA log (step 6) for Database upgrade in progress:
- Migration never started (new container crashed/failed early, you never saw that line) → the on-disk config is untouched. Use Option A (revert tag only).
- Migration started or completed (you saw that line, or HA reached the UI) → the DB/
.storage/are now on the new schema. Option A will fail — old core will refuse the newer recorder schema. Use Option B (restore the config backup).
Option A — revert image tag only (safe ONLY if migration never started)
Edit docker-compose.yml:
- set
image:back tohomeassistant/home-assistant:2024.5.4 - revert the healthcheck
testline tohttp://localhost:8123/api/ - revert
start_period: 60s
Then:
cd /home/padriano/projects/composer
docker compose up -d homeassistant
The local homeassistant/home-assistant:2024.5.4-rollback tag from step 2a guarantees the exact previous image is still resolvable even if the upstream tag was repushed.
Option B — restore config backup (default once migration has run)
Revert the image tag and healthcheck per Option A, then restore the pre-upgrade config so the DB/.storage/ schema matches 2024.5.4:
docker compose stop homeassistant
mv /home/padriano/projects/ha/config /home/padriano/projects/ha/config.failed-2026.5.0 # keep the failed state for diagnosis instead of rm -rf
cp -a /home/padriano/projects/ha/config.bak-2024.5.4 /home/padriano/projects/ha/config
docker compose up -d homeassistant
Option C — last resort
Restore the HA .tar backup (from step 2b/2c) via the HA UI recovery mode on a fresh 2024.5.4 container.
8. Post-upgrade follow-up
- Measure the actual first-boot migration time from the HA log and lower
healthcheck.start_periodback to a sensible steady-state value (e.g.2m) in a follow-up commit. - Once stable for a few days, delete
/home/padriano/projects/ha/config.bak-2024.5.4and the local:2024.5.4-rollbackimage tag (docker rmi homeassistant/home-assistant:2024.5.4-rollback) to reclaim disk.