Files
felhom-controller/REPORT.md
T

4.0 KiB

REPORT — Traefik scoped serversTransport for self-signed HTTPS backends (crafty 502 fix)

Repo: felhom-controller · Version: v0.82.0v0.83.0 · Date: 2026-06-26 Commit: 2d6df0f · Paired catalog commit: app-catalog-felhom.eu 1216a8a Deployed: guest 9201 (demo-felhom) on felhom-pve, golden/bootstrap mechanism.

Problem

The crafty-controller healthcheck fix (catalog 68ce009) un-withheld its Traefik route, exposing a pre-existing 502: Traefik proxied HTTP to Crafty's HTTPS-only self-signed backend on :8443. Crafty is the only catalog app with an HTTPS backend (all others serve plain HTTP, so Traefik's default HTTP transport works for them). In Traefik v3 insecureSkipVerify cannot be set via Docker labels — it must live in static/file config — so the fix necessarily touched the controller (which generates the Traefik config), not just the catalog.

Fix (Option B — scoped; verification stays ON by default)

A named serversTransport, opted into per-service — no global insecureSkipVerify.

  • internal/infra/infra.go — new pure RenderServersTransports() + exported const ServersTransportInsecure = "insecure-skip-verify". Emits:
    http:
      serversTransports:
        insecure-skip-verify:
          insecureSkipVerify: true
    
  • internal/stacks/infra.go — new ensureServersTransports(traefikDir) writes dynamic/serverstransports.yml (0644) idempotently (write-only-on-change, like wireController, so the traefik file-watcher doesn't reload each self-heal tick). Called from EnsureBaseStack outside ensureTraefik (which early-returns when traefik is already running) so an established node still materializes the file on the next self-heal tick / restart; the file-provider watch: true hot-loads it (no traefik restart).
  • Catalog (1216a8a): crafty service gains loadbalancer.server.scheme=https + loadbalancer.serverstransport=insecure-skip-verify@file.
  • Tests: TestServersTransports (named transport + insecureSkipVerify + valid YAML) and the new render added to the YAML-parse / no-:latest matrix. go test ./internal/infra/... ./internal/stacks/... green.

Deploy

Commit → build+push felhom-controller:0.83.0 on 192.168.0.180 → guest 9201 (docker pull/etc/felhom-controller-image → restart bootstrap svc). On controller startup, EnsureBaseStack wrote dynamic/serverstransports.yml automatically (logged: [infra] wrote backend transports → … (insecure-skip-verify)) — no manual file drop needed. Catalog sync (POST /api/sync) pulled the two labels; crafty recreated via POST /api/stacks/crafty-controller/update.

Verification (live, guest 9201)

Check Result
Dynamic file present + loaded /opt/docker/stacks/traefik/dynamic/serverstransports.yml written, no traefik parse error
A — public URL https://minecraft.demo-felhom.eu302 (was 502), via Cloudflare edge + in-guest Traefik
A — Traefik backend access log: 302 … "crafty-controller@docker" "https://172.18.0.6:8443" (before: 502 … "http://172.18.0.6:8443")
B — other apps unaffected filebrowser (HTTP backend) still 200 via Traefik — scoped, no global change
C — scoping proof no insecureSkipVerify in static traefik.yml; present ONLY in dynamic/serverstransports.yml
crafty health Up (healthy), dashboard state running

Deployed versions (docker ps)

felhom-controller  gitea.dooplex.hu/admin/felhom-controller:0.83.0          Up (healthy)
crafty-controller  registry.gitlab.com/crafty-controller/crafty-4:4.4.8     Up (healthy)

Verification method

curl to the Cloudflare public edge + in-guest Traefik probe (--resolve …:127.0.0.1) + Traefik access logs. (No browser tool used this run.)

Observation (carry, not acted on)

Generalize a backend_scheme/backend_tls hint in .felhom.yml so future HTTPS-backend apps get the scheme=https + serverstransport=…@file labels via the catalog convention rather than hand-added — own task.