feat(ci): publish to Gitea's registry, and stop deploying to a random host #1

Merged
christianmanivong merged 1 commits from feature/gitea-registry into main 2026-09-08 21:51:49 +00:00
Owner

Moves the site's image off registry.netork.io and removes a deploy job that had quietly
stopped being correct.

The registry

registry.netork.io is plain registry:2 with htpasswd auth — no notion of a repository,
so every account that can log in reads and writes everything on it, including the accounts
issued to customer instances. Verified: a customer server's credentials list the whole
catalogue and read netork/license-engine's tags.

That is fine for the images customer instances are meant to pull (engine, ui,
satellite) and wrong for everything else. The marketing site joins the KB in Gitea's
registry, where packages are scoped to their owning account and no customer has one — under
this split customers never touch Gitea at all. netOrk #172.

Login uses a REGISTRY_TOKEN secret (a Gitea token with write:package); the token Actions
injects per run is scoped to the repository API and the package registry rejects it with a
bare unauthorized. Both secrets are already set on this repository. The old
REGISTRY_PASSWORD secret is now unused and can go once nothing else wants it.

The deploy job

Removed, not migrated. It ran docker run against whatever runner picked the job up.
That was correct while exactly one runner existed; there are now several —
netork-runner-12 on .12, netork-runner-13 on .13, plus the original netork-runner —
and none of them is on 10.7.224.11, where this site runs and where the proxy-net it
attaches to lives.

The next push would therefore have started a second website container on the wrong host and
reported success, while netork.io went on serving the old one. Nothing had failed yet only
because the last deploy was 2026-07-17, when the pool was still one runner.

scripts/deploy.sh replaces it. It names the target host, pulls before it removes anything,
compares the running container's image id against what was pulled, and finishes by checking
that netork.io actually answers 200. The container is recreated with exactly the settings
the old job used — --restart unless-stopped, --network proxy-net, no port bindings —
read off the running container rather than assumed.

To get push-to-deploy back: register a runner on .11 with a label of its own and pin
runs-on: to it, or give CI an ssh key for .11. Both decide where a credential lives, so
neither was decided here.

Unrelated, but worth knowing

This repository's git remote embeds an access token in the URL, so it sits in plaintext in
.git/config and git remote -v prints it. That token was exposed in a session transcript
on 2026-09-08 and is due for rotation.

🤖 Generated with Claude Code

Moves the site's image off `registry.netork.io` and removes a deploy job that had quietly stopped being correct. ## The registry `registry.netork.io` is plain `registry:2` with htpasswd auth — no notion of a repository, so every account that can log in reads *and* writes everything on it, including the accounts issued to customer instances. Verified: a customer server's credentials list the whole catalogue and read `netork/license-engine`'s tags. That is fine for the images customer instances are meant to pull (`engine`, `ui`, `satellite`) and wrong for everything else. The marketing site joins the KB in Gitea's registry, where packages are scoped to their owning account and no customer has one — under this split customers never touch Gitea at all. netOrk #172. Login uses a `REGISTRY_TOKEN` secret (a Gitea token with `write:package`); the token Actions injects per run is scoped to the repository API and the package registry rejects it with a bare `unauthorized`. Both secrets are already set on this repository. The old `REGISTRY_PASSWORD` secret is now unused and can go once nothing else wants it. ## The deploy job **Removed, not migrated.** It ran `docker run` against whatever runner picked the job up. That was correct while exactly one runner existed; there are now several — `netork-runner-12` on .12, `netork-runner-13` on .13, plus the original `netork-runner` — and **none of them is on 10.7.224.11**, where this site runs and where the `proxy-net` it attaches to lives. The next push would therefore have started a second website container on the wrong host and reported success, while `netork.io` went on serving the old one. Nothing had failed yet only because the last deploy was 2026-07-17, when the pool was still one runner. `scripts/deploy.sh` replaces it. It names the target host, pulls before it removes anything, compares the running container's image id against what was pulled, and finishes by checking that `netork.io` actually answers 200. The container is recreated with exactly the settings the old job used — `--restart unless-stopped`, `--network proxy-net`, no port bindings — read off the running container rather than assumed. To get push-to-deploy back: register a runner on .11 with a label of its own and pin `runs-on:` to it, or give CI an ssh key for .11. Both decide where a credential lives, so neither was decided here. ## Unrelated, but worth knowing This repository's git remote embeds an access token in the URL, so it sits in plaintext in `.git/config` and `git remote -v` prints it. That token was exposed in a session transcript on 2026-09-08 and is due for rotation. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
christianmanivong added 1 commit 2026-09-08 21:41:47 +00:00
feat(ci): publish to Gitea's registry, and stop deploying to a random host
CI / TypeScript — type-check (pull_request) Successful in 10s
CI / Publish — build & push image (pull_request) Skipped
CI / TypeScript — type-check (push) Successful in 9m48s
CI / Publish — build & push image (push) Skipped
c40fa97cd1
The image moves off registry.netork.io. That registry is plain registry:2 with
htpasswd auth, which knows nothing about repositories: every account that can log
in reads and writes everything on it, including the accounts issued to customer
instances. Verified -- a customer server's credentials list the whole catalogue.
It keeps the images those instances are meant to pull; the marketing site is not
one of them. Gitea scopes packages to their owning account, and no customer has
one. netOrk #172.

Login uses a REGISTRY_TOKEN secret (a Gitea token with write:package). The token
Actions injects per run does not work here -- the package registry rejects it
with a bare "unauthorized", which is a confusing way to spend an afternoon.

The deploy job is removed rather than migrated, because it had quietly stopped
being correct. It ran `docker run` against whatever runner picked the job up,
which worked while exactly one runner existed. There are now several --
netork-runner-12 on .12, netork-runner-13 on .13, plus the original
netork-runner -- and none of them is on 10.7.224.11, where this site runs and
where the proxy-net it attaches to lives. The next push would have started a
second website container on the wrong host and reported success while netork.io
went on serving the old one. Nothing had failed yet; the last deploy was
2026-07-17, back when the pool was one runner.

scripts/deploy.sh replaces it: it names the target, pulls before it removes
anything, compares the running container's image id against what was pulled, and
finishes by checking that netork.io actually answers 200.

Push-to-deploy can come back by registering a runner on .11 with a label of its
own and pinning `runs-on:` to it, or by giving CI an ssh key. Both decide where a
credential lives, so neither was decided here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
christianmanivong merged commit 451a98c14a into main 2026-09-08 21:51:49 +00:00
christianmanivong deleted branch feature/gitea-registry 2026-09-08 21:51:49 +00: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: NetOrk/website#1