Skip to content

feat(service): add Compose profiles support#126

Open
ryan106 wants to merge 1 commit into
Mcrich23:mainfrom
ryan106:feat/profile-support
Open

feat(service): add Compose profiles support#126
ryan106 wants to merge 1 commit into
Mcrich23:mainfrom
ryan106:feat/profile-support

Conversation

@ryan106

@ryan106 ryan106 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Problem

The Compose spec lets services be gated behind named profiles:

services:
  web:
    image: nginx
  debug-tools:
    image: busybox
    profiles: ["debug"]

docker compose only starts debug-tools when debug is active (--profile debug or COMPOSE_PROFILES=debug); container-compose has no profiles support at all — the key is silently ignored, so profile-gated services always start. Projects that rely on Docker Compose profiles to scope multi-team stacks (auth-only vs. full-engine vs. frontend, etc.) can't reproduce that behavior.

Solution

  • Added profiles: [String]? to Service (plain list of strings per spec — no shorthand string form).
  • Added a repeatable --profile flag to the shared ComposeFileOptions group (used by up/down/build), plus support for the spec's COMPOSE_PROFILES environment variable (comma-separated), merged with --profile.
  • Service.isProfileEligible(activeProfiles:) implements the spec's default gate: no profiles (or empty) → always eligible; otherwise eligible only if one of the service's profiles is active.
  • Service.selectServices(from:requestedServices:activeProfiles:) is the shared selection algorithm for up, build, and down: it seeds from either the explicitly requested services or the profile-eligible set, then walks depends_on — matching the spec's stated exceptions, where an explicitly-named service and any service reached only as a dependency both bypass the profile gate regardless of their own profiles.
  • ComposeBuild and ComposeDown reuse selectServices for their own default (no explicit service args) selection, so build/up/down behave consistently for the same profile-gated dependency graph. down additionally prints a note listing any services skipped because their profile isn't active, so cleanup gaps aren't silent.

Changes

  • Sources/Container-Compose/Codable Structs/Service.swiftprofiles field + decoding, isProfileEligible(activeProfiles:), and the shared selectServices(from:requestedServices:activeProfiles:) (moved here alongside topoSortConfiguredServices since it's now used by all three subcommands, not just up).
  • Sources/Container-Compose/Commands/ComposeFileOptions.swift--profile option + activeProfiles (merges with COMPOSE_PROFILES).
  • Sources/Container-Compose/Commands/ComposeUp.swift — calls Service.selectServices.
  • Sources/Container-Compose/Commands/ComposeBuild.swift, ComposeDown.swift — default-selection paths now reuse Service.selectServices for parity with up.
  • Tests/Container-Compose-StaticTests/ProfilesTests.swift — decoding, eligibility, default/active/explicit/dependency selection, CLI parsing, and COMPOSE_PROFILES merging (suite marked .serialized since two tests mutate the process environment).
  • Tests/Container-Compose-StaticTests/ServiceDependencyTests.swift — updated one existing call site for the selectServices rename.

Adds `profiles` to Service plus a repeatable --profile flag and
COMPOSE_PROFILES env var support, gating default service selection
per the Compose spec (explicit targets and dependencies bypass the
gate). up/build/down share one selection algorithm (Service.selectServices)
so all three behave consistently for the same profile-gated graph; down
now prints a note listing anything skipped due to an inactive profile.
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