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.
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)
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>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Moves the site's image off
registry.netork.ioand removes a deploy job that had quietlystopped being correct.
The registry
registry.netork.iois plainregistry:2with 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'sregistry, 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_TOKENsecret (a Gitea token withwrite:package); the token Actionsinjects 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 oldREGISTRY_PASSWORDsecret is now unused and can go once nothing else wants it.The deploy job
Removed, not migrated. It ran
docker runagainst whatever runner picked the job up.That was correct while exactly one runner existed; there are now several —
netork-runner-12on .12,netork-runner-13on .13, plus the originalnetork-runner—and none of them is on 10.7.224.11, where this site runs and where the
proxy-netitattaches to lives.
The next push would therefore have started a second website container on the wrong host and
reported success, while
netork.iowent on serving the old one. Nothing had failed yet onlybecause the last deploy was 2026-07-17, when the pool was still one runner.
scripts/deploy.shreplaces 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.ioactually answers 200. The container is recreated with exactly the settingsthe 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, soneither 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/configandgit remote -vprints it. That token was exposed in a session transcripton 2026-09-08 and is due for rotation.
🤖 Generated with Claude Code