Skip to content

Add Docker update support via Watchtower integration#1330

Open
Sebbeben wants to merge 3 commits intoPart-DB:masterfrom
Sebbeben:feature/docker-watchtower-update
Open

Add Docker update support via Watchtower integration#1330
Sebbeben wants to merge 3 commits intoPart-DB:masterfrom
Sebbeben:feature/docker-watchtower-update

Conversation

@Sebbeben
Copy link
Copy Markdown
Contributor

@Sebbeben Sebbeben commented Mar 25, 2026

Summary

Extends the Update Manager to support Docker-based installations by integrating with Watchtower, a popular container update tool.

  • WatchtowerClient service — communicates with Watchtower's HTTP API to check status and trigger updates
  • Docker update progress page — Stimulus-based polling UI that survives container restarts, with progress indicators and timeout handling
  • Health endpoint (/update-manager/health) — unauthenticated JSON endpoint for post-restart detection (session is lost when container restarts)
  • Docker-specific UI — hides Git-only fields (branch, commit, local changes) for Docker installs, shows Watchtower connection status
  • Pre-update backup — creates database backup before triggering Watchtower
  • CSP fix — replaces javascript:history.back() with proper navigation in error template

How it works

  1. User clicks "Update to latest version" on the Update Manager page
  2. Part-DB creates a database backup
  3. Part-DB calls Watchtower's HTTP API to trigger an update
  4. User is redirected to a progress page that polls the health endpoint
  5. When the container restarts with the new image, the health endpoint responds and the UI shows success

Configuration

Docker users add a Watchtower sidecar to their docker-compose.yml:

watchtower:
  image: containrrr/watchtower
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  environment:
    - WATCHTOWER_HTTP_API_UPDATE=true
    - WATCHTOWER_HTTP_API_TOKEN=your-secret-token
    - WATCHTOWER_LABEL_ENABLE=true
  ports:
    - "8080:8080"

And set environment variables for Part-DB:

WATCHTOWER_API_URL=http://watchtower:8080
WATCHTOWER_API_TOKEN=your-secret-token

If Watchtower is not configured, the Update Manager gracefully shows an informational message explaining how to enable Docker updates.

Files changed

File Purpose
src/Services/System/WatchtowerClient.php New — Watchtower HTTP API client
src/Controller/UpdateManagerController.php Docker update actions + health endpoint
src/Services/System/UpdateChecker.php Watchtower status in update info
src/Services/System/UpdateExecutor.php Docker update validation
src/Services/System/InstallationType.php Docker supports auto-update
src/EventSubscriber/MaintenanceModeSubscriber.php Whitelist health endpoint
assets/controllers/docker_update_progress_controller.js New — Stimulus polling controller
templates/admin/update_manager/docker_progress.html.twig New — Progress page template
templates/admin/update_manager/index.html.twig Docker-specific UI sections
templates/bundles/TwigBundle/Exception/error.html.twig CSP fix for back link
translations/messages.en.xlf Translation keys for Docker update UI

Test plan

  • PHPStan passes (verified, 0 errors)
  • Tested on Docker installation (Orange Pi ARM64) with Watchtower sidecar
  • Verified update progress UI survives container restart
  • Verified graceful degradation when Watchtower is not installed
  • Verified health endpoint is accessible without authentication
  • Verified CSRF protection on all mutating endpoints

Screenshots

Update Manager - Docker Installation

update_manager_docker

Update in Progress

updating

Update Complete

update_complete note: this is when i was developing and thats why it says updating from v2.9.0 -> v2.9.0

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 25, 2026

Codecov Report

❌ Patch coverage is 44.89796% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.16%. Comparing base (4206b70) to head (43b9441).
⚠️ Report is 31 commits behind head on master.

Files with missing lines Patch % Lines
src/Controller/UpdateManagerController.php 0.00% 38 Missing ⚠️
src/Services/System/UpdateExecutor.php 10.00% 9 Missing ⚠️
src/Services/System/UpdateChecker.php 60.00% 4 Missing ⚠️
src/Services/System/InstallationType.php 0.00% 2 Missing ⚠️
src/EventSubscriber/MaintenanceModeSubscriber.php 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1330      +/-   ##
============================================
+ Coverage     56.45%   57.16%   +0.71%     
- Complexity     8323     8439     +116     
============================================
  Files           611      617       +6     
  Lines         26731    27210     +479     
============================================
+ Hits          15091    15555     +464     
- Misses        11640    11655      +15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jbtronics
Copy link
Copy Markdown
Member

I think it would be good to have something in the docker installation documentation on how to use setup that.

Add web-based Docker container updates using Watchtower HTTP API.
When configured with WATCHTOWER_API_URL and WATCHTOWER_API_TOKEN
environment variables, administrators can trigger container updates
from the Update Manager page.

Features:
- WatchtowerClient service for Watchtower HTTP API communication
- Docker update progress page with animated Docker whale logo
- Real-time step tracking: Trigger, Pull, Stop, Restart, Health Check, Verify
- CSP-compatible progress bar using CSS classes
- Translated UI strings via Stimulus values
- Health endpoint polling to detect container restart
- Watchtower setup documentation for Docker installations
- WatchtowerClient made nullable for non-Docker installations
- Unit tests for WatchtowerClient
@Sebbeben Sebbeben force-pushed the feature/docker-watchtower-update branch from 2fb6514 to 3cdd085 Compare March 31, 2026 08:09
@Sebbeben
Copy link
Copy Markdown
Contributor Author

Sebbeben commented Mar 31, 2026

I think it would be good to have something in the docker installation documentation on how to use setup that.

Added Watchtower setup documentation to the Docker installation guide (docs/installation/installation_docker.md). It covers:

  • Adding the Watchtower service to docker-compose.yaml
  • Configuring WATCHTOWER_API_URL and WATCHTOWER_API_TOKEN environment variables
  • Using label-based filtering to only manage the Part-DB container
  • How the Update Manager UI integrates with Watchtower

Also squashed all commits into a single clean commit and addressed the PHPStan issue (optional parameter before required ones).

Note: The postgres CI failures are a pre-existing upstream issue (FK violation during fixture loading) — they also fail on master.

@Sebbeben
Copy link
Copy Markdown
Contributor Author

Sebbeben commented Mar 31, 2026

Updated Docker Update Progress UI

The progress page has been redesigned to match the git update style:

[Docker Update Progress]new_update_screen

Changes in this update:

  • Animated Docker Moby whale logo (official SVG, Docker blue #2496ED)
  • 6 detailed steps with live timestamps: Trigger → Pull → Stop → Restart → Health Check → Verify
  • CSP-compatible progress bar using CSS classes instead of inline styles
  • Translated UI strings passed from Twig to Stimulus controller
  • WatchtowerClient made nullable for non-Docker installations (fixes crash on git installs)
  • Watchtower setup documentation added to docs/installation/installation_docker.md
  • All commits squashed into one clean commit

@jbtronics
Copy link
Copy Markdown
Member

I am not sure how wise it is, to build this around watchtower.
According to the github project README it is not maintained anymore: https://github.com/containrrr/watchtower

And the last release is from 2023.

@Sebbeben
Copy link
Copy Markdown
Contributor Author

That's a fair concern — I should have checked the maintenance status more carefully. Here are the options I see for keeping the one-click update UX this PR aims for:

Option 1: Switch to a maintained fork (smallest change)
nicholas-fedor/watchtower is an active fork — v1.16.1 released April 2026, same HTTP API (POST /v1/update with bearer token). Drop-in swap: zero code changes in Part-DB, just update the documented image reference in docs/installation/installation_docker.md. Tradeoff: still a single-maintainer fork, so bus factor is low.

Option 2: Abstract the backend behind an interface
Introduce a ContainerUpdaterInterface with Watchtower as one implementation. Users configure CONTAINER_UPDATER=watchtower|… and we can add new backends as the ecosystem evolves. Future-proofs the feature if forks also stagnate. More code to maintain, but keeps options open.

Option 3: DIY via docker.sock
Part-DB talks to the Docker Engine API directly (pull image, recreate container via a detached helper, since a container can't cleanly restart itself mid-request). No third-party dependency, but mounting docker.sock in a web app container is a meaningful security surface — effectively root on the host. Would need tecnativa/docker-socket-proxy with a minimal allow-list to mitigate. More complex, and Docker Engine API doesn't understand compose so reconstructing run args is fiddly.

My lean is Option 1 (swap to nicholas-fedor/watchtower) for this PR — minimal change, we ship the feature now — and if a second viable backend appears later we can refactor to Option 2 at that point. Option 3 only makes sense if we want to eliminate the sidecar entirely, and the security tradeoff feels heavy for the benefit.

What do you think?

@jbtronics
Copy link
Copy Markdown
Member

Yeah using the fork is probably the best solution for now

The original containrrr/watchtower is no longer maintained (last release
Nov 2023). Point users to the drop-in compatible active fork and add an
info note explaining why. No code changes — the HTTP API is identical,
so WatchtowerClient works against either image.
@Sebbeben
Copy link
Copy Markdown
Contributor Author

Done — pushed 43b9441b switching the Docker installation docs to ghcr.io/nicholas-fedor/watchtower:latest and added a short info note explaining why (original unmaintained since Nov 2023, fork is drop-in API-compatible).

No code changes — WatchtowerClient talks the same HTTP API to either image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants