klinux / klinux/gocdnext

Auto-derive docker daemon access for plugins that require it (drop manual `docker: true` for buildx)

Open
#50 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement help wanted
Dominant language
Go
Stars
7
Forks
3
Avg merge
2h 12m
Merged PRs (30d)
30

Description

Problem

A job that uses: the buildx plugin (and any future plugin that needs a docker daemon) must also remember to set docker: true on the job. Forgetting it produces a confusing, slow failure — the plugin waits 60s for a daemon that never comes up:

gocdnext/buildx: docker daemon did not become reachable within 60s
  DOCKER_HOST=<unset>
  is `docker: true` set on the job? agent wires a DinD sidecar only then
── task failed after 1m2s (exit 2)

buildx is useless without a daemon — it can't do anything else. The plugin already knows it needs docker, so requiring the pipeline author to repeat that as docker: true is redundant and a footgun (hit in real use on a release pipeline).

Why the flag must still exist (do NOT make it a global default)

docker: true is not free, and its cost/risk differs per engine:

Engine docker: true does… Cost / risk Without it
Docker (agent/internal/engine/docker.go:24-28) bind-mounts host /var/run/docker.sock + sets DOCKER_HOST cheap, but "effectively root on the host via the Docker API" (per the code comment) no socket → buildx fails
K8s (agent/internal/engine/kubernetes_isolated.go:317-357) spins up a privileged DinD sidecar (privileged: true, full second daemon) heavy + privileged no daemon reachable (nodes run containerd, not docker) → buildx fails

So most jobs (npm, go test, trivy) must NOT get a daemon by default — especially under k8s where it means a privileged container. The flag stays as the explicit opt-in for raw image: jobs that need a daemon (e.g. testcontainers, ad-hoc docker build).

Proposal

Let a plugin declare its requirement in its manifest, and have the agent satisfy it the engine-appropriate way — so the author never writes docker: true for such plugins:

  1. plugin.yaml schema: add requires_docker: true (today docker: true only appears in the example snippets of the manifest, there is no capability field). Mirror it as an OCI image label so the image is self-describing.
  2. Resolution (prefer parse-time, via embedded catalog): the server embeds the plugin catalog (go:embed); at parse/apply, a job using a docker-requiring catalog plugin auto-sets Docker=true, and we log it (job Y: docker access auto-enabled, required by plugin buildx) so the privileged-sidecar decision is traceable, not a hidden default. Custom/out-of-catalog plugins keep the current clear runtime error (or fall back to an agent-side image-label read if we want full generality — tradeoff: extra registry round-trip + private-registry creds at scheduling time).
  3. The agent then wires the daemon per engine (socket-mount on docker, DinD sidecar on k8s) exactly as it does today for docker: true — no change to the low-level path.

Decisions to keep

  • docker: true stays valid and explicit for raw jobs and custom plugins; auto-derive only adds a path, never removes the knob.
  • Never a global default-on (security + cost, especially privileged DinD under k8s).
  • Auto-enable is logged at apply so it's auditable.

Out of scope / open questions

  • Parse-time embedded-catalog vs agent-time image-label read (generality vs cost) — pick during design.
  • Whether to fail loud at apply ("buildx requires docker access") instead of silently auto-enabling — leaning auto-enable+log since choosing buildx is itself the opt-in, but worth deciding.

Context

Surfaced while validating the gated delivery flow in an internal test repo: the release pipeline's buildx build jobs failed for exactly this reason. Immediate fix was adding docker: true explicitly; this issue tracks removing the footgun in core.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the plugin.yaml manifest examples and the engine paths in agent/internal/engine/docker.go and agent/internal/engine/kubernetes_isolated.go. Then trace the server's embedded plugin catalog and job parse/apply flow to decide where requires_docker is resolved and logged. Done means catalog plugins can declare the requirement while raw jobs and custom plugins retain explicit docker access behavior, with tests covering both engines and no global default.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, go, kubernetes
Domain
ci-cd, devops, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.