cmd
This is the Docker Compose CLI plugin (v2), a Go implementation that orchestrates multi-container Docker applications defined in Compose YAML files. It provides the `docker compose` subcommand that builds, runs, watches, and manages containerized services by interfacing directly with the Docker daemon API, replacing the legacy Python-based docker-compose tool.
Key Features
- Full Compose Service Lifecycle
- Legacy CLI Compatibility
- File Watch & Hot Reload
- Rich Terminal UI
- Dry Run Mode
- Remote Project Loading
- Bridge/Provider Integration
- OpenTelemetry Tracing
- Docker Desktop Integration
Entry Points
Start here when working with this codebase
cmd/main.goInitialize and launch the Docker Compose CLI plugin with configuration, tracing, and argument handling
Start here when understanding the application bootstrap, plugin registration, or tracing initialization
cmd/compose/compose.goOrchestrate the Docker Compose CLI by defining the root command structure, managing project options, configuration loading, and initializing the compose backend service
Start here when adding a new subcommand, modifying project option parsing, or changing how the backend service is initialized
pkg/apiCore Service interface defining all compose operations (up, down, build, etc.), API types, events, labels, and error definitions
Start here when adding a new compose operation, modifying API types, or understanding what operations the engine must implement
pkg/composeCore compose engine implementing the Service API against the Docker daemon
Start here when modifying how compose operations interact with Docker, fixing engine bugs, or implementing a new Service method
cmd/compatibility/convert.goTransform and normalize docker-compose CLI arguments for plugin compatibility
Start here when handling legacy docker-compose argument formats or adding new argument transformations
cmd/display/tty.goRich terminal UI for monitoring Docker Compose operations with progress tracking and status updates
Start here when modifying terminal output, progress display, or adding new visual indicators
How to Make Changes
Common modification patterns for this codebase
Add a new CLI subcommand (e.g., 'docker compose <newcmd>')
cmd/compose/<newcmd>.goCreate a new file defining the Cobra command, its flags, and its run function. Define an options struct to hold parsed flags.
Pattern: Follow the exact structure in cmd/compose/down.go: define an options struct (e.g., downOptions), a constructor function (e.g., downCommand) that returns *cobra.Command, parse flags in the command definition, and wire the run function through the adapter pattern
pkg/apiAdd the new operation method signature to the Service interface and define any new option/result types needed
Pattern: Follow how DownOptions and the Down method are defined in the Service interface in pkg/api — add your new options struct and method signature in the same file or a new types file in pkg/api
pkg/composeCreate a new file implementing the Service interface method for the new command against the Docker daemon
Pattern: Follow the pattern in pkg/compose (the engine implementation files) — each operation is typically in its own file, receives a context and options, and interacts with the Docker client
cmd/compose/compose.goRegister the new subcommand by calling your constructor function and adding it to the root command's subcommands list
Pattern: Look at how existing commands like downCommand are instantiated and added via rootCmd.AddCommand() in cmd/compose/compose.go
pkg/mocksAdd a mock implementation of the new Service method for testing
Pattern: Follow the existing mock patterns in pkg/mocks where each Service method has a corresponding mock function field and implementation
pkg/e2eAdd end-to-end tests exercising the new command through the full CLI
Pattern: Follow existing E2E test patterns in pkg/e2e that invoke the CLI binary with arguments and assert on stdout/stderr output and container state
Conventions to follow:
Add a new flag to an existing CLI command
cmd/compose/<command>.goAdd the new field to the command's options struct and register the flag using cmd.Flags() in the command constructor
Pattern: See how cmd/compose/down.go defines flags like --volumes, --remove-orphans using cmd.Flags().BoolVar, cmd.Flags().StringVar, etc., binding them to fields on the options struct
pkg/apiIf the flag maps to a new API-level option, add the corresponding field to the relevant Options struct in pkg/api
Pattern: See how DownOptions in pkg/api includes fields like RemoveOrphans, Volumes that correspond to CLI flags
pkg/composeHandle the new option in the engine implementation, reading it from the options struct and adjusting behavior
Pattern: See how the compose engine reads DownOptions fields to decide which Docker API calls to make
Conventions to follow:
Modify output formatting or add a new display mode
cmd/formatter/container.goAdd or modify the formatting logic for container data, including new fields or format templates
Pattern: See how cmd/formatter/container.go transforms api.ContainerSummary into formatted output with field-level control over truncation and display
cmd/formatter/logs.goIf modifying log output, update the log formatting and colorization logic here
Pattern: See how cmd/formatter/logs.go handles log line formatting, container name prefixing, and color assignment
cmd/display/tty.goIf modifying the TTY progress display, update the real-time terminal UI components here
Pattern: See how cmd/display/tty.go manages concurrent status updates, hierarchical task visualization, and terminal size constraints
Conventions to follow:
Add a new compose engine operation (implement a Service method)
pkg/apiDefine the new method on the Service interface with its options and return types
Pattern: Follow how existing methods like Down(ctx context.Context, projectName string, options DownOptions) error are defined in the Service interface in pkg/api
pkg/composeCreate a new file (or add to an existing one) implementing the method on the composeService struct
Pattern: Each operation file in pkg/compose receives the composeService receiver, uses s.dockerCli or s.apiClient() to interact with Docker, and follows the context/cancellation patterns seen in other operation files
pkg/dryrunAdd a dry-run implementation that simulates the operation without side effects
Pattern: Follow the pattern in pkg/dryrun where each Service method is wrapped to log what would happen without actually calling Docker
pkg/mocksAdd a mock implementation for the new method
Pattern: Follow the mock pattern in pkg/mocks where each method has a function field that can be set in tests
Conventions to follow:
Add file watching support for a new scenario in dev mode
pkg/watchModify or extend the file system watcher, debouncing logic, or path filtering rules
Pattern: See how pkg/watch implements file system watching with debounce intervals and path matchers for ignoring files
pkg/composeUpdate the watch/dev-mode integration in the compose engine to handle the new scenario
Pattern: See how the compose engine's watch-related code connects file change events to rebuild/restart/sync actions
Conventions to follow:
Add keyboard shortcut to interactive log streaming
cmd/formatter/shortcut.goAdd the new shortcut key handler and update the menu rendering to display it
Pattern: See how cmd/formatter/shortcut.go defines keyboard shortcuts for watch, detach, and Docker Desktop integration — each shortcut has a key binding, a handler function, and a menu label
cmd/compose/compose.goIf the shortcut needs to trigger a compose operation, wire it through the backend service in the command adapter
Pattern: See how existing shortcuts in cmd/formatter/shortcut.go interact with the compose service and how the shortcut manager is initialized in the command flow
Conventions to follow:
Add tracing/observability to a new operation
internal/tracingAdd or extend span definitions and attribute constants for the new operation
Pattern: See how internal/tracing defines span management and how cmd/cmdtrace/cmd_span.go instruments CLI command execution with start/end spans and attribute recording
cmd/cmdtrace/cmd_span.goIf the operation is a CLI command, add tracing instrumentation in the command span lifecycle
Pattern: See how cmd/cmdtrace/cmd_span.go wraps command execution with OpenTelemetry spans, recording command name, flags, and duration
Conventions to follow:
Add bridge/provider integration for a new external format
pkg/bridgeAdd conversion logic between compose model types and the new external format
Pattern: See how pkg/bridge converts between compose and external formats, and how cmd/compose/bridge.go provides CLI command handlers for bridge operations
cmd/compose/bridge.goAdd or modify CLI command handlers for the new bridge/provider integration
Pattern: See how cmd/compose/bridge.go defines command handlers for compose-to-model conversion and transformer image management
Conventions to follow:
Add remote project loading from a new source type
pkg/remoteAdd the new source type handler alongside existing Git and OCI registry loaders
Pattern: See how pkg/remote implements Git repo and OCI registry loading with caching — each source type has a loader that resolves the remote reference, downloads the project, and caches it locally
Conventions to follow:
Coding Conventions
Standards and patterns used in this codebase
API routes are organized in routes/ directory
New endpoints go in pkg/api/api.go/routes/File naming uses: camelCase
main.go, cmd_span.go, convert.go, tty.go, container.goConfiguration is centralized in config files
Config files: cmd/compose/config.goStandard project structure
Code is organized by feature/module