Skip to content

Wave 4: deployment safety and CI (S4, B10, S7, A7, B11) - #91

Merged
coderbuzz merged 8 commits into
mainfrom
fix/wave4-deploy
Oct 15, 2026
Merged

coderbuzz merged 8 commits into
mainfrom
fix/wave4-deploy

Conversation

@coderbuzz

@coderbuzz coderbuzz commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Wave 4 of the Fable 5.1 audit (audits/DOCKIFY-AUDIT-FABLE-5.1.md §7): deployment safety and CI.

Changes

  • S4, fail closed on an open bind. config.CheckAuth (pure, tested): when DOCKIFY_ADMIN_PASSWORD is empty, the bind host is not loopback (127.0.0.1, ::1, localhost) and DOCKIFY_ALLOW_NO_AUTH is not true, serve exits with a message naming the three ways out. New Config.AllowNoAuth. install.sh requires the admin password in every mode; the .env it writes is unchanged otherwise. README (env table, "No password set", Docker Compose note: the image binds 0.0.0.0 and so needs the password or the override, build-from-source command) and SPEC updated. Extra: .air.toml defaults DOCKIFY_HOST to 127.0.0.1 and the AGENTS.md go run / docker run examples bind loopback, so the dev workflow keeps starting without a password (separate docs: commit).
  • B10, Docker Compose keys. Removed the ${HOME}/.ssh:/home/dockify/.ssh:ro mount and the DOCKIFY_SSH_KEY_DIR override; keys go to /var/lib/dockify/keys in dockify_data (created by config.Load and by the Dockerfile). README Option C explains it and how to fix an older compose file.
  • S7, self-update. RunUpdate writes no file: upgradeArgv (tested) builds systemd-run --no-block --unit=dockify-upgrade --collect --setenv=DOCKIFY_FORCE=y --setenv=DOCKIFY_VERSION=<tag> /bin/bash -c "set -o pipefail; sleep 3; curl -fsSL .../<tag>/scripts/update.sh | bash", where <tag> is the latest release from CheckUpdate (must match vX.Y.Z, otherwise refused). Output goes to journalctl -u dockify-upgrade instead of /tmp/dockify-update.log. The release workflow publishes dockify-linux-amd64.sha256; update.sh and update-latest.sh download it and run sha256sum -c before installing, aborting when it is missing (message says older releases have none) or does not match. update.sh honours DOCKIFY_VERSION so the binary matches the pinned script. Rollback logic unchanged.
  • A7, CI. build.yml now also runs on pull_request and push to main: go vet, gofmt -l (fails on output), go test -race, govulncheck, smoke test. Binary build, Docker push and release stay gated on refs/tags/v*. style: gofmt is a separate commit (2 files, whitespace only).
  • B11, managed Caddy. InitWorker inspects an existing caddy container (running or stopped) and only touches it when a mount source is /opt/dockify/caddy (current layout, prod-heavy-1) or /opt/dockify/caddy/config.json (old layout, staging), or it has dockify.managed=true; otherwise the server goes to error with "remove or rename it first". Decision in caddyManaged (tested with both production layouts, the label, foreign containers). New containers get --label dockify.managed=true and caddy:2 instead of caddy:latest (pull and run, both branches). Dev mock answers the new inspect. SPEC worker init flow updated.

CI now runs on this PR itself. The first run failed in govulncheck: setup-go picked the runner's cached go1.26.8, which has 12 stdlib vulnerabilities fixed in go1.26.9. check-latest: true fixes it (and puts the patched stdlib into released binaries); the second run (go1.26.9) passed every step: vet, gofmt, race tests, govulncheck (0 vulnerabilities), smoke test. The release job was skipped.

Verification

  • go build ./... && go vet ./... && go test -race -timeout 300s ./...: pass
  • gofmt -l .: empty; govulncheck ./...: no reachable vulnerabilities (Go 1.27.2 locally)
  • bash -n on install.sh, update.sh, update-latest.sh, smoke-test.sh: pass
  • bash scripts/smoke-test.sh: pass
  • Manual S4: no password on 0.0.0.0 exits 1 with the message; DOCKIFY_HOST=127.0.0.1 starts and /health is 200
  • sha256sum -c against a file produced by sha256sum <file> > <file>.sha256: OK, and FAILED after changing the file

Not verified

  • systemd-run self-update and update.sh checksum path on a real Linux host (no release with a .sha256 exists yet; the first one is the next tag). Until then update.sh from main aborts on binary installs with the "no checksum" message.
  • install.sh interactive runs, the Docker Compose stack, and InitWorker against real workers (both production layouts are covered only by the unit test with inspect JSON).
  • Production note: before upgrading the controller, nothing changes for S4 (password set). Existing compose installs must re-download docker-compose.yml for B10.

🤖 Generated with Claude Code

coderbuzz and others added 8 commits October 15, 2026 14:16
Dockify now exits at start when DOCKIFY_ADMIN_PASSWORD is empty and
DOCKIFY_HOST is not loopback, unless DOCKIFY_ALLOW_NO_AUTH=true.
install.sh requires the admin password in every mode; the Air and
go-run dev commands bind 127.0.0.1.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The compose file mounted ${HOME}/.ssh read-only and pointed
DOCKIFY_SSH_KEY_DIR at it, so adding a server failed to save its key.
Keys now go to /var/lib/dockify/keys in the dockify_data volume.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
RunUpdate no longer writes /tmp/dockify-upgrade.sh: it runs
systemd-run ... /bin/bash -c with update.sh fetched from the tag that
CheckUpdate found, and refuses when no tag is known. CI publishes
dockify-linux-amd64.sha256; update.sh and update-latest.sh verify the
binary with sha256sum -c and abort when the file is missing or wrong.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
InitWorker inspects an existing caddy container and treats it as
Dockify's only when it mounts /opt/dockify/caddy (current layout) or
/opt/dockify/caddy/config.json (old layout), or carries
dockify.managed=true; any other caddy container sets the server to
error. New containers get the label and caddy:2 instead of
caddy:latest.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The runner's cached go1.26.8 has 12 stdlib vulnerabilities fixed in
go1.26.9, so govulncheck failed; check-latest also puts the fix into
released binaries.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@coderbuzz
coderbuzz merged commit 9d12608 into main Oct 15, 2026
2 checks passed
@coderbuzz
coderbuzz deleted the fix/wave4-deploy branch October 15, 2026 07:29
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.

1 participant