Skip to content

config: add --filter to select services by profile or label - #14046

Open
ndeloof wants to merge 1 commit into
docker:mainfrom
ndeloof:config-services-filter
Open

config: add --filter to select services by profile or label#14046
ndeloof wants to merge 1 commit into
docker:mainfrom
ndeloof:config-services-filter

Conversation

@ndeloof

@ndeloof ndeloof commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

What I did

Added a repeatable --filter criteria=value option to docker compose config --services, restricting the printed service names to those matching the criteria:

  • profile=NAME selects services declaring the profile. Filtering on a profile implies activating it (consistent with naming a profile-gated service explicitly), so no separate --profile is needed.
  • label=KEY[=VALUE] selects services carrying the label.

Same criteria = alternatives, distinct criteria = all required (docker --filter conventions).

This gives a first-class, scriptable way to select services, e.g. stopping only a profile's services without stopping the profile-less ones:

services=$(docker compose config --services --filter profile=workers)
[ -n "$services" ] && docker compose stop $services

The expression parsing and matching live in a new pkg/filter package, deliberately decoupled from the config command so the same selection mechanism can later be offered directly by commands operating on a subset of services (stop, restart, down, ...).

Related issue

Addresses #13993

Created with: Claude Code

@ndeloof
ndeloof requested review from a team as code owners August 14, 2026 10:33
@ndeloof
ndeloof requested a review from glours August 14, 2026 10:33

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Assessment: 🟡 NEEDS ATTENTION

One confirmed medium-severity logic gap: profile=* does not auto-activate profiled services, contrary to the PR description.

Comment thread cmd/compose/config.go
return err
}
// Filtering on a profile implies activating it.
if profiles := serviceFilter.Profiles(); len(profiles) > 0 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[medium] profile=* filter silently produces incomplete results — profiled services are never activated

The PR description states that profile=* "selects every service declaring at least one profile" with no need for a separate --profile flag, but the implementation contradicts this.

Filter.Profiles() explicitly excludes the wildcard with e.Value != "*", so WithProfiles is never called for the profile=* case. Since SelectNames only iterates over project.Services (active services), any profiled service that was not already activated at load time silently stays in DisabledServices and is invisible to the filter.

The e2e test (pkg/e2e/config_test.go line 134) actually confirms the workaround: it passes --profile "*" as a separate CLI flag alongside --filter profile=* to activate all profiles first. Without that extra flag, the filter returns an empty or incomplete list — the opposite of "no separate --profile is needed."

Trigger path: A user runs

docker compose config --services --filter profile=*

without any --profile flag and expects all profiled services to appear. Instead they get only those whose profile happens to already be active (typically none beyond the default set).

Fix: detect the wildcard in runServices (or in Filter.Profiles()) and call project.WithProfiles with all profiles the project declares before filtering:

if profiles := serviceFilter.Profiles(); len(profiles) > 0 {
    project, err = project.WithProfiles(append(project.Profiles, profiles...))
    if err != nil {
        return err
    }
}
// NEW: handle profile=* wildcard — activate every declared profile so that
// SelectNames can see all profiled services.
if serviceFilter.HasWildcardProfile() {
    project, err = project.WithProfiles(project.AllProfiles())
    if err != nil {
        return err
    }
}

Or, simpler, change Profiles() to return the sentinel "*" and let the caller pass it to WithProfiles (if WithProfiles handles "*" already via the existing --profile "*" mechanism).

Confidence Score
🟢 strong 100/100

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.42857% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/compose/config.go 80.95% 2 Missing and 2 partials ⚠️
pkg/filter/filter.go 95.91% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Add a --filter criteria=value option to docker compose config
--services, restricting the printed service names to those matching the
given criteria:

- profile=NAME selects services declaring the profile. Filtering on a
  profile implies activating it, so the services need not be otherwise
  enabled with --profile. Profiles must be selected explicitly: the "*"
  wildcard is rejected.
- label=KEY[=VALUE] selects services carrying the label.

Expressions with the same criteria are alternatives; distinct criteria
must all be satisfied, following the docker --filter conventions.

This gives a first-class way to script service selection, e.g. stopping
only the services of a profile without stopping the profile-less ones:

  services=$(docker compose config --services --filter profile=workers)
  [ -n "$services" ] && docker compose stop $services

The expression parsing and matching live in a new pkg/filter package,
deliberately decoupled from the config command so the same selection
mechanism can later be offered by commands operating on a subset of
services (stop, restart, down, ...).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
@ndeloof
ndeloof force-pushed the config-services-filter branch from c5584ee to f2762a1 Compare August 14, 2026 11:53
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