From 1f13e1dc7585138051b589f960d82d0405a6298c Mon Sep 17 00:00:00 2001 From: Lev Date: Fri, 6 Mar 2026 11:30:57 +0000 Subject: [PATCH] Filter services in config --no-interpolate to respect [SERVICE...] argument When using docker compose config --no-interpolate with specific service names, the SERVICE argument was being ignored and all services were returned. This adds service filtering after the model is loaded in the no-interpolate code path. Fixes #13614 Signed-off-by: odlevq@gmail.com --- cmd/compose/config.go | 14 ++++++++++++++ pkg/e2e/config_test.go | 9 +++++++++ pkg/e2e/fixtures/config-filter/compose.yaml | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 pkg/e2e/fixtures/config-filter/compose.yaml diff --git a/cmd/compose/config.go b/cmd/compose/config.go index 646ecd81806..4b877386a8d 100644 --- a/cmd/compose/config.go +++ b/cmd/compose/config.go @@ -271,6 +271,20 @@ func runConfigNoInterpolate(ctx context.Context, dockerCli command.Cli, opts con return nil, err } + if len(services) > 0 { + if svcs, ok := model["services"].(map[string]any); ok { + filtered := make(map[string]any, len(services)) + for _, name := range services { + if svc, exists := svcs[name]; exists { + filtered[name] = svc + } else { + return nil, fmt.Errorf("no such service: %s", name) + } + } + model["services"] = filtered + } + } + if opts.resolveImageDigests { err = resolveImageDigests(ctx, dockerCli, model) if err != nil { diff --git a/pkg/e2e/config_test.go b/pkg/e2e/config_test.go index 15d3e3d932a..30d8f3b6804 100644 --- a/pkg/e2e/config_test.go +++ b/pkg/e2e/config_test.go @@ -17,8 +17,10 @@ package e2e import ( + "strings" "testing" + "gotest.tools/v3/assert" "gotest.tools/v3/icmd" ) @@ -47,6 +49,13 @@ func TestLocalComposeConfig(t *testing.T) { res.Assert(t, icmd.Expected{Out: `- ${PORT:-8080}:80`}) }) + t.Run("--no-interpolate with service filter", func(t *testing.T) { + res := c.RunDockerComposeCmd(t, "-f", "./fixtures/config-filter/compose.yaml", "--project-name", projectName, "config", "--no-interpolate", "example1") + res.Assert(t, icmd.Expected{Out: `example1`}) + // example2 should NOT appear in the output when only example1 is requested + assert.Assert(t, !strings.Contains(res.Stdout(), "example2"), "expected example2 to be filtered out") + }) + t.Run("--variables --format json", func(t *testing.T) { res := c.RunDockerComposeCmd(t, "-f", "./fixtures/config/compose.yaml", "--project-name", projectName, "config", "--variables", "--format", "json") res.Assert(t, icmd.Expected{Out: `{ diff --git a/pkg/e2e/fixtures/config-filter/compose.yaml b/pkg/e2e/fixtures/config-filter/compose.yaml new file mode 100644 index 00000000000..6aa3dc90564 --- /dev/null +++ b/pkg/e2e/fixtures/config-filter/compose.yaml @@ -0,0 +1,18 @@ +services: + example1: + container_name: example1 + image: example/example + restart: unless-stopped + ports: + - "3001:3000" + environment: + TZ: ${TZ:-Etc/UTC} + + example2: + container_name: example2 + image: example/example + restart: unless-stopped + ports: + - "3002:3000" + environment: + TZ: ${TZ:-Etc/UTC}