Public Wiki36,953View on GitHub
Want docker/compose knowledge in your AI?

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

Main Entry
cmd/main.go

Initialize 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

Root Command Definition
cmd/compose/compose.go

Orchestrate 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

Service API Interface
pkg/api

Core 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

Compose Engine Implementation
pkg/compose

Core 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

CLI Compatibility Layer
cmd/compatibility/convert.go

Transform and normalize docker-compose CLI arguments for plugin compatibility

Start here when handling legacy docker-compose argument formats or adding new argument transformations

Display & TTY Output
cmd/display/tty.go

Rich 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>')

1
cmd/compose/<newcmd>.go

Create 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

2
pkg/api

Add 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

3
pkg/compose

Create 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

4
cmd/compose/compose.go

Register 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

5
pkg/mocks

Add 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

6
pkg/e2e

Add 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:

Each CLI command lives in its own file under cmd/compose/ named after the commandOptions structs are private (lowercase) and defined in the same file as the commandThe command constructor returns *cobra.Command and accepts the project options and a backend (Service interface)Use the Adapt/AdaptWithContext wrapper from cmd/compose/compose.go for the RunE function to handle signals and error formattingAll engine operations go through the pkg/api Service interface — never call Docker directly from cmd/Dry-run support must be added in pkg/dryrun for the new method

Add a new flag to an existing CLI command

1
cmd/compose/<command>.go

Add 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

2
pkg/api

If 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

3
pkg/compose

Handle 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:

Flag names use kebab-case (e.g., --remove-orphans)Boolean flags default to false unless there's a strong reason otherwiseFlag descriptions should be concise and match Docker CLI styleIf the flag has a short form, register it with cmd.Flags().BoolVarP (note the P suffix)

Modify output formatting or add a new display mode

1
cmd/formatter/container.go

Add 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

2
cmd/formatter/logs.go

If 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

3
cmd/display/tty.go

If 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:

Support multiple output formats: table (default), JSON, and Go templatesUse the --format flag pattern seen in cmd/compose/images.go for format selectionColor output should be TTY-aware — disable colors when not writing to a terminalContainer names and IDs should be truncatable with consistent truncation lengths

Add a new compose engine operation (implement a Service method)

1
pkg/api

Define 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

2
pkg/compose

Create 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

3
pkg/dryrun

Add 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

4
pkg/mocks

Add 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:

All Docker interactions go through the compose engine, never directly from CLI commandsOperations must respect context cancellationUse the event/progress reporting mechanism (api events) to report status back to the display layerError types should use the defined error types in pkg/api for consistent error handlingThe Service interface is the single contract between CLI and engine — keep it clean

Add file watching support for a new scenario in dev mode

1
pkg/watch

Modify 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

2
pkg/compose

Update 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:

File watching must be efficient — use debouncing to avoid excessive rebuildsRespect .dockerignore and compose watch ignore patternsWatch operations should be cancellable via context

Add keyboard shortcut to interactive log streaming

1
cmd/formatter/shortcut.go

Add 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

2
cmd/compose/compose.go

If 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:

Shortcuts must handle terminal state properly (raw mode)Display the shortcut in the menu bar at the bottom of log outputShortcuts should be single-key (no modifier keys) for simplicityError states from shortcut actions should be displayed inline, not crash the log stream

Add tracing/observability to a new operation

1
internal/tracing

Add 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

2
cmd/cmdtrace/cmd_span.go

If 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:

Use OpenTelemetry conventions for span and attribute namingTracing should be opt-in and not affect performance when disabledSpan names should follow the pattern 'compose/<operation>'Record meaningful attributes (project name, service count, etc.) but avoid sensitive data

Add bridge/provider integration for a new external format

1
pkg/bridge

Add 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

2
cmd/compose/bridge.go

Add 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:

Bridge conversions should be lossless where possible, with clear warnings for unsupported featuresExternal format handling should be isolated in pkg/bridge, not leaked into the core engine

Add remote project loading from a new source type

1
pkg/remote

Add 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:

Remote loading must support caching to avoid repeated downloadsSource type detection should be automatic based on the URL/reference formatErrors should clearly indicate network vs. authentication vs. format issues

Coding Conventions

Standards and patterns used in this codebase

api-patterns

API routes are organized in routes/ directory

New endpoints go in pkg/api/api.go/routes/
pkg/api/api.gopkg/api/errors.gopkg/api/event.go
naming

File naming uses: camelCase

main.go, cmd_span.go, convert.go, tty.go, container.go
cmd/main.gocmd/cmdtrace/cmd_span.gocmd/compatibility/convert.go
configuration

Configuration is centralized in config files

Config files: cmd/compose/config.go
cmd/compose/config.go
file-organization

Standard project structure

Code is organized by feature/module
cmd/main.gocmd/cmdtrace/cmd_span.gocmd/compatibility/convert.go