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

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
This commit is contained in:
2026-09-21 20:52:56 -04:00
co-authored by Claude Sonnet 5
parent 32037b1190
commit a114a7d3d8
4 changed files with 85 additions and 10 deletions
+16 -3
View File
@@ -12,14 +12,27 @@ jobs:
steps:
- uses: actions/checkout@v4
# driver: docker (not the action's default docker-container driver) so buildx reuses the
# host's own dockerd instead of spinning up an isolated builder container — the isolated
# one doesn't see the host's /etc/docker/certs.d, which is how the login step below trusts
# the registry's self-signed cert (docs/DECISIONS.md D17). We don't need multi-platform
# builds, so nothing the docker-container driver offers is actually lost here.
- uses: docker/setup-buildx-action@v3
with:
driver: docker
# secrets.GITEA_TOKEN cannot push to the Gitea container registry — a documented Gitea
# limitation, not a misconfiguration (see CLAUDE.md). REGISTRY_TOKEN is a separate PAT with
# package:write, expected to already exist as a repo secret.
#
# registry.bbergle.com:9537, not the raw 192.168.0.3:3000 Gitea talks HTTP on directly —
# Docker refuses any non-localhost registry over plain HTTP by default. This hostname is an
# NPMplus proxy host in front of Gitea's registry, terminating TLS with a self-signed cert;
# the runner host trusts it via /etc/docker/certs.d/registry.bbergle.com:9537/ca.crt (not
# committed here — host-local trust material, docs/DECISIONS.md D17 has the full setup).
- uses: docker/login-action@v3
with:
registry: 192.168.0.3:3000
registry: registry.bbergle.com:9537
username: BBergle
password: ${{ secrets.REGISTRY_TOKEN }}
@@ -38,5 +51,5 @@ jobs:
file: Dockerfile
push: true
tags: |
192.168.0.3:3000/bbergle/bike-app:latest
192.168.0.3:3000/bbergle/bike-app:${{ steps.tag.outputs.value }}
registry.bbergle.com:9537/bbergle/bike-app:latest
registry.bbergle.com:9537/bbergle/bike-app:${{ steps.tag.outputs.value }}