ComposeDetector & ComposeClient¶
ComposeDetector¶
Discovers Compose projects from container labels. Optionally merges with compose file config to include services with no running containers.
Usage¶
import { ComposeDetector } from 'sidekick-docker-shared';
const detector = new ComposeDetector();
const containers = await client.listContainers();
const projects = detector.detect(containers);
Detection Methods¶
- Label-based (primary) — reads
com.docker.compose.projectandcom.docker.compose.servicefrom container labels - File-based (secondary) — runs
docker compose configto discover the full service list from compose files
The detector merges both sources, so you see running containers and planned services in a single view.
Return Type¶
Returns an array of ComposeProject objects, each containing:
name— project nameservices— array ofComposeServiceobjects with name, state, container ID (if running), and configurationworkingDir,configFile,configFiles— optional recorded project location and files in override order;configFileremains the first file for compatibilitystatus—running,partial, orstopped, accounting for all discovered replicas
Services include optional replicas, runningReplicas, and totalReplicas fields. Each ComposeReplica records containerId, state, image, and ports. The service's existing containerId refers to a deterministic representative, preferring a running replica. Planned services have an empty replica list and zero counts.
ComposeClient¶
Wraps docker compose CLI commands for project lifecycle management.
Usage¶
import { ComposeClient } from 'sidekick-docker-shared';
const compose = new ComposeClient();
await compose.up('my-project');
await compose.down('my-project');
await compose.restart('my-project', 'web');
Methods¶
| Method | Signature | Description |
|---|---|---|
up |
(project: string, cwd?: string | ComposeCommandOptions) => Promise<ComposeExecResult> |
Start a Compose project (docker compose up -d) |
down |
(project: string, cwd?: string | ComposeCommandOptions) => Promise<ComposeExecResult> |
Stop a Compose project (docker compose down) |
restart |
(project: string, service?: string, cwd?: string | ComposeCommandOptions) => Promise<ComposeExecResult> |
Restart a project or specific service |
stop |
(project: string, service?: string, cwd?: string | ComposeCommandOptions) => Promise<ComposeExecResult> |
Stop a project or specific service |
start |
(project: string, service?: string, cwd?: string | ComposeCommandOptions) => Promise<ComposeExecResult> |
Start existing service containers |
streamLogs |
(project: string, service?: string, tail?: number, signal?: AbortSignal) => AsyncIterable<LogEntry> |
Follow logs; default tail is 100 |
Lifecycle methods resolve to a ComposeExecResult (exitCode, stdout, stderr); use throwIfComposeFailed(result, operation) to turn a nonzero exit into a ComposeError. String cwd arguments remain supported. ComposeCommandOptions accepts { cwd?: string; configFiles?: string[] }, passing every file with -f in the supplied order.
Use resolveComposeOptions(source, fallback?) to resolve recorded paths and reject missing files before an action:
import { ComposeClient, resolveComposeOptions, throwIfComposeFailed } from 'sidekick-docker-shared';
const compose = new ComposeClient();
const options = resolveComposeOptions(project, workspaceDirectory);
const result = await compose.up(project.name, options);
throwIfComposeFailed(result, 'Up');
streamLogs has its own abort signal, preserves split UTF-8 and trailing output, and throws when the command fails. The lifecycle options object does not change its signature.
All operations shell out to docker compose rather than using the Docker API directly, because compose orchestration logic lives in the compose CLI.