The first run answered Question 1 with a flat no. The job container has no docker binary, so login died with exit 127 and the three steps that mattered were skipped — no answer on whether the registry accepts a push, and no build time.
What it did establish is that /var/run/docker.sock is mounted. The daemon is reachable; only the client is missing. That is a gap a step can close without reconfiguring the runner, so it is worth one more iteration before deciding anything.
The static binary rather than apt: one download, no package index to refresh, no repository to add, and only the CLI is wanted since the daemon already exists on the other side of that socket.
The architecture is resolved with uname rather than hardcoded. Nothing in this repository has ever confirmed what the NAS is, and assuming x86_64 would waste a whole run on the one machine everything else queues behind — the same class of mistake as assuming Portainer's build context contained .git in #235.
This step is deliberately not continue-on-error, unlike the diagnostics above it. If the client cannot be installed there is nothing left to measure, and one clear failure reads better than three skipped steps.
Still workflow_dispatch only, still bounded by timeout-minutes, still deleted when #237 is answered.
Ref #237
Throwaway. Deleted once #237 has an answer, whichever way it goes.
#233 was designed on an assumption about the Docker build context and broke every Portainer deploy. The chosen fix for the commit stamp — build in Actions, push to Gitea's registry, have Portainer pull — rests on three more assumptions about infrastructure that nothing in this repository can confirm. This probes them instead of designing around them.
Whether a job here can run `docker build` at all is genuinely unknown: the other workflows use `services:`, which proves the runner can start containers, not that it can build images. Whether the registry is usable is likewise unconfirmed — the packages API answers but lists nothing, so it has never been exercised. And the real build is timed because backend-integration.yml is manual after a job once held this runner for 3h12m, so what an image build costs here is part of deciding whether building on every merge is tenable at all.
The trivial image is built and pushed before the real one on purpose. It separates "can this runner build and push anything" from "does our Dockerfile work here", so a later failure still says which half is broken.
workflow_dispatch only, with no push or pull_request trigger, so merging this changes nothing until somebody presses the button. Bounded by timeout-minutes on the same reasoning backend-integration.yml already documents.
Ref #237