Release checks and host updates
Signed-in users automatically check the configured GitHub repository's latest published stable release. A newer numeric version adds an update arrow immediately after the version label (bottom right on desktop, in the mobile admin header, or in the mobile setup footer). Click it to review the formatted changelog, release-specific upgrade notes and deployment consequences in a modal. The compact 28px circle, 16px arrow and 5px status dot retain a 44px tap target and keyboard focus styling in both themes. HTML, scripts and remote images stay literal; links allow only HTTP/HTTPS. Missing notes have an explicit empty state. Sign-in keeps the version without an action.
Checks run when the session opens, every minute while the page is visible and on
window focus. The server coalesces checks and caches metadata for fifteen minutes,
or one minute after a failure. Numeric stable tags, with or without v, are
supported. Drafts, prereleases, malformed tags, equal versions and downgrades are
never offered. Changelogs scroll within the modal; Update and Cancel stay ordered.
Install the host updater once
Panel updates run on the installation host. The GitHub deployment workflow is removed. The remaining Verify workflow supplies evidence that the selected commit passed quality, deterministic database tests, browser tests and container checks. The container job bounds optional build-cache exports to two minutes and tolerates cache-export errors so image smoke, migration and restore checks can still run. The host builds images from that exact commit and reuses the existing protected backup/migration/readiness cutover. Publishing a release makes it discoverable; installation starts only after a deployment administrator clicks Update now. No Actions write token or GitHub SSH deployment secrets are needed.
This currently supports the dedicated Linux x86_64 Docker VPS stack, including its Docker Codex runner. It does not replace a custom Compose topology, the optional Code Truth service or a local build overlay. See the VPS guide first.
On the provisioned host, copy the checked-in daemon and service template:
sudo install -d -m 700 /opt/repodesk/updater
sudo install -m 700 scripts/update-host.mjs /opt/repodesk/updater/update-host.mjs
sudo install -m 700 scripts/cleanup-host.mjs /opt/repodesk/updater/cleanup-host.mjs
# The app image's node user is UID/GID 1000. Root daemon can read its private queue.
sudo install -d -o 1000 -g 1000 -m 700 /opt/repodesk/updates /opt/repodesk/updates/requests
sudo install -m 644 deploy/updates/repodesk-updater.service /etc/systemd/system/repodesk-updater.service
# Edit root, project, repository, Node path and service user for this installation.
sudo systemctl daemon-reload
sudo systemctl enable --now repodesk-updater
Node 24, Git, Docker Engine/Compose v2, Bash, gzip, sha256sum and flock must be available. The service must have the deployment user's Docker/filesystem access. The sample uses root, which already has Docker's equivalent host privileges. A matching deployment account may be configured instead; ensure it can read the app's UID-1000 queue and write the host releases/backups. Do not grant Docker socket access to the web app. Only the existing trusted Codex supervisor keeps it.
The base Compose app mounts <deployment root>/updates at
/var/lib/repodesk-updates. This contains requests, results and an updater
heartbeat. Keep the deployment root and Compose project identical to the running
stack so its database and Codex volumes are preserved. Restart the app once with
the new Compose configuration after provisioning. For a direct Node app set
UPDATES_DIRECTORY=/opt/repodesk/updates; it must reach this same queue.
Set UPDATES_GITHUB_REPOSITORY=owner/repository for a fork; the service's last
argument must match. Default: stonega/repodesk. Public repositories work without
a token. An optional fine-grained Contents: read / Actions: read token can
increase API limits or read private source/CI. Store it in the host's protected
.env for the app (UPDATES_GITHUB_TOKEN), or use a private mounted file for a
Node app (UPDATES_GITHUB_TOKEN_FILE). The host service can read its own token
file using the commented Environment entry. Restart after token rotation.
Credentials never enter requests, browser responses or ordinary app logs.
Update and recovery
Only authenticated deployment operators can queue installations. Existing session, origin and CSRF checks apply; workspace accounts can review notes. The server rechecks release ID, notes fingerprint and tag commit before saving a reservation, operator audit and atomic queue file. Concurrent clicks and app restarts produce one request. A missing/stale heartbeat or mismatched host repository prevents submission. No file is written by a release check or modal open.
The host verifies the exact published stable release and a successful Verify run
for its commit, fetches that commit, checks package version, builds app/Codex
images locally, and smoke-tests the Node app image. It rechecks release metadata
immediately before passing the bundle to deploy-vps.sh --local-images. The
bundle records all three local image IDs; the script checks the release tags
still resolve to those IDs before stopping writers. Saving and reloading images
on the same daemon is unnecessary. Manual transferred archives retain checksum
verification and import support. The cutover waits for safe coding checkpoints,
stops writers, backs up PostgreSQL, migrates,
starts writers and confirms readiness. A changed release or unverified commit
fails before any cutover. Expect a brief outage; the queue and results survive it.
The updater requires at least 1GiB free on the deployment filesystem before checkout, each image build and cutover. This is a minimum reserve, not an estimate of build or database-backup size. A disk-space failure is shown explicitly in the modal; free space before using Retry update. Keep a retention policy for unused release images and build cache, preserving running/retained release and task images, database volumes, credentials and backups. The updater does not automatically prune host resources; the separately installed daily cleanup timer provides that policy and shares the updater's storage lock. Older releases still use the archive path; the direct local-image path takes effect in a release containing this correction.
The modal polls queued/running/completed/failed status and offers Reload after
success. Installed version is checked after reload, separately from daemon
completion. Host logs are at updates/logs/<request UUID>.log (private); service
health is available through systemctl status repodesk-updater and journalctl.
Queue/result files contain release metadata, not secrets or conversation contents.
A failed job shows an explicit Retry update action after the operator reviews
logs and fixes the cause. It creates a fresh bundle/backup ID. Restarting the
agent during an active job records an uncertain outcome and never repeats cutover.
An interrupted or ambiguous request blocks further installations. Follow the VPS
recovery guide, confirm no old updater child or deployment is running, and clear
that reservation from deployment_updates by repository/release ID only after
reconciliation. Preserve its operator audit. Never restore a database or revert
a migrated image automatically. Retain backups and prune old sources/logs/release
images through an operator policy; successful source checkouts are removed.
updates.http documents the API. Local tests use fake
GitHub, host commands and queue fixtures. Host provisioning and a direct VPS
cutover were verified on 2026-10-09 for cfffdfc (v0.1.32), including public
readiness and queue access from the app. This host uses
/opt/repodesk/updater/node (v24.21.0, extracted from the verified app image) in
its installed service instead of a global Node installation. The in-app v0.1.34
retry succeeded on 2026-10-10 after recovering disk capacity, and the reloaded
browser showed v0.1.34. That release used the original archive path; installing
the new direct local-image path remains a future-release live check. See
the recovery evidence.
API references: GitHub Releases, Verify run lookup.