v1.5.0-rc.8
[1.5.0-rc.8] - 2026-04-13
Added
- Backend-driven update queue — Container updates are now queued server-side with per-trigger concurrency limits. UI shows Queued → Updating → Updated state progression with sequence labels (e.g. "Updating 1 of 3"). (#bacbc1c7, #5edc55a2, #7d7cfdfc)
- Watcher next-run metadata (#288) — Watcher API and Agents view now show when each watcher will next poll for updates. (#6706929e)
- Notification delivery failure audit entries (#282) — Failed notification deliveries appear in the notification bell dropdown. (#ae5309b3)
- Container action operations — Container actions (start, stop, restart, etc.) tracked with dashboard updates. (#6615ccbf)
- Identity-keyed container tracking — Containers tracked by stable identity key (agent::watcher::name) across renames/replacements. Audit events include
containerIdentityKey. Recent-status API returnsstatusesByIdentityfor precise per-container status resolution. (#8fb75070, #ea413c34) - Trigger buffer retention and capacity limits — Digest and batch-retry buffers now enforce a 5,000-entry cap and 7-day retention window, evicting the oldest entries first and pruning stale entries before each access. Prevents unbounded memory growth on long-running controllers. (#c6a9930c)
- Update operation recovery phases — New phases (
recovered-cleanup-temp,recovered-rollback,recovered-active,recovery-failed,recovery-missing-containers) distinguish operations that completed via the deferred reconciliation recovery path from the primary update flow. (#3ffe2f12)
Changed
- Auth user cache removed — Replaced TTL-based auth cache with request deduplication only, ensuring logout/session expiry in other tabs is reflected immediately. (#923e0926)
- ♻️ refactor(ui) — Container update cards now render phase-only queue status, while grouped stack headers own the frozen
X of Y donebatch progress copy for multi-container updates.
Fixed
- #296 — Notification server-name prefix no longer renders the container ID on Docker Compose setups.
getServerName()precedence is nowDD_SERVER_NAME→ detected Docker/Podman daemon host name (fromdockerApi.info().Name) →os.hostname(). Remote watchers never hijack the controller identity. (#b723369f) - #286 — Stack view column shifting fixed by collapsing all stacks into a single table. (#2f511d33)
- #283 — Duplicate server name in notification prefix and suffix suppressed. (#aaf9962d)
- #270 — Hide-pinned filter now uses computed
tagPinnedproperty instead of stale stored field. Unconditional startup repair ensures tagPrecision data is always correct. (#c7ecceef, #0949a142) - #291 — Dashboard update widget now uses the same update-start semantics as containers view (shows "Updating" toast, not "Updated"). (#c9f21a7b)
- #290 — Update-applied success events preserved across Docker container rename race. (#6b5c1f72)
- #289 — Standalone (non-queued) update state transitions restored after queue-aware changes broke them in rc.7. (#2b00c4b8)
- #287 — Custom healthcheck backward compatibility restored. The built-in
/bin/healthcheckremains the default image probe and now handles TLS backends, whilecurlis again present in the Docker image for user-defined customhealthcheck:overrides during the v1.5.x deprecation window. v1.6.0 is the final warning release, and removal is now scheduled for v1.7.0. (#414f0170) - #282 — Digest buffer evicted after batch send; watcher events awaited for handler ordering; batch send retry with delivery failure audit; agent remote report events awaited. (#982b4d74, #0594e971, #c31f78eb, #1ac7c36d)
- #276 — Dashboard update tracking keyed by container ID instead of name. (#c81e25a8)
- #256 — Pending update state scoped by stable container identity, preventing cross-contamination between same-name containers on different hosts. (#05c023fe)
- #253 — Shorthand trigger references resolved in notification rule matching; notification buffering keys stabilized; debug logging added to every silent filter path. (#ba6341b4, #d475d33c, #bb1550e4)
- #248 — API guard against duplicate container updates (409 conflict). (#110aae36)
- #217 — Vulnerability rows top-aligned in detail panels. (#431be5ea)
- Expired update operations — Executor revives expired pre-created operations instead of inserting duplicate rows. (#04e847ef)
- Static asset throttling — SPA fallback rate limiter no longer throttles static assets. (#bfe52038)
- Compound rolling tag aliases misclassified as pinned —
isTagPinnednow treats aliases likelatest-alpine,stable_arm64, anddev.buildas floating even when their suffixes contain digits. (#da613f70)
Performance
- Virtual scrolling for grouped containers table — Grouped container tables no longer render every row eagerly, keeping the DOM light on deployments with many containers. (#606d5cc0)
Security
- Axios CVE-2025-62718 — Updated axios 1.13.6 → 1.15.0. (#c4af5e4a)
- Healthcheck HTTPS probe hardening —
/bin/healthcheckno longer usespopen()with shell command interpolation to invokeopenssl. The probe now locates the openssl binary explicitly, fork/execs it with pipes, and uses poll-driven I/O with SIGPIPE handling — eliminating any shell injection surface. (#0173d7ed) - SSE log IP hashing with opt-in raw mode — SSE connect/disconnect lines and per-IP rate-limit warnings now log the internal client ID plus a salted hash of the source IP (
h:xxxxxxxx) by default. The hash salt rotates on every process start, so hashed identifiers cannot be correlated across restarts and raw addresses never touch the log. Operators troubleshooting a specific connection issue can setDD_SSE_DEBUG_LOG_IP=trueto temporarily log raw IPs. (#9e236745) - HTTP trigger proxy URL scheme validation — HTTP trigger proxy URLs must now be
http://orhttps://schemes. Invalid schemes are rejected at config-validation time and fail closed at runtime instead of silently constructing a broken proxy. (#981f7f8e) - Vulnerability CSV export escape hardening — Every CSV field (including column headers) is now quoted unconditionally, and tab/CR leading characters are escaped alongside
=+-@to fully close the CSV formula-injection surface. (#95de9f0e) - Snyk policy file — Added a repo-level
.snykfile so reviewed false-positive Snyk Code findings are silenced with a mandatory reason and expiry date alongside the code, instead of in PR comments. Initial entries cover the ephemeral session-secret generator and the UI static file sink flagged viaprocess.argv[1]taint. (#61f49606) - Supply-chain toolchain refresh — Bumped pinned Alpine edge/testing package versions for
cosign(2.4.3-r12) andtrivy(0.69.3-r2) in the Dockerfile to track upstream security fixes. (#b542eb15)
Internal
- Exact-version package.json pinning — Flipped the four remaining caret specifiers (
nodemailer,@biomejs/biome,lefthook,lodash) to exact versions so every package.json matches the already-exact lockfile resolutions and Renovate cannot pull in-range bumps without a PR. Every dependency layer is now SHA-immutable: npm via lockfile integrity hashes, Docker base images via@sha256:digests, and GitHub Actions via 40-char commit SHAs. (#23b7fcfd) - Regression test coverage — Closed the remaining app + UI coverage gaps flagged by the pre-push gate, including guard branches in
detectLocalDaemonServerName,useOperationDisplayHold,useContainerFilters,preferences/migrate, serviceslogsandsystem-log-stream, anduseContainerPolicy. (#58932e40, #9f238be5, #72d6d688)