Releases: CodesWhat/drydock
v1.4.5
What's New
Added
- Dashboard Update buttons — Per-row update buttons and "Update all" button in the Updates Available dashboard widget. (#173)
- Getting Started guide — New step-by-step onboarding guide covering watchers, tag filters, registries, notifications, auto-updates, safety features, and multi-host setup. (#153)
Fixed
- Container recreate alias filtering — Hardened Docker watcher timestamp parsing, added event handler early return for transient aliases, canonical MQTT topic naming, and stale topic cleanup for recreated containers. (#156)
- About modal version display — Version is now fetched dynamically from the API instead of being hardcoded. (#167)
- Version resolution fallback —
DD_VERSION=unknownis now skipped so the version is correctly read frompackage.jsonat startup. - Theme circle transition origin — The theme toggle animation now originates from the click point instead of the viewport center.
- Trigger code bugs — Gotify URL and Apprise URL now correctly enforce
.required()validation; KafkaclientIdcasing normalized.
Security
- OIDC debug log redaction — Sensitive OIDC parameters are now redacted in debug logs. (#168)
- Agent API error sanitization — Error logs and responses in the agent API are sanitized to prevent leaking internal details.
- Registry config value redaction — Trigger group configuration now logs keys only, not values.
- socket.io-parser 4.2.5 → 4.2.6 (CVE-2026-33151)
Changed
- API versioning — All UI fetch calls migrated from
/api/to/api/v1/paths. - Docs audit (78 files) — Fixed 18 doc accuracy issues, 3 code bugs, 22+ broken links, and restructured 8 pages.
Dependencies
fast-xml-parser5.3.8 → 5.5.6 (CVE),next16.1.6 → 16.1.7 (HTTP smuggling, CSRF bypass, DoS)step-security/harden-runnerv2.15.1 → v2.16.0,github/codeql-actionv4.32.6 → v4.33.0- App, UI, Website, and Demo dependency bumps — see CHANGELOG for full details.
Full Changelog: v1.4.4...v1.4.5
v1.4.4
UI Polish & Hardening
Bug Fixes
- Container recreate alias hardening — Unconditional 30s transient window skip, single inspect per event, security-bounded suppression. Fixes slow-shutdown containers producing duplicate MQTT/Telegram entries. (#156)
- Dashboard host-status for remote watchers — Widget now shows correct container counts for non-agent remote watchers. (#155)
- Tooltip viewport overflow — Replaced CSS pseudo-element tooltips with body-appended popup using
position:fixedand auto-flip. (#165) - Theme switcher — Restored document binding for
startViewTransitionAPI.
New Features
- Click-to-copy on version tags —
CopyableTagcomponent with "Copied!" tooltip feedback on all version displays (dashboard, container list, detail panels). (#164) - Dark mode icon inversion — Simple Icons (
si:prefix) auto-invert in dark mode. - Tailwind v4 class-based dark mode —
@custom-variant darkdirective for proper.darkclass detection.
Improvements
- Dashboard version column centered
- Sidebar search button border removed, ⌘K badge improved dark mode contrast
- CI pipeline graph connected (lint/test now depend on security check, build gates on all three)
- Pre-push build-test script captures output for readable failure diagnostics
- URL rebrand: all references updated to
getdrydock.com - CHANGELOG split into proper v1.4.2/v1.4.3/v1.4.4 sections
- TypeScript quality improvements across UI source and test files
Full Changelog
v1.4.3
What's Changed
Fixed
- DNS resolution failures on Alpine (EAI_AGAIN) — Node.js 24 defaults to
verbatimDNS ordering, which on Alpine's musl libc can causegetaddrinfo EAI_AGAINerrors when IPv6 records are returned first on dual-stack networks. Drydock now defaults to IPv4-first DNS ordering at startup, configurable viaDD_DNS_MODE(ipv4first|ipv6first|verbatim, default:ipv4first). (#161)
Security
- Scope CI secrets to dedicated environments — Repository secrets referenced by CI and release workflows are now scoped to
ciandreleaseGitHub environments, preventing unauthorized workflow access. - Make zizmor findings blocking — The zizmor GitHub Actions security scanner is now a blocking step in both CI and local pre-push hooks (previously advisory-only).
Documentation
- DNS configuration page — New DNS configuration docs covering
DD_DNS_MODEvalues and IPv6-only setup. - DNS troubleshooting FAQ — Added FAQ entry for diagnosing
EAI_AGAINerrors.
Full Changelog: v1.4.2...v1.4.3
Verification
All container images are signed with Sigstore cosign (keyless). Verify with:
cosign verify \
--certificate-identity-regexp="https://github.com/CodesWhat/drydock" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/codeswhat/drydock:1.4.3Release artifact signatures can be verified similarly:
cosign verify-blob \
--bundle drydock-v1.4.3.tar.gz.bundle \
--certificate-identity-regexp="https://github.com/CodesWhat/drydock" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
drydock-v1.4.3.tar.gzv1.4.2
What's Changed
Bug Fixes
- Container recreate alias duplicates — Docker's transient aliases during container recreation no longer produce duplicate entries in triggers (#156)
- Stale store data after recreation — Every startup now runs a full scan with alias filtering, fixing stale records from previous runs (#157)
- Watcher container counts on Hosts page — Per-watcher counts now use
watcher.nameinstead ofwatcher.id, fixing zero-count display (#155) - Docker images tagged
:main— Release workflow now only triggers on version tags (v*), removing the unversioned:mainimage tag (#154) - Auth registration errors on login — Provider registration failures are now surfaced on the login page for admin diagnosis
- Maturity badge sizing — Fixed height mismatch and tooltip clipping in list view
Refactors
- Extract
ClonedRuntimeFieldEvaluationContextinterface for trigger runtime config - Improve Argon2 hash parsing type safety with extracted interfaces and helpers
- Extract
AgentClientconstructor into focused private methods - Deduplicate self-hosted registry config schema into shared helper
Dependencies
- biome 2.4.7, vitest 4.1.0, fast-check/vitest 0.3.0, knip 5.86.0
- Vue, Storybook, and icon packages (UI)
- zizmor-action v0.5.2, cosign-installer v4.1.0 (CI)
Full Changelog: v1.4.1...v1.4.2
v1.4.1
What's New
Added
- Headless mode (
DD_SERVER_UI_ENABLED) — Run drydock as an API-only service by settingDD_SERVER_UI_ENABLED=false. The REST API, SSE, and healthcheck endpoints remain fully functional while the UI is not served. Useful for controller nodes that only manage agents. - Maturity-based update policy — Per-container update maturity policy via
dd.updatePolicy.maturityMode(allormature) anddd.updatePolicy.maturityMinAgeDays(default 7). When set tomature, containers with updates detected less than the configured age threshold are blocked from triggering until the update has settled. UI shows NEW/MATURE badges with flame/clock icons on containers with available updates. (#120) ?groupByStack=trueURL parameter — Bookmarkable URL parameter to enable stack grouping on the containers page. (#145)
Fixed
- Agent handshake and SSE validation failure — Fixed agent API returning redacted container data causing controller-side Joi validation to reject the handshake and crash on real-time SSE container events. (#141)
- Mangled argon2 hash detection — Docker Compose
$interpolation can strip$delimiters from argon2 PHC hashes. Drydock now detects mangled hashes at startup and surfaces an actionable error message. (#147) - Anonymous auth fallback — When all configured auth providers fail to register, Drydock now falls back to anonymous mode if
DD_ANONYMOUS_AUTH_CONFIRM=trueis set. (#147) - Auth registration errors on login page — Registration warnings are now surfaced on the login page instead of a generic "No authentication methods configured" message. (#147)
- CSRF validation behind reverse proxies — Same-origin mutation checks now honor
X-Forwarded-ProtoandX-Forwarded-Hostwhen present. (#146) - Hosts page missing env-var-configured watchers — Watchers configured via
DD_WATCHER_*environment variables are now displayed on the Hosts page. (#151) - Compose trigger affinity — Enforce compose-file affinity when associating triggers with containers. (#139)
- CSP inline style violations — Replaced runtime
element.stylemutations with CSS custom properties and class-based styling.
Security
- Username enumeration timing side-channel — Eliminated timing difference between valid and invalid usernames during authentication.
- LokiJS metadata exposure — Stripped internal LokiJS fields from API responses.
- Permissions-Policy header — Added
Permissions-Policyheader to restrict browser feature access. - CSP and Cross-Origin-Embedder-Policy — Tightened Content Security Policy and added COEP header.
- Production image hardening — Removed
wget,nc, andnpmfrom the production Docker image; upgraded zlib.
Dependencies
- undici — Bumped to 7.24.1 (fixes 12 CVEs including WebSocket memory consumption, CRLF injection, and request smuggling).
Full Changelog: v1.4.0...v1.4.1
v1.4.0
Drydock v1.4.0
The biggest release yet — a complete UI overhaul, fail-closed security hardening, and 80+ changes.
What's New
UI Modernization
- Tailwind CSS 4, Vue 3 Composition API, shared component library
- 6 color themes — One Dark, GitHub, Dracula, Catppuccin, Gruvbox, Ayu (dark + light)
- 7 icon libraries — 500+ icons with tree-shaking, offline-capable
- Font size preference, borderless redesign, responsive layouts
Dashboard
- Real-time stat cards (containers, updates, security, registries)
- Update summary, security overview, and host status widgets
- Drag-and-drop widget ordering with localStorage persistence
Compose Trigger Overhaul
- Auto compose file detection from container labels with Docker inspect fallback
- Pre-commit
docker compose configvalidation before writes - Digest pinning, reconciliation modes (warn/block), compose-file-once batch mode
- Directory-as-FILE support (
DD_TRIGGER_DOCKERCOMPOSE_{name}_FILE=/path/to/dir)
Security Hardening
- Argon2id password hashing (OWASP recommended, Node.js built-in
crypto.argon2Sync) - OIDC redirect URL validation, CSRF Sec-Fetch-Site protection
- Rate limiting with identity keying for shared proxies
- Permissions-Policy, Cross-Origin-Embedder-Policy, tightened CSP
- Timing side-channel elimination on auth, LokiJS metadata stripping from all API responses
- Production image: wget/nc removed, zlib upgraded, npm stripped
Home Assistant / MQTT
- HASS discovery with
entity_pictureauto-resolution from container icons - Attribute filtering —
short(default) andfullpresets dd.display.picturelabel for direct entity picture URL override
Container Operations
- Update, rollback, scan, start/stop/restart with confirmation dialogs
- Compose trigger affinity — actions route to the correct compose trigger
- Group operations with per-container progress feedback
More Highlights
- Self-update controller — automated Drydock self-update via Docker trigger
- Tag-family semver —
dd.tag.transformregex rewriting for non-standard versioning - OpenAPI 3.1.0 — full spec at
GET /api/openapi.json - mTLS client certificates —
CLIENTCERT/CLIENTKEYregistry options - Audit log for external state changes — container start/stop/restart via Portainer or CLI
Breaking Changes
MQTT
HASS_ATTRIBUTESdefault changed fromfulltoshortThis excludes large SBOM documents, scan vulnerabilities, details, and labels from Home Assistant entity payloads. To retain the previous behavior:
DD_TRIGGER_MQTT_{name}_HASS_ATTRIBUTES=full
Migration from v1.3.9
Drop-in upgrade — pull the new image and restart. Legacy v1.3.9 password hashes ({SHA}, $apr1$, crypt, plaintext) are accepted with a deprecation banner. Upgrade to argon2id at your convenience; legacy hash support is removed in v1.6.0.
docker pull codeswhat/drydock:1.4.0See the full CHANGELOG for the complete list of changes.
v1.4.0-rc.12
v1.4.0-rc.12
60+ commits since rc.11 — bug fixes from community testers, new features, UI polish, and security hardening.
Bug Fixes
- Compose directory resolution —
DD_TRIGGER_DOCKERCOMPOSE_*_FILEnow accepts a directory path and auto-discoverscompose.yaml/docker-compose.ymlinside it (#84) - docker.io prefix preserved — Compose mutations no longer strip the explicit
docker.io/registry prefix from image refs - Lowercase env var keys — Compose trigger config like
composefileonce,digestpinning,reconciliationmodenow accepted in any case - Legacy hash login on upgrade — SHA-1, APR1, DES crypt, and plaintext htpasswd hashes from v1.3.x are now accepted during upgrade so you can log in and migrate to argon2id
- TLS healthcheck — Container healthcheck now uses HTTPS when
DD_SERVER_TLS_ENABLED=true - Log level propagation —
DD_LOG_LEVEL=debugnow properly propagates to all log destinations (#134) - Feature flags after login — Container action buttons no longer appear disabled after first login
- HASS entity_picture URL — Fixed broken entity picture in Home Assistant after logo rename (#138)
New Features
- MQTT HASS entity_picture from icons —
entity_pictureauto-resolved fromdd.display.iconlabels (sh:, hl:, si: prefixes) dd.display.picturelabel — New container label to override the HASS entity picture URL directly- PHC argon2id hashes — Basic auth now accepts standard PHC-format argon2id hashes (
$argon2id$v=19$...) - Config tab URL deep-linking — Config view tab selection syncs to URL query params for shareable links
- mTLS client certificate support — Registries now support mutual TLS via
CLIENTCERT/CLIENTKEYoptions - Container-update audit events — External container lifecycle changes are now recorded in the audit log
UI Polish
- Borderless redesign across all views, config tabs, and detail panels
- Dashboard version column left-aligned
- Detail panel expand button redesigned with frame-corners icon
- Font sizes converted from px to rem
Security
- Unsupported hash formats now fail closed (no plaintext fallback)
- PostMessage origin validation in service worker and demo
- HASS_ATTRIBUTES default preset changed to
short(less data exposed)
Full changelog: https://github.com/CodesWhat/drydock/blob/main/CHANGELOG.md
Configuration docs: https://drydock.codeswhat.com/docs/configuration
docker pull codeswhat/drydock:1.4.0-rc.12v1.4.0-rc.11
Highlights
Fixed
- Bouncer-blocked state in container detail views — Full-page and side panel detail views now show a red "Blocked" button with lock icon when a container's target image is blocked by the security bouncer, replacing the misleading green "Update" button. Force-update flow with confirmation dialog wired through all four detail components.
Changed
- Clean-tree gate in pre-push pipeline — New priority-0 lefthook step rejects pushes when the working tree has untracked files, uncommitted changes, or stashed changes. Prevents qlty from hanging on interactive "Format these files?" prompts and catches the common case where local tests pass against uncommitted changes that CI will never see.
QA / DevEx
- Cosign signature verification disabled in QA —
DD_SECURITY_VERIFY_SIGNATURES=falsein qa-compose.yml allows update flow testing without cosign-signed images. - Mosquitto broker and icon test labels — QA environment expanded with MQTT broker container and icon display label coverage.
- Snyk removed from lefthook — Snyk scans are now CI-only (release workflow) to preserve the 200/month API quota.
Full changelog: https://github.com/CodesWhat/drydock/blob/main/CHANGELOG.md
v1.4.0-rc.9
Fixed
- Silent error on recheck failure — "Recheck for Updates" button now displays an error banner when the backend request fails instead of silently stopping the spinner with no feedback. This was a regression from v1.3.9 where the error toast was lost during the Vue 3 rewrite.
- Silent error on env reveal failure — Environment variable reveal in the container detail panel now shows an inline error message when the API call fails instead of silently failing.
Full changelog: CHANGELOG.md
v1.4.0-rc.8
Highlights
- Deprecation warnings: All deprecated features now log warnings with
v1.6.0removal targets — OIDC HTTP discovery, legacy trigger templates (${name},${count}), Dockerwatchatstartenv var, unversioned/api/*path, WUD env vars, CORS wildcard origin, PUT settings endpoint - OIDC logouturl fallback: Providers without
end_session_endpointnow fall back to the configuredlogouturl - Trigger error suppression: Repeated identical trigger errors during bursts are suppressed to reduce log noise
- Compose trigger hardening: File lock manager, validation, reconciliation, batch mode support
- Identity-aware rate limiting: Rate limit keys now include authenticated user identity for shared proxy deployments
- Advisory-only security scanning: New
DD_SECURITY_BLOCK_SEVERITY=NONEmode for scan-without-block - UI compose preview: File path display and preview details for compose-managed containers
- Reactive server feature flags: Composable for SSE-driven feature flag updates
Bug Fixes
- Include container name in non-semver digest warnings
- Fix registry test mock path (was silently ignored since initial commit)
- Fix compose type assertions for ContainerImage
- Prune backups on failed updates and guard undefined maxCount
- Record failing new image as fromVersion in rollback audit entries
- Deduplicate server feature loads and preview normalization
- E2E: skip GHCR/LSCR containers when credentials unavailable
Test & Quality
- 3,959 backend tests, 1,575 UI tests (100% coverage thresholds)
- 665 lines of compose trigger edge case coverage
- Identity-aware rate limiter integration tests across all API routers
- Deprecation warning coverage for OIDC, triggers, watchatstart, API path
Full Changelog
See CHANGELOG.md for the complete list of changes.