k3s-deploy-notes.md documents GHCR pull as canonical - docker-save sideload is the real pattern #38

Closed
opened 2026-05-23 20:54:32 +00:00 by coilysiren · 1 comment
Owner

Originally filed by @coilysiren on 2026-05-21T04:34:52Z - https://github.com/coilysiren/infrastructure/issues/218

Problem

docs/k3s-deploy-notes.md documents the GHCR-push + cluster-side-pull flow as the canonical CI deploy pattern (the CI workflow block around line 210, and the docker-registry ExternalSecret in section 5). But the actual canonical homelab pattern - used by repo-recall, galaxy-gen, and now backend - is the docker-save sideload:

  1. Build the image in CI.
  2. docker save it, stream the tarball over tailscale ssh deploy@kai-server into sudo k3s ctr -n k8s.io images import -.
  3. kubectl set image + rollout status.

No registry pull on the cluster, no imagePullSecret, no kubeconfig in CI - just an OIDC tailnet join (TS_CLIENT_ID / TS_AUDIENCE) and an SSH tunnel.

This drift is not cosmetic: backend followed the documented GHCR pattern and the cluster could not pull the image (403, read:packages), which forced the migration (coilysiren/backend#70, #71).

Fix

Update k3s-deploy-notes.md to make the docker-save sideload the documented default, with repo-recall/.github/workflows/docker.yml and galaxy-gen/.github/workflows/build-and-publish.yml as reference templates. Keep the GHCR path documented only as the option for repos that publish public images for third-party consumers (repo-recall does both).

_Originally filed by @coilysiren on 2026-05-21T04:34:52Z - [https://github.com/coilysiren/infrastructure/issues/218](https://github.com/coilysiren/infrastructure/issues/218)_ **Problem** `docs/k3s-deploy-notes.md` documents the GHCR-push + cluster-side-pull flow as the canonical CI deploy pattern (the CI workflow block around line 210, and the `docker-registry` ExternalSecret in section 5). But the actual canonical homelab pattern - used by `repo-recall`, `galaxy-gen`, and now `backend` - is the **docker-save sideload**: 1. Build the image in CI. 2. `docker save` it, stream the tarball over `tailscale ssh deploy@kai-server` into `sudo k3s ctr -n k8s.io images import -`. 3. `kubectl set image` + `rollout status`. No registry pull on the cluster, no `imagePullSecret`, no kubeconfig in CI - just an OIDC tailnet join (`TS_CLIENT_ID` / `TS_AUDIENCE`) and an SSH tunnel. This drift is not cosmetic: `backend` followed the documented GHCR pattern and the cluster could not pull the image (403, `read:packages`), which forced the migration (coilysiren/backend#70, #71). **Fix** Update `k3s-deploy-notes.md` to make the docker-save sideload the documented default, with `repo-recall/.github/workflows/docker.yml` and `galaxy-gen/.github/workflows/build-and-publish.yml` as reference templates. Keep the GHCR path documented only as the option for repos that publish public images for third-party consumers (repo-recall does both).
Author
Owner

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: burndown-2026-06.

Backlog burndown 2026-06-17: closing low-priority (P3/P4) to bring the open count to a manageable level. Nothing lost — reopen if this resurfaces. Batch tag: `burndown-2026-06`.
coilysiren 2026-06-17 08:22:55 +00:00
Sign in to join this conversation.
No description provided.