Self-update: recreate via the Docker API — zero-config, with rollback - #27
Merged
Merged
Conversation
…llback Self-update no longer depends on the compose file at all. Previously, applying an update ran docker compose up -d through the coordinator, which required the compose file path (from container labels or manual overrides) to resolve on the host — the top failure mode being "Compose file not found at ... inside the Watchtower container". The coordinator now recreates the Watchtower container purely via the Docker API: it clones the running container's configuration onto the freshly pulled image (ContainerCloneSpec — carries Config/HostConfig/networks, drops the id-derived default hostname and runtime-assigned network fields, filters the old container's stale alias), stops and renames the old container aside, creates and starts the replacement under the original name, and rolls back to the old container if that fails. The old container is only removed once the new one is up, so a failed update can never leave the host without Watchtower. Consequences: - Zero configuration: no compose path/project detection, no overrides section in Settings, no mount requirements. Config is down to the registry credential. Works for any deployment shape, including docker run. - Trade-off (documented in docs/architecture.md): a compose file edited since the last deploy is not re-asserted by a self-update — run docker compose up -d on the host to apply compose-file changes. - The main process now watches the coordinator after spawning it, so a failed (rolled-back) apply surfaces in the UI immediately instead of sticking at "restarting" until the next restart; concurrent applies are blocked for the whole restart window. On success the next process instance reconciles the coordinator exit code at startup, as before. - Saving the config clears a lingering apply error (remediation path), never an in-flight stage. - DockerEngineClient gains raw-JSON inspect/create, rename and network-connect endpoints for the full-fidelity clone; Docker API error bodies are surfaced in exceptions instead of bare status codes. - ComposeCliService.ConfigAsync removed (no callers left); rpc-schema and the generated frontend client regenerated. The cloning rules are pinned by unit tests (ContainerCloneSpecTests); Docker itself is not exercised in CI, so run one manual update cycle on a test host before tagging a release.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Self-update no longer depends on the compose file at all. The coordinator now recreates the Watchtower container purely via the Docker API instead of running
docker compose up -d, which removes the whole category of compose-configuration failures — most prominently:How it works
ContainerCloneSpec— carries Config/HostConfig/networks, drops the id-derived default hostname so HOSTNAME-based self-detection keeps working, strips runtime-assigned network fields and the old container's stale alias, splits extra networks into post-create connects).Consequences
docker run.docs/architecture.md): a compose file edited since the last deploy is not re-asserted by a self-update — rundocker compose up -don the host to apply compose-file changes.DockerEngineClientgains raw-JSON inspect/create, rename and network-connect endpoints for the full-fidelity clone; Docker API error bodies are surfaced in exceptions instead of bare status codes.ComposeCliService.ConfigAsyncremoved (no callers left);rpc-schema.jsonand the generated frontend client regenerated.Testing
ContainerCloneSpecTestspinning the cloning rules, 140 API); frontend typecheck clean.system.updateConfiground trip against a live dev stack in the browser.