groot 63d514e50d
release-tag / release-image (push) Successful in 2m43s
Update
2026-09-01 14:48:01 +02:00
2026-08-31 17:09:21 +02:00
2026-09-01 06:31:41 +02:00
2026-09-01 06:31:55 +02:00
2026-09-01 14:48:01 +02:00
2026-09-01 14:48:01 +02:00
2026-08-31 22:34:50 +02:00
2026-09-01 06:31:41 +02:00
2026-08-31 22:34:50 +02:00
2026-09-01 06:31:41 +02:00
2026-09-01 13:59:25 +02:00
2026-08-31 22:17:18 +02:00
2026-08-31 17:09:21 +02:00
2026-08-31 22:28:26 +02:00
2026-09-01 14:48:01 +02:00
2026-08-31 17:09:21 +02:00

Dockwatch v9.5.3

Go module: git.send.nrw/sendnrw/dockwatch

Dockwatch is a single-binary Go control plane for Docker Compose, Docker resources and uptime monitoring. It combines Dockge/Dockhand-style operational workflows with Uptime-Kuma-style monitoring while keeping its own implementation and UI.

The same binary runs as standalone, master or agent. SQLite uses modernc.org/sqlite, so the application itself builds with CGO_ENABLED=0.

v9.5.3 deutsche Weboberfläche

  • die Weboberfläche ist nun durchgängig deutsch beschriftet; interne API-/Compose-Werte bleiben unverändert
  • Navigation, Compose-Designer, Monitoring, Dienste, Statusseiten, Docker-Ressourcen, Git, Benachrichtigungen und Host-Sicherheit wurden sprachlich vereinheitlicht
  • Status- und Rollenwerte werden im UI deutsch dargestellt, ohne die API-Werte (up, down, admin, operator usw.) zu verändern
  • die öffentliche Statusseite ist ebenfalls deutsch
  • häufige serverseitige Diagnosemeldungen werden für die Anzeige im WebUI verständlich ins Deutsche übertragen
  • statische Assets verwenden v=9.5.3 zur sicheren Cache-Aktualisierung

v9.5.1 UI / Compose editor fixes

  • Compose scalar edits no longer re-render the complete visual tree after every keystroke, so text/port fields keep focus while typing. Structural changes (add/remove/type changes) still re-parse the YAML AST.
  • Compose designer controls now use the application theme instead of browser-default white form controls in dark mode.
  • Stack container cards format Compose publisher JSON into readable port mappings and wrap long image/command values safely.
  • Docker inventory tables now have horizontal overflow handling, sensible column widths, compact label summaries, and a sticky action column so buttons are no longer squeezed off-screen.
  • Static assets are cache-busted to v9.5.1.

v9.5 firewall-provider layer

  • Host Security firewall management now uses a provider model: Auto detect / UFW / firewalld / native nftables
  • Auto detect adopts an already-active UFW or firewalld frontend instead of refusing all changes simply because one exists
  • multiple truly competing active frontends are still treated as a hard conflict
  • UFW rules are added with deterministic dockwatch: comments and Dockwatch removes only those managed rules; it never runs ufw reset
  • firewalld uses the selected native zone and managed rich rules while preserving unrelated services, ports, sources and rich rules
  • native nftables keeps the isolated table inet dockwatch model and never flushes the global ruleset
  • existing provider state/rules are displayed read-only in the firewall editor before changes are applied
  • provider selection, default inbound management, firewalld zone selection, ALLOW/DENY/REJECT/LIMIT rules and rule reordering are available in the unified UI
  • provider changes retain the timed rollback/explicit commit safety model; rollback restores the previous Dockwatch-managed policy and provider default snapshot where applicable
  • package installation/upgrade now installs the selected firewall frontend (ufw, firewalld or nftables) rather than always installing nftables

v9.4.1 fixes

  • fixed monitor creation when no monitor is selected (state.monitor == null)
  • static UI assets are served with Cache-Control: no-store, preventing stale frontend code after upgrades
  • Compose visual-editor patches now use a real queue so rapid edits on different fields are not lost
  • the Volumes section now reconciles every service mount with top-level volumes: declarations
  • named volumes missing a top-level declaration can be added individually or with Add missing declarations
  • bind mounts, anonymous mounts and dynamic mounts are shown in the reconciliation view but are never silently converted into named volumes
  • unused top-level volume declarations are highlighted and can be removed explicitly without deleting the Docker volume itself

What is included

Compose / stack management

  • multiple Compose stacks per environment
  • local Docker plus remote agents
  • staged docker compose config --quiet validation before a save
  • atomic managed-file writes and rollback on save failure
  • full bidirectional Compose designer backed by a YAML AST
  • recursive editing of all YAML maps/arrays/scalars, including unknown/future Compose fields
  • compose.yaml, root .env, envs/, secrets/ and configs/
  • Up / Start / Stop / Restart / Down / Pull / Update / Force recreate
  • service/container status
  • live SSE logs with pause, follow, filter and download
  • interactive PTY/WebSocket docker compose exec terminal
  • normalized service/dependency/network/volume graph from docker compose config --format json
  • registry digest based image-update checks
  • safe stack deletion: only Dockwatch-managed definition files are removed by default
  • explicit, typed-name confirmation for full stack-folder purge

The editor keeps unsaved drafts in browser storage. Background refresh never overwrites a dirty editor.

Git-backed stacks

Git sources support:

  • local or remote-agent environment
  • repository, branch, workdir and Compose filename
  • manual sync
  • optional deploy after sync
  • signed webhooks (X-Hub-Signature-256, X-Gitlab-Token or X-Webhook-Token)
  • encrypted webhook secret at rest
  • last commit / last sync / last error

A Git sync is now managed-file based. Dockwatch stores a small .dockwatch/git-manifest.json in the stack directory and only replaces/removes files that belong to the Git checkout. Unrelated runtime or bind-mount data beside the Compose project is preserved. Syncs of the same source are serialized and a failed apply rolls back the touched file set.

Symlink stack destinations and symlink paths inside Git-managed writes are rejected.

Docker resources

Containers

  • list/filter
  • start / stop / restart / force-remove
  • operator-only inspect
  • one-shot CPU/memory/network/block stats

Container identity / host UID-GID checks

Container rows include an Identity action. Dockwatch inspects the selected container and reports:

  • configured Compose/image user and the effective runtime UID/GID where resolvable
  • whether the process currently runs as UID 0
  • a conservative root assessment based on privileged, Docker socket mounts, passed-through devices and added Linux capabilities
  • bind-mount sources and their host UID/GID ownership when host access is configured
  • single-container detail checks plus a throttled Identity audit across all containers in the selected environment
  • whether the container UID/GID already maps to a local host account/group

Dockwatch deliberately does not claim that a root container can always be converted to non-root. Application-internal filesystem permissions, entrypoints and image-specific PUID/PGID conventions cannot be proven from Docker metadata alone. It also never rewrites Compose user: automatically.

A matching local host username is not required by Docker. Linux file ownership is numeric; creating a host account can nevertheless make bind-mount ownership, backups and administration easier.

Host inspection is opt-in. For read-only inspection, set:

HOST_ROOT=/host
ALLOW_HOST_USER_MANAGEMENT=false
ALLOW_HOST_PERMISSION_MANAGEMENT=false

and mount the host root read-only at /host. examples/compose-host-identity.override.yml shows this setup.

Admins may optionally create a locked/non-login local host account using the container's server-side re-resolved UID/GID. This requires both a writable host-root mount and:

ALLOW_HOST_USER_MANAGEMENT=true

See examples/compose-host-user-management.override.yml. The browser cannot supply an arbitrary UID/GID: Dockwatch re-inspects the container immediately before the change and derives the IDs itself. Existing numeric users/groups are reused and UID/name collisions are refused. Docker rootless/user-namespace remapping is detected where possible; automatic same-numbered host-account creation is refused when IDs are remapped. This operation is intentionally admin-only and disabled by default.

Identity & Bind Mount Permissions

Dockwatch can now diagnose the actual bind-mount permission problem instead of stopping at "container runs as UID X". The container Identity dialog and each stack's Permissions tab show, per bind mount:

  • effective PID 1 UID/GID and a separate expected bind UID/GID
  • PUID/PGID or USER_ID/GROUP_ID when the image exposes those paired conventions
  • host owner UID/GID and POSIX mode bits
  • static writeability (w+x for directories, w for files)
  • extended POSIX ACL detection when getfacl is available
  • an optional non-mutating runtime test -w using the expected numeric identity
  • read-only mounts, rootless/userns remapping and unsafe symlinked host paths as hard repair blockers

The repair flow is Analyze → Preview → Repair → Verify. For recursive ownership repair Dockwatch scans the tree first and shows how many files/directories differ. Automatic recursive repair is refused above 200,000 entries. Symlinks are never followed or chowned. :ro mounts are never repaired automatically.

Permission repair is a separate high-trust opt-in from host-user creation:

HOST_ROOT=/host
ALLOW_HOST_PERMISSION_MANAGEMENT=true

and / must intentionally be mounted read-write at /host. See examples/compose-host-permissions.override.yml. The browser supplies only the container and its mount destination (for example /config); the backend re-reads docker inspect and resolves the real host source itself. Arbitrary host paths and arbitrary UID/GID values cannot be submitted for repair.

Ownership repair can operate on only the bind root or recursively. chmod is separate, optional, explicit, and only applies to the bind root; Dockwatch never automatically applies chmod 777 and never recursively rewrites modes. After a repair Dockwatch re-runs the ownership/writeability analysis and reports the result.

Images

  • list/filter
  • pull / remove / prune
  • registry login/logout
  • persistent Docker auth via DOCKER_CONFIG=/data/docker-config

Volumes

  • list/filter
  • create / remove / prune
  • driver and labels

Networks

  • list/filter
  • create / remove / prune
  • driver, labels, internal, attachable

Docker positional arguments and Compose service names are validated before invoking the CLI so option-like values cannot be interpreted as Docker CLI flags.

Host Security layer

Dockwatch can optionally act as a host-security control plane for the selected local or remote-agent environment. The feature is disabled by default and uses three independent capabilities so that audit, configuration changes and package management can be granted separately.

The System → Host Security page provides a posture overview and managed workflows for:

Firewall (Auto / UFW / firewalld / nftables)

  • Auto detect adopts the already-active host firewall frontend: UFW first when it is the sole active frontend, firewalld when it is the sole active frontend, otherwise native nftables is used when available
  • an explicit provider can be selected when you intentionally want to migrate or standardize a host
  • only genuinely competing active frontends are treated as conflicts; for example UFW + firewalld, or UFW + an already-loaded Dockwatch nftables table
  • the editor shows installed/active frontends plus the provider's existing runtime rules/state before any mutation
  • common managed policy supports trusted IPv4/IPv6 CIDRs and ordered TCP/UDP ALLOW / DENY / REJECT / LIMIT rules
  • provider-global default inbound management is an explicit opt-in for UFW/firewalld; nftables keeps its default policy inside Dockwatch's own table
  • UFW: Dockwatch uses native ufw commands, tags its rules with deterministic dockwatch: comments and removes only those tagged rules; it never runs ufw reset and preserves foreign UFW rules
  • firewalld: Dockwatch targets a selected zone, uses native rich rules, and preserves unrelated zone services/ports/sources/rich rules; default zone target changes are opt-in
  • nftables: Dockwatch continues to own only table inet dockwatch, validates with nft -c, never runs flush ruleset, and does not alter Docker NAT/FORWARD chains
  • when an enabled policy is applied to an inactive UFW/firewalld provider, Dockwatch activates the selected frontend inside the rollback window; rollback restores the previous active state
  • timed rollback (30–600 seconds, UI default 90 seconds) after apply; changes must be explicitly kept after management connectivity is verified
  • package installation/upgrade uses the selected provider package instead of always installing nftables
  • browser clients never submit arbitrary firewall command text; the backend renders and executes only the typed policy model

Fail2Ban

  • package/runtime/boot status
  • package installation/upgrade when separately enabled
  • managed global ban/find/max-retry/backend settings
  • ignore IP/CIDR list
  • configurable jails with filter, port, backend, log path and per-jail retry threshold
  • server-side fail2ban-client -t validation before activation/reload
  • Dockwatch owns only /etc/fail2ban/jail.d/dockwatch.local; distro and administrator configuration is preserved

Linux Audit (auditd)

  • package/runtime/boot status
  • managed watches for identity files, sudoers, SSH configuration, Docker socket/configuration, systemd units and kernel-module configuration
  • additional explicitly configured file watches
  • path/key/permission validation
  • augenrules --check validation and augenrules --load activation
  • Dockwatch owns only /etc/audit/rules.d/90-dockwatch.rules; unrelated audit rules remain untouched

Installation and maintenance

  • install or upgrade the selected firewall provider (ufw, firewalld or nftables), fail2ban and auditd/audit using the detected host package manager
  • supported package-manager families: apt, dnf, yum, zypper, apk and pacman
  • enable, disable, restart and (where meaningful) reload the corresponding host services
  • current package/service/config-drift information in the UI
  • backups of Dockwatch-managed host configuration before replacement
  • all mutation endpoints are administrator-only and flow through Dockwatch's existing origin/CSRF guard and activity audit log

Dockwatch intentionally manages its own drop-in/configuration scope rather than rewriting the host's entire security configuration. It is a focused administration layer, not a replacement for a complete CIS/STIG benchmark, SELinux/AppArmor policy management, an enterprise EDR, or distro-specific security tooling.

Capability modes

Read-only file/configuration audit:

services:
  dockwatch:
    environment:
      HOST_ROOT: /host
      HOST_SECURITY_ENABLED: "true"
      ALLOW_HOST_SECURITY_CHANGES: "false"
      ALLOW_HOST_PACKAGE_MANAGEMENT: "false"
    volumes:
      - /:/host:ro

A ready-to-use example is examples/compose-host-security-audit.override.yml. In this mode Dockwatch cannot mutate the host. Runtime/service checks that require entering the host namespaces may be unavailable and are reported as such.

Full host-security management is intentionally high privilege:

services:
  dockwatch:
    pid: host
    privileged: true
    environment:
      HOST_ROOT: /host
      HOST_SECURITY_ENABLED: "true"
      ALLOW_HOST_SECURITY_CHANGES: "true"
      ALLOW_HOST_PACKAGE_MANAGEMENT: "true"
      HOST_SECURITY_HOST_PID: "1"
    volumes:
      - /:/host:rw

See examples/compose-host-security.override.yml. Dockwatch verifies that HOST_ROOT and /proc/<HOST_SECURITY_HOST_PID>/root refer to the same host before enabling its namespace executor. Host commands are executed through nsenter in the target host namespaces; the browser can select only predefined operations and cannot submit arbitrary shell commands.

Because this mode grants Dockwatch broad host-administration capability, use OIDC, restrict the admin role carefully, protect the Dockwatch database/APP_SECRET, and do not expose an agent token or the UI to untrusted networks.

The same security APIs are available through the existing master/agent relay, so each agent can audit/manage its own host when that agent has been configured with the appropriate host-security capability. A master does not silently inherit host privileges on an agent.

Monitoring

Probe types:

  • HTTP(S)
  • TCP
  • DNS
  • Docker container running state
  • Docker container running + optional healthy requirement

Monitor lifecycle:

  • create / edit / delete
  • pause / resume
  • manual or timed maintenance
  • maintenance notes
  • manual Check now
  • interval and timeout
  • HTTP method and accepted status range
  • request headers/body
  • keyword / inverted keyword assertion
  • optional HTTP TLS verification bypass
  • local or remote-agent execution
  • heartbeat history
  • last latency/status message
  • 24-hour uptime
  • retention cleanup

The scheduler uses a lightweight monitor query and does not recompute 24-hour uptime statistics every two seconds. Manual checks are serialized with scheduled checks and do not accidentally resume paused/maintenance monitors. Shutdown-cancelled checks are not persisted as false outages.

Services and public status pages

Probes can be grouped into user-facing Services. Aggregation is strict:

  • any probe down -> Service down
  • otherwise maintenance -> Service maintenance
  • pending/paused states are retained
  • otherwise Service up

Service dialogs can assign/unassign probes directly.

Admins can publish selected Services on public pages:

/status/<slug>
/public/api/status/<slug>

The public JSON API uses a dedicated DTO and exposes only public status information (name, status, uptime, latency and last-check timestamp), not targets, node IDs, request headers, bodies or credentials. HTML/JSON status responses are not cached.

Notifications

Providers:

  • generic JSON webhook
  • ntfy
  • Gotify
  • SMTP

SMTP supports:

  • STARTTLS
  • implicit SSL/TLS
  • None
  • authentication on/off independently of TLS
  • optional certificate-verification bypass for private/self-signed infrastructure

SMTP connections inherit the notification deadline after connect as well, so a stalled server cannot leave a delivery goroutine hanging indefinitely. SMTP/password/token/secret values are AES-GCM encrypted at rest. Notification configuration is admin-only in both API and UI.

PocketID / OIDC and roles

Roles are mapped from OIDC/PocketID groups:

  • viewer – dashboards/status/inventory, sanitized monitor configuration
  • operator – stack configuration/logs/terminal, Docker actions, monitor/service operations, Git stacks
  • admin – environments, notifications, status-page administration and audit log

Viewer API responses do not expose monitor request headers/body/keywords. Stack definition detail and live logs require Operator access because .env, secrets and runtime logs may contain sensitive data.

Required OIDC setup:

AUTH_DISABLED=false
BASE_URL=https://dockwatch.example.com
OIDC_ISSUER=https://id.example.com
OIDC_CLIENT_ID=...
OIDC_CLIENT_SECRET=...
APP_SECRET=replace-with-at-least-32-random-characters
OIDC_ADMIN_GROUP=dockwatch-admins
OIDC_OPERATOR_GROUP=dockwatch-operators

Redirect URI:

https://dockwatch.example.com/auth/callback

OIDC discovery, token exchange and verification are bounded by HTTP_TIMEOUT_SECONDS. Session/state cookies are HttpOnly, SameSite=Lax and become Secure when BASE_URL uses HTTPS.

Master / agent

Modes:

APP_MODE=standalone
APP_MODE=master
APP_MODE=agent

An agent exposes only /agent/v1/* and requires an AGENT_TOKEN of at least 24 characters. Agent tokens are AES-GCM encrypted in the master's SQLite database.

Remote-capable features include:

  • stacks and actions
  • logs and PTY terminal
  • Compose graph
  • image update checks
  • containers/images/networks/volumes
  • container identity analysis, bind-mount permission repair and optional host-account creation on the agent host
  • monitoring probes
  • Git clone/sync/deploy
  • host-security audit/management when explicitly enabled on that agent

See examples/compose-master.yml and examples/compose-agent.yml.

Full Compose designer

The Compose tab uses two synchronized representations:

  1. the raw YAML source of truth
  2. a recursive visual designer

YAML changes are parsed after a short debounce. Visual changes patch the selected YAML AST path instead of reserializing a simplified Compose model. Unknown keys, x-* extensions and comments are therefore preserved where possible. Invalid/incomplete YAML pauses visual synchronization and never overwrites the source editor.

The designer is not limited to a hard-coded subset: arbitrary maps, arrays and scalar types remain editable, including current/future Compose fields and long syntax objects.

Server-side save validation still uses Docker Compose itself after all related .env, secret, env-file and config files have been staged.

Reliability and security work in v9 / v9.2

The v9.2 identity extension is opt-in, admin-gated and preserves the existing least-surprise rule: diagnostics are read-only by default and no container user or host account is changed automatically.

The v9 review includes, among other changes:

  • fixed fresh-database migration ordering before monitor indexes are created
  • SQLite WAL/busy-timeout/foreign-key configuration with a small connection pool
  • strict environment parsing instead of silently accepting invalid numeric/boolean values
  • graceful HTTP shutdown and sensible server timeouts
  • security headers and same-origin checks for browser mutations
  • request JSON size limit and single-value decoding
  • admin-only audit activity and notification configuration
  • audit retention cleanup
  • public-status DTO that does not leak internal monitor configuration
  • safe IP parsing for audit entries
  • sensitive viewer responses reduced
  • Compose save snapshot/rollback
  • safe stack delete vs. explicit purge
  • symlink protection on stack/Git file paths
  • atomic managed-file writes
  • Git sync serialization and managed-file manifest
  • Git copy file-descriptor leak fixed
  • Node URL validation rejects credentials/query/fragment
  • remote terminal WebSocket URL/query handling fixed
  • registry/Docker CLI positional-argument validation
  • scheduler query and shutdown behaviour improved
  • defensive frontend collection handling (null cannot break list pages)
  • admin-only navigation entries hidden for non-admin users
  • persisted dark/light theme and collapsible/mobile sidebar
  • API connectivity indicator and manual refresh
  • denser Docker/monitor/service tables and better empty/error states

Configuration

.env.example contains the defaults. Important values:

APP_MODE=standalone
LISTEN_ADDR=:8080
BASE_URL=http://localhost:8080
DATA_DIR=/data
STACKS_DIR=/stacks
AUTH_DISABLED=true
APP_SECRET=change-me-change-me-change-me-32bytes
CHECK_CONCURRENCY=8
CHECK_RETENTION_DAYS=30
HTTP_TIMEOUT_SECONDS=10
AUDIT_RETENTION_DAYS=180
HOST_ROOT=
ALLOW_HOST_USER_MANAGEMENT=false
ALLOW_HOST_PERMISSION_MANAGEMENT=false
HOST_SECURITY_ENABLED=false
ALLOW_HOST_SECURITY_CHANGES=false
ALLOW_HOST_PACKAGE_MANAGEMENT=false
HOST_SECURITY_HOST_PID=1

AUTH_DISABLED=true is for local development only. Do not expose that configuration publicly.

Run with Docker Compose

cp .env.example .env
docker compose up -d --build

Runtime mounts normally include:

/data                       SQLite, Docker registry config
/stacks                     Compose projects
/var/run/docker.sock        Docker Engine access

Giving Dockwatch access to the Docker socket grants highly privileged control of that Docker host. Protect the UI and agent endpoint accordingly.

v9.3.1 build-context fix

v9.3 accidentally used the broad ignore pattern dockwatch in both .gitignore and .dockerignore. Because patterns without a slash match path components recursively, that could hide cmd/dockwatch/ from Git and from the Docker build context. v9.3.1 removes that pattern, writes local Makefile builds to bin/dockwatch, ignores only bin//dist/, and makes the Dockerfile fail early with a clear message if cmd/dockwatch/main.go is ever missing from the build context.

Build from source

The pinned OIDC/OAuth2 releases require Go 1.25. The Docker build uses golang:1.25-alpine.

go mod tidy
go test ./...
CGO_ENABLED=0 go build ./cmd/dockwatch

Build metadata can be injected through the supplied Makefile/Dockerfile (VERSION, COMMIT, BUILD_DATE) and is visible in /healthz and the UI.

Database

SQLite database:

/data/dockwatch.db

modernc.org/sqlite is used, so no SQLite CGO binding is required. Migrations are additive and include users/sessions, nodes, monitors/checks/services, public status pages, audit events, notification channels and Git sources.

Verification for this archive

The artifact-building environment cannot reach proxy.golang.org, so it cannot download the real external modules or generate a trustworthy go.sum here. The repository intentionally does not ship fake checksums or test stubs.

For quality control, the project is copied into a temporary test workspace where API-compatible local stubs replace only the external dependencies. Those stubs are not included in the ZIP. The checks used for this source snapshot include:

# all packages type/compile checked with temporary external-module stubs
go test -run='^$' ./...

go test ./internal/config ./internal/gitops ./internal/httpapi \
        ./internal/monitor ./internal/nodes ./internal/notify ./internal/stacks ./internal/hostsecurity

go vet ./...
go test -race ./internal/config ./internal/gitops ./internal/httpapi ./internal/monitor ./internal/nodes ./internal/notify ./internal/stacks ./internal/hostsecurity
node --check web/app.js

The SQLite migration SQL is additionally smoke-tested against Python's SQLite engine because the temporary modernc.org/sqlite stub does not implement a real SQL driver.

On a normal networked development machine or during docker build, run go mod tidy && go test ./... once against the real pinned dependencies.

Module metadata / go mod tidy

The Docker builder runs go mod tidy after the full source tree has been copied and before compiling. This is intentional: Go 1.17+ module graph pruning may require transitive dependencies to be recorded as indirect requirements once the actual imported package graph is known. A checkout with an older/incomplete go.mod or without go.sum therefore still builds reproducibly in CI instead of failing late with updates to go.mod needed.

For repository maintenance, run:

go mod tidy
git add go.mod go.sum
git commit -m "chore: tidy Go modules"

CI can use make verify to fail when go.mod/go.sum are not committed in tidy form.

v9.3.2 module-build fix

v9.3.2 fixes Docker/CI builds that stopped at go: updates to go.mod needed; to update it: go mod tidy. The builder now runs go mod tidy after the complete source tree has been copied and before go build, so indirect requirements required by Go module graph pruning are materialized in the build stage. The Makefile also includes tidy and verify targets for maintaining committed go.mod/go.sum files.

Build-context note (v9.3.3)

Runtime directories in .dockerignore and .gitignore are root-anchored (/stacks/, /data/, /bin/, /dist/). This is intentional: unanchored patterns such as stacks/ also match the source package internal/stacks/ and can make Go try to resolve the project's own internal package as a remote module during go mod tidy.

v9.5.2 UI polish

  • Firewall rule editor uses a wide responsive modal and keeps long CIDRs, comments and provider output inside the dialog.
  • Security details and notices wrap long unbroken values safely.
  • Light mode now has consistent navigation, buttons, inputs, tables, tabs, code/editor surfaces, notices, modals and Host Security cards instead of inheriting dark-only hard-coded colors.
S
Description
No description provided
Readme
801 KiB
Languages
Go 98.4%
HTML 0.7%
Dockerfile 0.4%
PowerShell 0.3%
Makefile 0.2%