Upgrades¶
What this is¶
How to move a running compose install to a newer git tag or main, pull the published image, and let Alembic migrate the database.
Why a checklist¶
Upgrades change code and schema. A self-backup + unchanged master key is the difference between a smooth pull and an unrecoverable encrypted store.
Prefer tags
Prefer tagged production releases (v1.6.0 / later 1.6.x). Treat untagged main as moving. See Home · RELEASE_v1.6.0.md.
# Config DR first
# Settings → PiHerder backup → run now
# Also snapshot Postgres volume if you can
git fetch --tags
git checkout v1.6.0 # or later 1.6.x
docker compose pull
docker compose up -d
# Alembic runs on web startup
# optional pin: PIHERDER_IMAGE=bjorngluck/piherder:1.6.0 docker compose up -d
Checklist¶
- Self-backup successful (admin — Settings → PiHerder backup)
-
PIHERDER_MASTER_KEYunchanged and backed up offline - Read RELEASE notes for the version you jump to
-
docker compose pshealthy (imagebjorngluck/piherder:…) - Smoke: login, Users recovery (if multi-user), one server, maps/ports, optional template
- Hard-refresh browser once after UI/CSS deploys (query-busted stylesheets)
1.1 → 1.2¶
Jump from v1.1.x to v1.2.0. Full notes: RELEASE_v1.2.0.md.
- Take a 1.1 self-backup (config pack) and keep it offline with
PIHERDER_MASTER_KEY. - Read the release notes. Pre-1.2 “full” archives are not a Postgres dump.
- Confirm
.envhas a long randomSECRET_KEY. The 1.2 web process will not boot on the compose default (change-me-in-prod) unless you setPIHERDER_ALLOW_INSECURE=true(lab only). git fetch --tags && git checkout v1.2.0(or pull the1.2.0image).docker compose pull && docker compose up -d— Alembic runs on web start (includes039_ssh_hostkey_pin).- Immediately run Settings → PiHerder backup → Full DR once and copy the archive off-box. Set the schedule to Full.
- Test connection once per host — first success pins the SSH host key. Later key changes are refused until you reset the pin under SSH access (rebuilds). Existing
ssh_usernamevalues are not rewritten (new hosts default topi). - Hard-refresh the browser (compiled Tailwind CSS; no Play CDN).
- New / changed env (Compose has defaults):
PIHERDER_SSH_CONSOLE— web SSH, default offPIHERDER_CSP— default on; nounsafe-eval(compiled CSS)PIHERDER_TRUSTED_PROXY_CIDRS— Compose trusts RFC1918 + loopback so Caddy can pass visitor IPsPIHERDER_ALLOW_INSECURE— leave false on a real fleet- Web port is
127.0.0.1:8000only (not published on the LAN) - Set
PIHERDER_PUBLIC_URLif you use email password reset or SSO (reset links and OIDC redirects are built from it only). - Smoke: login, one host, one job, optional console (if you enabled it).
SSO / passkeys / demo mode are new optional surfaces — they do not turn on by themselves.
1.2 → 1.3¶
Jump from v1.2.x to v1.3.0. Full notes: RELEASE_v1.3.0.md.
Settings policy is JSON in appsetting. Alembic 040_ssh_identities (fleet + optional privileged SSH keys per host). Alembic 041_console_transcripts (opt-in encrypted command audit; default off).
- Self-backup first (Full DR). Keep
PIHERDER_MASTER_KEY. git fetch --tags && git checkout v1.3.0(or pullbjorngluck/piherder:1.3.0).docker compose pull && docker compose up -d— Alembic runs on web start.- Compose change: bundled compose no longer injects defaulted
PIHERDER_SSH_CONSOLE_*knobs (idle, max, bind, …). Only the master enablePIHERDER_SSH_CONSOLEstays in compose. Timeouts live in Settings → Console. 2FA / grant live in Settings → Security. - If you previously relied on those vars in
.envand compose interpolation, they will not reach the container until you add that one line to composeenvironment(env then locks the knob). Otherwise Settings apply. - Smoke: Settings → Security (password / 2FA) · Settings → Console (including who may open privileged) · one host SSH access (fleet identity still there; optional privileged card) · optional live shell if the flag is on.
- Alembic
040_ssh_identitiescopies each host’s existing username + key into a fleet identity.Server.ssh_usernameis unchanged. Jobs keep using fleet. - Alembic
041_console_transcriptsis empty until you turn on Settings → Console → Command audit. Default remains off. - Host Files is off until you set
PIHERDER_HOST_FILES=trueand restart web. Transfer cap is Settings → Files (default 512 MiB, ceiling 32 GiB) unless you lockPIHERDER_HOST_FILES_MAX_BYTES. Host Files. - Reports is on at
/reports(no flag) — Reports. - Immediately run Settings → PiHerder backup → Full DR once and copy the archive off-box. Hard-refresh the browser.
1.3 → 1.4¶
Jump from v1.3.x to v1.4.0. Notes: RELEASE_v1.4.0.md.
Alembic 042_compose_project_meta (per-project host lock). Move a service stays off until PIHERDER_SERVICE_MIGRATE=true and you recreate web.
- Self-backup first (Full DR). Keep
PIHERDER_MASTER_KEY. - After tag:
git fetch --tags && git checkout v1.4.0(or pullbjorngluck/piherder:1.4.0). docker compose pull && docker compose up -d— Alembic runs on web start.- Optional: enable Move, recreate web, walk Move a service on a disposable stack.
- Smoke: lock a hardware-bound project · 1.3 Settings / Reports / Files / console.
- Immediately run Full DR again. Hard-refresh the browser.
1.4 → 1.5¶
Jump from v1.4.x to v1.5.0. Notes: RELEASE_v1.5.0.md.
No new Alembic. Rebuild web and celery-worker. Move stays off until PIHERDER_SERVICE_MIGRATE=true and you recreate web.
- Self-backup first (Full DR). Keep
PIHERDER_MASTER_KEY. - After tag:
git fetch --tags && git checkout v1.5.0(or pullbjorngluck/piherder:1.5.0). docker compose pull && docker compose up -d— recreate web and celery-worker.- Optional: enable Move, recreate web, walk Move a service on a disposable stack (recycle web mid-copy is now safe).
- Smoke: Reports pin/hide · 1.4 Settings / Files / console.
-
Immediately run Full DR again. Hard-refresh the browser.
-
Move runs on celery-worker. Recycle web mid-copy is safe. Recycle worker fails a running Move (staging kept).
- Reports pin / hide / reorder + Move jobs card — Reports. Cookie
ph_reports_layout.
1.5 → 1.6¶
Jump from v1.5.x to v1.6.0. Notes: RELEASE_v1.6.0.md.
Alembic 043, 044, and 045 run on web start. Recreate web and celery-worker. Move stays off. Home Assistant is a separate HACS repo, not this image.
- Self-backup first (Full DR). Keep
PIHERDER_MASTER_KEY. - After tag:
git fetch --tags && git checkout v1.6.0(or pullbjorngluck/piherder:1.6.0). docker compose pull && docker compose up -d— recreate web and celery-worker.- Confirm
alembic_versionincludes045_host_resources. Open System Info and use the refresh icon once per host you want on the HA card. - Optional: HACS piherder-ha 0.2.4 with a read token. Home Assistant.
1.6 → 1.7¶
v1.7.0 is tagged. Notes: RELEASE_v1.7.0.md. Recreate web and celery-worker, confirm Alembic 046, and update HACS to plugin 0.3.0. Move stays off. The next jump is 1.7 → 1.8.
1.7 → 1.8¶
v1.8.0 is tagged. Notes: RELEASE_v1.8.0.md. The patch on that line is v1.8.1. Pins 1.8.1 / 1.8 and 1.8.0 stay valid. Pins 1.7.0 / 1.7 stay valid. The next jump is 1.8 → 1.9.
v1.8.1 refreshes PyJWT to 2.15.1 and urllib3 to 2.8.0. No new migration. Recreate web and celery-worker. About should say 1.8.1.
Alembic 047 runs on web start. Recreate web and celery-worker. HACS plugin 0.4.4 with resource ?v=0.4.4. The MCP adapter stays 0.2.0 and does not start the one-service jobs. Move stays off. Google Drive copy is Settings → PiHerder backup. The public demo is the 1.7.0 image. 6. Optional: PIHERDER_SSH_CONSOLE=true, recreate web, tick Console mux only on a Debian host that already has tmux or screen. 7. Move stays off until PIHERDER_SERVICE_MIGRATE=true and you recreate web. Public demo stays Report-Only CSP. Do not set PIHERDER_CSP_ENFORCE there. 8. Immediately run Full DR again. Hard-refresh the browser.
1.8 → 1.9¶
v1.9.0 is tagged. Notes: RELEASE_v1.9.0.md. Pin 1.8.1 / 1.8 stays the previous image for that line. The next jump is 1.9 → 1.10.
No new database revision. Recreate web and celery-worker. About should say 1.9.0. Move is on unless PIHERDER_SERVICE_MIGRATE=false. A LAN share can be saved beside Google Drive. HACS plugin 0.5.0 with resource ?v=0.5.0. Adapter 0.3.1 sends the four one-service jobs. OneDrive is unselectable on this 1.9.0 tag.
1.9 → 1.10¶
v1.10.0 is tagged. Notes: RELEASE_v1.10.0.md. Image 1.10.0 / 1.10 / latest. Pin 1.9.0 / 1.9 stays the previous image.
Alembic 048 runs on web start. Recreate web and celery-worker. About should say 1.10.0. OneDrive is a third row on Copy the backup drive. A destination can copy each new self-backup. Hosted /mcp can sign an agent in through the browser. Plugin 0.5.0 and adapter 0.3.1 stay on this 1.10.0 image. The next jump is 1.10 → 1.11.
1.10 → 1.11¶
v1.11.0 is tagged. Notes: RELEASE_v1.11.0.md. Image 1.11.0 / 1.11. Pin 1.10.0 / 1.10 stays the previous image for that line. The next jump is 1.11 → 1.12.
Alembic 049 and 050 run on web start. Recreate web and celery-worker. About should say 1.11.0. A passkey counts as 2FA when Force 2FA is on. A host can send files straight to a saved Drive, OneDrive, or LAN share. Hosted /mcp can start a Move, read or start a LAN Discovery scan, and tidy devices. Docker → Repository… can update an existing checkout. Plugin 0.5.3 is the current card. It needs Home Assistant 2024.7 or newer. Set the resource to /piherder/piherder-dashboard-card.js?v=0.5.3. Do not also list that URL as a frontend extra module. 0.5.1 still runs on Home Assistant 2024.1. Adapter 0.4.3 is on PyPI. 0.4.2 sends confirm=true on discovery purge and does not list prune_docker. uvx --refresh piherder-mcp, then restart the MCP client. The public demo is updated separately.
1.11 → 1.12¶
v1.12.0 is tagged. Notes: RELEASE_v1.12.0.md. Pin 1.12.0 stays that patch. The next jump is 1.12.0 → 1.12.1.
No new Alembic revision. Recreate web and celery-worker. About should say 1.12.0. The default Jobs and Audit lists leave a successful host snapshot out. A rejected copy sign-in stays one critical alert. An image stays flagged while a running container is still on the previous id. Restore can pull one selected folder from a copy destination. Plugin 0.5.2 and adapter 0.4.3 are the companions for this release. The public demo is updated separately.
1.12.0 → 1.12.1¶
v1.12.1 is the previous patch. Notes: RELEASE_v1.12.1.md. Pin 1.12.1 stays that patch. Pin 1.12.0 stays that patch. The next jump is 1.12.1 → 1.13.0.
No new Alembic revision. Recreate web and celery-worker. About should say 1.12.1. certifi is 2026.10.19. Plugin 0.5.3 is the card for that patch. Adapter 0.4.3 stays.
1.12.1 → 1.13.0¶
v1.13.0 is the current release. Notes: RELEASE_v1.13.0.md. Image 1.13.0 / 1.13 / latest. Pin 1.12.1 stays that patch.
Alembic 051 adds docker_prune_schedule. Recreate web and celery-worker. About should say 1.13.0. Plugin 0.5.4 is the current card. 0.5.3 was the card when v1.13.0 shipped. Adapter 0.4.4 is the current package. 0.4.3 was the package when v1.13.0 shipped. uvx --refresh piherder-mcp, then restart the MCP client. Hosted /mcp lists list_alerts, prune_build_cache, and replace_stale_mac. fleet_summary returns 404 on this image. Volume prune stays on the Docker page. The public demo is updated only when asked.
Breaking notes¶
Read the release doc for the version you jump to (migrations, new env keys, behaviour changes).