The spike is answered. One file deleted, as it always said it would be.
What it established
The runner can build images once a docker CLI is installed. The socket was mounted all along; only the client was missing.
The container registry works and accepts pushes. It had never been exercised, so this was genuinely unknown.
TLS from the runner to the Gitea host is trusted — the iteration-2 failure was a 401, not an x509 error. That also answers the certificate half of the Portainer question.
A PAT with write:package authenticates; the token Actions injects automatically does not.
A full image build and push costs 9m14s on that runner.
#235 removed COPY .git from the Dockerfile to stop the version stamp breaking every Portainer deploy. So it does not matter that an Actions checkout has history — the Dockerfile never copies it. Build location was never the problem, and migrating builds to CI would have delivered nothing on its own.
#248 carries the actual fix: a build arg, a few lines, and no registry needed.
Why this deletes from main too
The workflow was merged here in #238, before iteration 2 showed that workflow_dispatch fires from a branch and a spike never needed to reach main at all. Both copies go; the spike/237-registry-docker-cli branch goes with them.
Still owed by hand
The spike-trivial and spike-3085970 packages in the registry. I will try the API; if it is not exposed, deleting them is a click in Gitea's package view.
On the registry question itself
Left open in #248's framing rather than decided here. It is feasible and measured, and if it is ever done it should be release-triggered, not per-merge — 9m14s per build on a single serialised runner where a CI pass is already ~21.5 minutes and the queue reached six deep. This spike itself waited over two hours across three attempts to run, which is its own evidence.
The spike is answered. One file deleted, as it always said it would be.
## What it established
- **The runner can build images** once a docker CLI is installed. The socket was mounted all along; only the client was missing.
- **The container registry works and accepts pushes.** It had never been exercised, so this was genuinely unknown.
- **TLS from the runner to the Gitea host is trusted** — the iteration-2 failure was a 401, not an x509 error. That also answers the certificate half of the Portainer question.
- **A PAT with `write:package` authenticates**; the token Actions injects automatically does not.
- **A full image build and push costs 9m14s** on that runner.
## What it disproved, which was the point
A CI-built image **still reports `commit: "unknown"`**:
```
git says: 3085970
image says: { "commit": "unknown", "builtAt": "2026-08-30T22:12:32Z" }
```
#235 removed `COPY .git` from the Dockerfile to stop the version stamp breaking every Portainer deploy. So it does not matter that an Actions checkout has history — the Dockerfile never copies it. **Build location was never the problem**, and migrating builds to CI would have delivered nothing on its own.
#248 carries the actual fix: a build arg, a few lines, and no registry needed.
## Why this deletes from `main` too
The workflow was merged here in #238, before iteration 2 showed that `workflow_dispatch` fires from a branch and a spike never needed to reach `main` at all. Both copies go; the `spike/237-registry-docker-cli` branch goes with them.
## Still owed by hand
The `spike-trivial` and `spike-3085970` packages in the registry. I will try the API; if it is not exposed, deleting them is a click in Gitea's package view.
## On the registry question itself
Left open in #248's framing rather than decided here. It is feasible and measured, and if it is ever done it should be **release-triggered, not per-merge** — 9m14s per build on a single serialised runner where a CI pass is already ~21.5 minutes and the queue reached six deep. This spike itself waited over two hours across three attempts to run, which is its own evidence.
Closes #237
The spike is answered, so the throwaway goes as it always said it would.
What it established. The runner can build images once a docker CLI is installed — the socket was mounted all along and only the client was missing. The container registry works and accepts pushes; it had never been exercised, so that was genuinely unknown. TLS from the runner to the Gitea host is trusted, which also answers the certificate half of the Portainer question. A personal access token with write:package authenticates where the token Actions injects automatically does not. And a full image build and push costs 9m14s on that runner.
What it disproved, which was the point. A CI-built image still reports `commit: "unknown"`. #235 removed `COPY .git` from the Dockerfile to stop the version stamp breaking every Portainer deploy, so it does not matter that an Actions checkout has history — the Dockerfile never copies it. Build location was never the problem, and moving builds to CI would have delivered nothing on its own. #248 carries the actual fix, a build arg, which is a few lines and does not need the registry at all.
Deleting this from main rather than only from the spike branch: it was merged here in #238, before iteration 2 showed that workflow_dispatch fires from a branch and a spike never needed to reach main at all.
Still owed by hand: the spike-trivial and spike-3085970 packages in the registry.
Closes#237
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.
The spike is answered. One file deleted, as it always said it would be.
What it established
write:packageauthenticates; the token Actions injects automatically does not.What it disproved, which was the point
A CI-built image still reports
commit: "unknown":#235 removed
COPY .gitfrom the Dockerfile to stop the version stamp breaking every Portainer deploy. So it does not matter that an Actions checkout has history — the Dockerfile never copies it. Build location was never the problem, and migrating builds to CI would have delivered nothing on its own.#248 carries the actual fix: a build arg, a few lines, and no registry needed.
Why this deletes from
maintooThe workflow was merged here in #238, before iteration 2 showed that
workflow_dispatchfires from a branch and a spike never needed to reachmainat all. Both copies go; thespike/237-registry-docker-clibranch goes with them.Still owed by hand
The
spike-trivialandspike-3085970packages in the registry. I will try the API; if it is not exposed, deleting them is a click in Gitea's package view.On the registry question itself
Left open in #248's framing rather than decided here. It is feasible and measured, and if it is ever done it should be release-triggered, not per-merge — 9m14s per build on a single serialised runner where a CI pass is already ~21.5 minutes and the queue reached six deep. This spike itself waited over two hours across three attempts to run, which is its own evidence.
Closes #237