v1.7.1-rc.1
Full Changelog: v1.7.0...v1.7.1-rc.1
[1.7.1-rc.1] — 2026-10-23
This is a release candidate for the maintenance release on the 1.7 line. It is opt-in testing: v1.7.0 remains the stable release, and latest and the 1.7 channel do not move. 1.7.1 fixes data loss and breakage when Drydock recreates a container (anonymous volumes are kept, and containers sharing a network namespace with an updated container are recreated against it), updates services defined in compose include: files, and finishes the dependency work 1.7.0 described with a dependency view and update guards in the UI. It also adds an offline indicator that shows last-known data, a scan or install scope for the maintenance window (scan stays the default), maturity countdowns wherever a held update is listed, one pinned Trivy version with scanner versions shown in the Security view, the /api/v1/actions and /api/v1/notification-triggers routes (with /api/v1/triggers deprecated), optional dashboard widgets, translations for the remaining hard-coded UI strings, and a musl-dev pin so the image builds again.
Fixed
- Pin
musl-devto1.2.6-r3in the healthcheck build stage. Alpine 3.24 retired1.2.6-r2, so the image build failed atapk add. - The update-status panel now shows the Manual and Blocked action policy badges, not only Auto, and the full-page associated-triggers rows carry the per-trigger policy tooltip and Auto badge like the other trigger lists.
- Translate the remaining hard-coded UI strings and gate against new ones. Seven English literals are now localized in all 17 locales: the yes/no values in the container preview and compose-write rows, the "Page" and "unknown image" search subtitles, the preview-request fallback error, and a missing
containerComponents.groupedViews.updateFailedkey that rendered its raw key path when an update failed over SSE. New i18n specs fail CI when a key used inui/srcis absent from the English locale files (including dynamict(\prefix.${x}`)` keys) and when a user-facing literal reaches a template expression, toast, dialog or label property outside a documented allowlist. - The v1.7.0 dependency promise is now delivered in the UI. The release notes described a dependency-aware update flow, but only the API and wave ordering shipped. Besides the dependency rows, chain update and parent guard above, updating a single container now lists the containers that depend on it and says they are not updated or restarted with it, and a stack, group or dependency-group Update All that would update a child while its parent has its own pending update outside the batch asks first, naming the children and parents, with "Update anyway" to continue.
- Keep anonymous volumes when recreating a container. Containers whose image declares a
VOLUMEwith no named volume or bind mount, such as a defaultpostgresormysqlsetup, came back from an update with a fresh empty volume while the old one, with the data on it, was left orphaned. The docker and dockercompose actions, and self-update, now reattach the existing volume at the same path, asdocker compose updoes. - Containers that share a replaced container's network namespace or volumes now follow it. When Drydock updated a container that others attach to with
network_mode: container:<id>orservice:<name>(the Gluetun pattern) orvolumes_from, those containers kept pointing at the removed container and lost their network, and restarting them failed with "joining network namespace of container: No such container". Drydock now recreates them against the new container, keeping the rest of their configuration. - Update images for services defined in included compose files. Compose records only the files named on the command line in the
config_fileslabel, never the ones pulled in withinclude:, so Drydock could not find a service defined in an included file and skipped the compose file rewrite. Drydock now followsinclude:entries (nested ones too) from the listed files and rewrites the file that defines the service. Services that inherit their image throughextendsare still left alone. - Show the maturity countdown wherever a held update is listed. A candidate held by
maturityMode: maturenow shows the time left and its local unlock date and time in the container list and card tooltips, in a compact label next to the clock icon, and on the Updates Available dashboard widget, ticking once a minute from one shared clock. Previously only the container detail panels had it. - The default Docker scanner worker image and the release SBOM job now use the same pinned Trivy as the bundled image (0.73.0). They had stayed on 0.72.0 after the Dockerfile moved. A test now fails if the three digests differ, and Renovate bumps them in one PR.
- The Security view now shows the scanner version, image digest, and vulnerability database or cache update time in each scanner's tooltip, using the asset details the API already returned.
Added
- Prometheus lockout counters
drydock_auth_account_lockout_totalanddrydock_auth_ip_lockout_total, labelled by provider, increment once each time a login lockout starts. The existingdrydock_auth_account_locked_totalanddrydock_auth_ip_locked_totalgauges only show lockouts active at scrape time. The monitoring docs list the new counters and add an alert example and dashboard panel. - Category-specific trigger API routes that match the
DD_ACTION_*/DD_NOTIFICATION_*split:/api/v1/actions(docker,dockercompose,command) and/api/v1/notification-triggers(every other provider). They list, get and run triggers with the same auth and response shapes as/api/v1/triggers, and a trigger of the other category returns 404./api/v1/notificationsstays the notification rules collection. The UI trigger service now uses the new routes, and the OpenAPI spec and API docs cover them. - Optional dashboard cards and a Recent Activity widget. The dashboard Customize panel now lists Images, Triggers and Watchers stat cards and a Recent Activity widget, all hidden by default so saved layouts look exactly as before. Images counts distinct images and how many have updates, Triggers splits configured actions from notifications, and Watchers shows the count with a red state when an agent-backed watcher is disconnected. Each card links to its view. Recent Activity shows the latest 10 audit entries (time, actor, action, target), links each row to the Audit view filtered to that container, fetches only while shown, and refreshes on container and update events plus a 60 second interval. Preferences schema moves to version 13 to hide the new widgets once for existing layouts.
- The UI now shows a banner when the browser is offline or the Drydock server is unreachable, and clears it and refreshes the open views when the connection returns. While it's up, the dashboard and container views render the last known data with a "last updated" time, and update, start/stop, policy, rollback and delete actions are disabled with a tooltip. A 502, 503 or 504 from a reverse proxy counts as unreachable once a confirming request agrees, so one transient 503 doesn't flash the banner. The saved copy covers only a short list of safe read endpoints, is used only after the server can't be reached, expires after 24 hours, and is wiped on sign-out, sign-in and any 401. Also adds the missing
apple-mobile-web-app-status-bar-stylemeta tag for the installed iOS app. - The container list now shows dependencies and guards child-before-parent updates, which v1.7.0 described but never shipped in the UI (#219). A container with dependencies gets a chevron next to its name; expanding it lists what it depends on, what requires it, a cycle marker, and an "Update dependency group" button that previews the chain in wave order and asks for confirmation before dispatching it. Updating one container whose dependency also has a pending update now warns first, names the parents, and offers "Update anyway". The confirm dialog also renders multi-line messages as separate lines, so the wave list no longer runs together.
- A Dependencies view groups the container list into dependency trees. The new toolbar toggle, next to Group by stack, lists each connected set of containers as one group with parents first and their dependents indented beneath them, marks cycles and unresolved dependency targets, and leaves containers with no dependency edges in an unnamed group at the end. The group's Update All previews the chain in wave order and asks for confirmation before dispatching, the same path as the row's "Update dependency group" button. Stack and dependency grouping are exclusive, and the choice is remembered.
- Rows show "Depends on N" and "Required by N" badges. v1.7.0 already put
dependencyCountanddependentCounton every container but nothing in the UI displayed them. DD_WATCHER_{watcher_name}_MAINTENANCE_WINDOW_SCOPElets the maintenance window hold back installs only. The default staysscan, so nothing changes unless you opt in: the window keeps gating the whole scheduled scan, as in every earlier release. Set it toinstalland the scheduled scan keeps running on the watcher's ownCRONoutside the window, so new containers still appear, container state stays current and update notifications go out when the update is found. Only the automatic action is deferred, every action trigger rather than only the image-installing ones (commandincluded), and it runs as soon as the window opens; a digest-mode trigger flushes what it deferred when the window opens instead of waiting for its nextDIGESTCRON. Manual UI and API updates are unaffected. Containers watched by a remote agent are not deferred by the controller yet.dd_watcher_maintenance_deferred_updates_total{type,name}counts what the window held back, whiledd_watcher_maintenance_skip_totalkeeps its one-per-skipped-scan meaning and only moves underscan. Batch and digest action triggers no longer record a window-deferred container as notified, so aonce=truetrigger cannot swallow the rescan that runs when the window opens (Discussion #946).
Deprecated
/api/v1/triggersis deprecated in favor of/api/v1/actionsand/api/v1/notification-triggers. It keeps working and now sendsDeprecation: trueand aLink: <successor>; rel="successor-version"header, and logs a one-time warning per process. Removal is planned no earlier than v1.9.0 (see DEPRECATIONS.md).
Security
- Bump
nodemailerto 10.0.10 (GHSA-39m8-27wv-hr27, used by the SMTP notification trigger) and theip-addressoverride to 10.7.4 (GHSA-rxp7-6hxx-x8q5), and the website'sdompurifyto 3.4.17 (GHSA-c6gr-qvv4-5v3f, GHSA-mrv2-3pqr-j5jr). - Bump the website and docs app to
next16.4.2 for GHSA-p3m5-59mp-jv5r and GHSA-2464-fhr4-w9xw (website only, not in the Drydock image). - Override the e2e-only
http-cache-semanticsto 4.3.0 andargparseto 2.0.1 so the load-test harness no longer resolves the vulnerablehttp-cache-semantics4.2.0 orsprintf-js1.0.3 (GHSA-ch52-4w7c-c8xp, GHSA-hp3w-g68c-fv3c). Neither is in the shipped image.argparseis only used by js-yaml's CLI, which Artillery doesn't call. - Bump
viteto 8.2.4 (app, ui) and 7.3.7 (demo), and vitest and@vitest/coverage-v8to 4.1.12, for GHSA-587h-7wmj-h5pm, GHSA-698v-4r3x-3vcv, GHSA-r825-w8mm-5pxw, GHSA-9jrq-w75r-8gcw, GHSA-rq7h-c2jc-7f22, GHSA-vfpm-58rq-9qcg (vite) and GHSA-qxg6-89mg-rqv8, GHSA-xp26-3454-mjgp (@vitest/mocker). Dev dependencies only, not in the image. The app lockfile also movesfollow-redirectsto 1.16.1 for GHSA-8r9p-f939-6h3c and GHSA-q3jh-wrc6-jgq8.
Changed
- Prepare retained v1.7 release-metadata CI with available exact Alpine libexpat/cosign pins and the reviewed scanner configuration from the active train. The published v1.7.0-rc.24 image, source, artifacts and soak are unchanged; GA promotes that image.
Note: this is a maintenance cut, built from dev/v1.7 at 7a4155a45bb450758fbf0eec2e306afc914dd562, not from main.
- The container image and release artifact are cosign-signed (identity
release-cut.yml@refs/heads/main, since the workflow run itself always executes at that ref), but carry no SLSA build-provenance attestation — this workflow's own OIDC token always claimsmainHEAD as the build source, which would be false for this artifact, so attestation is skipped rather than publish a false claim.