fix(deploy): push through a TLS-terminating proxy, not raw Gitea HTTP #9

Merged
BBergle merged 3 commits from fix/deploy-registry-tls into main 2026-09-21 22:15:05 -04:00
Owner

Re-targets #8's commits at main directly — that PR was accidentally based on fix/deploy-unraid-template-port (PR #7's branch), and by the time it merged, #7 had already been merged into main separately. Merging #8 into a branch that was no longer connected to main meant none of it actually landed there, even though Gitea reported it as merged. Caught by checking main's actual release.yml content against what should have been there — it still had the plain-HTTP 192.168.0.3:3000 registry address.

Nothing was lost — both branches were still on the remote with commits intact. This PR is the same 3 commits from #8 (verified via the compare API: exactly a114a7d3, 45719f2, 6b0f28c, nothing more, nothing less, no duplication with what #7 already merged), now based on current main directly.

Content-wise this is unchanged from #8: the D17 registry-TLS fix (self-signed cert + NPMplus + certs.d + buildx driver:docker), the main-push release trigger with corrected latest-tag handling, and the /data uid/gid docs note. See #8 for the original description and verification notes — all still accurate, nothing here is new work.

🤖 Generated with Claude Code

Re-targets #8's commits at `main` directly — that PR was accidentally based on `fix/deploy-unraid-template-port` (PR #7's branch), and by the time it merged, #7 had *already* been merged into `main` separately. Merging #8 into a branch that was no longer connected to `main` meant none of it actually landed there, even though Gitea reported it as merged. Caught by checking `main`'s actual `release.yml` content against what should have been there — it still had the plain-HTTP `192.168.0.3:3000` registry address. Nothing was lost — both branches were still on the remote with commits intact. This PR is the same 3 commits from #8 (verified via the compare API: exactly `a114a7d3`, `45719f2`, `6b0f28c`, nothing more, nothing less, no duplication with what #7 already merged), now based on current `main` directly. Content-wise this is unchanged from #8: the D17 registry-TLS fix (self-signed cert + NPMplus + certs.d + buildx driver:docker), the main-push release trigger with corrected latest-tag handling, and the /data uid/gid docs note. See #8 for the original description and verification notes — all still accurate, nothing here is new work. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
BBergle added 3 commits 2026-09-21 22:13:54 -04:00
fix(deploy): push through a TLS-terminating proxy, not raw Gitea HTTP
CI / Repo hygiene (pull_request) Successful in 2s
CI / Web (lint, typecheck, build) (pull_request) Successful in 16s
CI / Migrations reversible (pull_request) Successful in 6s
CI / API (lint, types, tests) (pull_request) Successful in 54s
a114a7d3d8
release.yml's first real run failed: docker/login-action against
192.168.0.3:3000 hit "server gave HTTP response to HTTPS client" — Docker
refuses any non-localhost registry over plain HTTP by default, so this was
never actually a workflow bug.

Rejected insecure-registries in daemon.json after reading this Unraid host's
own rc.docker script: applying it needs a full dockerd restart, and with
Live Restore disabled here, that stops every one of the ~40 other containers
on the box first. Also rejected a real Let's Encrypt cert on a public
bbergle.com subdomain — this host's other subdomains are Cloudflare-proxied,
which would terminate TLS at Cloudflare's edge and never reach our own cert
at all.

Chosen instead, scoped to touch nothing already working: a self-signed cert
for registry.bbergle.com behind a new NPMplus proxy host (found its real
HTTPS port, 9537, by reading `docker port NPMplus` rather than assuming 443,
which is a different nginx process on this box entirely); an /etc/hosts
entry on the Unraid host so only that host needs to resolve the name (no
DNS record, no router/NAT dependency); and its CA dropped into
/etc/docker/certs.d, which Docker's own docs confirm is read per-connection
with no daemon restart required. Also pins buildx to driver: docker instead
of setup-buildx-action's default docker-container driver, which runs an
isolated builder that doesn't see /etc/docker/certs.d and would have quietly
defeated all of the above.

Full record, including what was rejected and why, in docs/DECISIONS.md D17.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R2ZKeWkZV7ehf7fivrAkkG
feat(deploy): build+push release image on every merge to main
CI / Repo hygiene (pull_request) Successful in 3s
CI / Web (lint, typecheck, build) (pull_request) Successful in 22s
CI / Migrations reversible (pull_request) Successful in 10s
CI / API (lint, types, tests) (pull_request) Successful in 1m4s
45719f284c
Was tag-push-or-manual-dispatch only. Adds a push:main trigger so main stays
continuously deployable without needing a version tag for every change.

Also fixes a real bug this surfaced while testing the D17 registry-TLS fix:
the old tag logic unconditionally retagged :latest on every run, including
manual test dispatches off a feature branch — one such dispatch, done while
verifying the previous commit, silently overwrote :latest with a
feature-branch build. Tag resolution now only moves :latest on an actual
main push or a version tag; a manual dispatch gets its own
manual-<timestamp>-<sha> tag and leaves :latest alone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R2ZKeWkZV7ehf7fivrAkkG
docs(deploy): note the /data uid/gid-mismatch trap on first start
CI / Repo hygiene (pull_request) Successful in 2s
CI / Web (lint, typecheck, build) (pull_request) Successful in 14s
CI / Migrations reversible (pull_request) Successful in 6s
CI / API (lint, types, tests) (pull_request) Successful in 54s
6b0f28cf74
Hit this deploying to the real Unraid host: the container runs as a fixed
non-root uid/gid (999), not root and not Unraid's usual nobody:users
(99:100). A freshly-created appdata directory is owned by nobody:users with
no write access for anyone else, so the container starts but uvicorn fails
immediately with "unable to open database file" — not obvious from the
error alone, worth documenting once rather than re-debugging it later.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R2ZKeWkZV7ehf7fivrAkkG
BBergle merged commit 3b80034f0e into main 2026-09-21 22:15:05 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: BBergle/bike-app#9