Skip to content

fix: allow disabled services as build additional contexts - #931

Merged
ndeloof merged 1 commit into
compose-spec:mainfrom
Shubham-Padkonde:fix/profile-build-context
Sep 18, 2026
Merged

ndeloof merged 1 commit into
compose-spec:mainfrom
Shubham-Padkonde:fix/profile-build-context

Conversation

@Shubham-Padkonde

Copy link
Copy Markdown
Contributor

A service used only as a build additional context can have an inactive profile. The consistency check currently rejects that service as unknown, before Docker Compose can include it in the build graph. This reproduces docker/compose#14223.

Look up disabled services for this build-context check while leaving their profile state unchanged. Missing targets still report an unknown service, and image-only targets still report a non-buildable service. The regression exercises the full loader with profile filtering and consistency checks enabled and verifies that only classroom is active.

Validation:

  • Original code: buildable and image-only regression cases fail; missing-target case passes.
  • Updated code: all three cases pass; full go test ./... passes on Linux, Go 1.24.13 and 1.26.3.

Repository-pinned golangci-lint 2.1.6 also passes (0 issues, Go 1.24.13).

No Docker daemon/image-build test was run. This addresses the loader rejection; Docker Compose needs to consume the updated dependency.

Prepared with OpenAI Codex assistance.

Validate build-only dependencies without enabling their profiles. Reproduces docker/compose#14223 through the loader and preserves missing and non-buildable target errors.

Assisted-by: OpenAI Codex
Signed-off-by: Shubham Padkonde <shubhampadkonde12@gmail.com>

@ndeloof ndeloof left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix is correct and minimal — mirrors the tolerance the depends_on check already has a few lines below (errors.Is(err, errdefs.ErrDisabled)), and the loader-level regression test correctly locks in all three outcomes (buildable / image-only / missing) plus p.DisabledServices["base"].Build != nil — i.e. the service stays disabled at the project level, which is the right scope for this fix.

I traced the follow-on question this raises: once a disabled service is reachable this way, does re-enabling it for the build risk it also getting started? On docker/compose's side (pkg/compose/build.go), s.build calls project.WithServicesEnabled(...) — but that method deepCopy()s before mutating (per its own doc comment, "returns a new Project instance ... keeps the original unchanged"), and s.build only ever returns a digest map, never the re-enabled project, back to its caller (ensureImagesExists → preparePlan → create/up). So the enabled-for-build copy is scoped to the build step and never reaches the reconciler that decides what to create/start — base gets built, not started. That safety property is real today, but it's an emergent consequence of a narrow return type + immutable-Project convention holding together, not something asserted by a test anywhere. Worth a docker/compose-side e2e case (once this dependency bumps) pinning "disabled build-context service is built but never started" — not a blocker for this PR, since it's out of loader scope, but flagging so it doesn't get silently relied upon forever.

@ndeloof
ndeloof merged commit f18e211 into compose-spec:main Sep 18, 2026
8 checks passed
ndeloof added a commit to ndeloof/compose that referenced this pull request Sep 21, 2026
…d service

A service reachable only as another service's build additional_contexts
must still build even when its own profile is inactive: it's referenced
for its image, not started as a workload -- the same tolerance the
depends_on consistency check already grants a disabled, non-required
dependency, and the same case addBuildDependencies already special-cases
on the docker/compose side.

compose-go's own consistency check doesn't grant that tolerance yet: it
rejects the reference outright, failing the whole project load before
addBuildDependencies (or anything else, up included) ever runs -- for
up, build and up --no-build alike, exactly as reported.

This is expected to fail until compose-go bumps to include
compose-spec/compose-go#931.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
ndeloof added a commit to ndeloof/compose that referenced this pull request Sep 21, 2026
compose-spec/compose-go#931 is merged: TestBuildAdditionalContextDisabledService,
red until now by design, passes for real against the released compose-go pin.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
glours pushed a commit to docker/compose that referenced this pull request Sep 21, 2026
A service reachable only as another service's build additional_contexts
must still build even when its own profile is inactive: it's referenced
for its image, not started as a workload -- the same tolerance the
depends_on consistency check already grants a disabled, non-required
dependency, and the same case addBuildDependencies already special-cases
on the docker/compose side.

compose-go's own consistency check doesn't grant that tolerance yet: it
rejects the reference outright, failing the whole project load before
addBuildDependencies (or anything else, up included) ever runs -- for
up, build and up --no-build alike, exactly as reported.

This is expected to fail until compose-go bumps to include
compose-spec/compose-go#931.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
glours pushed a commit to docker/compose that referenced this pull request Sep 21, 2026
compose-spec/compose-go#931 is merged: TestBuildAdditionalContextDisabledService,
red until now by design, passes for real against the released compose-go pin.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants