Documentation
¶
Overview ¶
relationships:
references: [builder, metadata, spec]
relationships:
references: [metadata, up, spec]
relationships:
references: [up, manage, ../../cli/cli]
Package dockercompose brings a docker-compose-mode devcontainer up against a docker-compatible daemon. The package owns the full orchestration loop natively: it parses and merges compose files through compose-spec/compose-go, generates an in-memory override layer that injects the feature-derived image into the primary service, and creates networks / volumes / containers via the docker engine API. There is no shell-out to the `docker compose` CLI.
The Compose file owns workspace mounts. Up adds no automatic workspace bind; workspaceFolder selects the lifecycle working directory and defaults to "/". A workspaceFolder of "/" does not add a mount at the root.
The "primary service" is the one named in devcontainer.json's `service` field: it's where lifecycle commands run and where Exec attaches. Other services come up alongside it, ordered by their compose `depends_on` graph; `service_healthy` and `service_completed_successfully` conditions are honored by polling the dependency's container state before the dependent is created (timeout tunable via Options.DependencyTimeout).
Compatibility ¶
Containers, networks, and volumes are labeled with the standard compose keys (`com.docker.compose.project`, `com.docker.compose.service`, etc.). The devcontainer-discovery labels (`devcontainer.local_folder`, `devcontainer.config_file`) are stamped only onto the primary service's container, matching the upstream `devcontainers/cli` so editor extensions (and the InspectPrimary helper) find a unique target. A project brought up here can be torn down by `docker compose down -p <name>` and vice versa.
Compose-side build ¶
Both the primary and sidecars may declare a compose `build:` block. BuildPrimaryImage runs the primary's build through BuildKit and uses the result as the base for feature derivation; Up walks the project for non-primary services with a build block and compiles each through BuildKit before creating its container, then mutates the in-memory project so the spawn step uses the freshly-built tag. Options.SkipServiceBuild opts out for embedders that manage their own image pipeline. dockerfile_inline is rejected.
Recreate-on-config-change ¶
Every container created by Up carries a `com.docker.compose.config-hash` label computed from a normalized JSON snapshot of its compose ServiceConfig (image, entrypoint, command, env, volumes, ports, networks, depends_on, security flags, …) with host-managed labels stripped. On subsequent Up calls, an existing container whose hash disagrees with the current spec (or is missing) is stopped, removed, and rebuilt from the current spec; matching hashes preserve the container. Set Options.NoRecreate to fall back to the prior "always reuse" behavior; UpResult.RecreatedThisCall lists which services were destroyed and rebuilt this call.
Profiles ¶
Up takes a Profiles slice on its request. Compose services whose `profiles:` list is non-empty are excluded unless one of the activated profiles matches (or "*" is passed). The primary service stays enabled regardless — without it there's no devcontainer — and any service named in spec.RunServices stays enabled too, matching `docker compose up <svc>`'s "implicitly activate this service's profiles" behavior.
Configs and secrets ¶
Top-level compose `configs:` and `secrets:` are honored in standalone (non-swarm) mode. Each ServiceConfig.Configs / .Secrets reference is translated into a read-only bind mount of the source file into the container; default targets match upstream (`/<source>` for configs, `/run/secrets/<source>` for secrets) and explicit `target:` overrides land verbatim. Source resolution follows the spec:
- `file:` is bound directly.
- `environment:` reads the named host env var (from UpRequest.LocalEnv) and writes it to a private run directory under Options.UserDataFolder (default: $TMPDIR/dcb-compose) before binding it. Docker volume labels record ownership before any payload write. Remove discovers and cleans these directories without the original options or source configuration; cleanup failures retain ownership for retry.
- Config `content:` writes the literal value to the same private directory. The pinned Compose loader schema does not accept secret `content:`.
- `external: true` is rejected — the package doesn't speak swarm.
- `driver:` is rejected — only file/env/content sources work.
UID/GID/Mode on the FileReferenceConfig are not enforced: the bind mount inherits the on-host file's ownership (matching `docker compose` standalone mode).
Watch / develop ¶
Host.Watch loops over every service in the project that declares `develop.watch` and polls each trigger's Path for filesystem changes. Action coverage:
- `sync`: changed files are tarred and pushed via the CopyToContainer engine API; deletions trigger an `rm -rf` exec inside the target container.
- `restart`: ContainerRestart on the target.
- `sync+restart`: both.
- `sync+exec`: sync, then run trigger.exec.command via the same Exec path lifecycle commands use.
- `rebuild`: not honored — would need the build pipeline. Any active rebuild trigger errors out.
Include/ignore use `*`, `?`, and `**` (leading `**/` / trailing `/**`) globs. Watch blocks until ctx is cancelled; the caller owns the goroutine.
Scope cuts ¶
- tmpfs, image, and cluster volume types return an error rather than being silently dropped.
- port publishing from compose `ports:` is forwarded to the engine, but devcontainer.json `forwardPorts`/`appPort` are intentionally not layered onto compose services (the user already has compose `ports:` for that).
relationships:
references: [up, ../../cli/options_lifecycle]
relationships:
references: [projectname, project, labels]
relationships:
references: [up, metadata, spawn]
relationships:
references: [objects, up, manage, ../../../internal/datafolder/staging]
relationships:
references: [manage, projectname]
relationships:
references: [up, configuration]
relationships:
references: [projectname, up, build]
relationships:
references: [project, manage, ../../../../reference/cli/src/spec-node/dockerCompose.ts]
relationships:
references: [host, composebuild, ../../buildkit/auth, ../../registryauth]
relationships:
references: [metadata, up, spec]
relationships:
references: [metadata, override, lifecycle]
Index ¶
- Constants
- Variables
- func FindExisting(ctx context.Context, cli *dockerclient.Client, projectName, serviceName string) (string, error)
- func LoadProject(ctx context.Context, in LoadInputs) (*types.Project, error)
- func OverrideYAML(in OverrideInputs) ([]byte, error)
- func ProjectName(workspace string, composeFiles ...string) string
- type BuildPrimaryInputs
- type BuildPrimaryResult
- type BuildServiceImagesInputs
- type BuildServiceImagesResult
- type ContainerInfo
- type ExecRequest
- type ExecResult
- type Host
- func (h *Host) Client() *dockerclient.Client
- func (h *Host) Exec(ctx context.Context, req ExecRequest) (*ExecResult, error)
- func (h *Host) Execer(containerID string) runner.Execer
- func (h *Host) Inspect(ctx context.Context, localWorkspace string) (*ProjectInfo, error)
- func (h *Host) InspectPrimary(ctx context.Context, localWorkspace string) (*ContainerInfo, error)
- func (h *Host) Remove(ctx context.Context, localWorkspace string) error
- func (h *Host) RemoveProject(ctx context.Context, projectName, localWorkspace string) error
- func (h *Host) RemoveRuntime(ctx context.Context, localWorkspace string) error
- func (h *Host) Stop(ctx context.Context, localWorkspace string) error
- func (h *Host) Up(ctx context.Context, req UpRequest) (*UpResult, error)
- func (h *Host) Watch(ctx context.Context, req WatchRequest) error
- type LoadInputs
- type Options
- type OverrideInputs
- type ProjectConflict
- type ProjectConflictError
- type ProjectInfo
- type UpRequest
- type UpResult
- type WatchRequest
Constants ¶
const ( LabelProject = "com.docker.compose.project" LabelService = "com.docker.compose.service" LabelOneoff = "com.docker.compose.oneoff" LabelConfigHash = "com.docker.compose.config-hash" LabelContainerN = "com.docker.compose.container-number" LabelWorkingDir = "com.docker.compose.project.working_dir" LabelConfigFiles = "com.docker.compose.project.config_files" LabelDependencies = "com.docker.compose.depends_on" LabelVersion = "com.docker.compose.version" LabelComposeVer = "3.13.0" // minimum compose version we claim )
Compose-standard labels written by Up so containers can be rediscovered by either this package or the upstream `docker compose` CLI. Keys match docker/compose's own constants.
const ( LabelLocalFolder = "devcontainer.local_folder" LabelConfigFile = "devcontainer.config_file" LabelPrimary = "devcontainer.compose.primary" )
Devcontainer-side labels mirrored from pkg/host/docker so a project is discoverable by workspace.
Variables ¶
var ErrPrimaryNotFound = errors.New("dockercompose host: primary service not found in compose project")
ErrPrimaryNotFound is returned when the spec's `service` is not present in the merged compose project.
var ErrProjectNotFound = errors.New("dockercompose host: project not found")
ErrProjectNotFound is returned when no compose project exists for a supplied selector (workspace path or project name).
Functions ¶
func FindExisting ¶
func FindExisting(ctx context.Context, cli *dockerclient.Client, projectName, serviceName string) (string, error)
FindExisting returns the first container ID for a Compose project and service, including stopped containers, or an empty string if none exists. Compose's own labels allow reuse of containers created by docker compose.
func LoadProject ¶
LoadProject parses and merges the spec's compose files (plus any override layer) into a single normalized *types.Project, ready for engine-API consumption.
func OverrideYAML ¶
func OverrideYAML(in OverrideInputs) ([]byte, error)
OverrideYAML returns a YAML document suitable for appending to the compose merge chain. Only the primary service is touched; other services pass through unchanged.
func ProjectName ¶
ProjectName supplies the directory-based default used by the devcontainers CLI: <workspace>_devcontainer for a first Compose file in <workspace>/.devcontainer, otherwise the basename of that file's directory. With no file it assumes the conventional .devcontainer directory. LoadProject applies environment, .env, and authored Compose names ahead of this default. Names are lowercased and retain only [-_a-z0-9]; they contain no workspace hash.
Types ¶
type BuildPrimaryInputs ¶
type BuildPrimaryInputs struct {
// SkipDefaultLoad leaves BuilderOptions.Load unchanged instead of enabling
// local loading by default. Push and filesystem exports retain their meaning.
SkipDefaultLoad bool
// Spec is the parsed devcontainer.json (compose mode).
Spec *spec.DevContainer
// Workspace is the host workspace path; used as the build context.
Workspace string
// LocalEnv is forwarded to compose interpolation.
LocalEnv map[string]string
// Tag is the image tag to assign. When empty, a timestamped tag
// under "devcontainer-builder/compose-primary" is generated.
Tag string
// BuilderOptions tunes the underlying builder. Spec, SpecPath and Workspace
// are derived from the primary service. Tag overrides the first image name;
// additional Tags are retained. Load defaults on unless pushing or exporting.
BuilderOptions builder.Options
}
BuildPrimaryInputs feeds BuildPrimaryImage.
type BuildPrimaryResult ¶
type BuildPrimaryResult struct {
// Image is the image reference compose should use for the primary
// service. Equal to the primary service's compose `image:` when
// no feature, server, or export customization requires a derived image.
Image string
// Built is true when a Compose service or derived image was built.
Built bool
// BuildResult is non-nil only for a derived build. Its image label owns
// the full current config/features; pass ImageBuilt: BuildResult != nil
// to Up. A Compose service build alone does not have that provenance.
BuildResult *builder.Result
}
BuildPrimaryResult reports the outcome.
func BuildPrimaryImage ¶
func BuildPrimaryImage(ctx context.Context, in BuildPrimaryInputs) (*BuildPrimaryResult, error)
BuildPrimaryImage produces the image the primary compose service should run with.
- When the primary declares only `image:` and no feature, server, or build customization requires a derived image, the image is unchanged.
- When the primary declares `build:`, that compose-side build is built with BuildKit first to produce a base image. When the caller requests features or build customizations, a derived image is layered on top; otherwise the build's output tag is returned directly.
- When features are present, a derived image is built FROM the base (compose `image:` or compose `build:` output) with the features (and the VS Code server, when requested) layered on, and the derived tag is returned.
type BuildServiceImagesInputs ¶
type BuildServiceImagesInputs struct {
OmitSyntaxDirective bool
// Project is the loaded compose project. Required.
Project *types.Project
// Services restricts the build to the named services. When empty,
// every service in the project that has a `build:` block is built.
// Names that don't exist in the project are an error.
Services []string
// Skip lists service names to leave alone even if they have a
// `build:` block. Useful when an embedder is baking a particular
// service through a different path (e.g. BuildPrimaryImage for the
// devcontainer primary).
Skip []string
// BuildKitAddress selects a separate BuildKit. Empty falls back to
// BUILDKIT_HOST, then to the Docker daemon's built-in BuildKit.
BuildKitAddress string
// Docker is the Engine API client the built images are loaded
// through. When nil, one is created from the DOCKER_* environment.
Docker *dockerclient.Client
// Platforms are the target platforms. Empty means the daemon's
// default. Per-service compose `build.platforms` takes precedence
// over this when set.
Platforms []string
// NoCache disables the build cache.
NoCache bool
// Pull always re-pulls referenced images.
Pull bool
// RegistryAuth supplies the registry credentials of every service
// build. When nil, BuildKit reads the docker CLI's configuration
// (registryauth.FromEnvironment).
RegistryAuth buildkit.RegistryAuth
// Progress one of "auto" | "plain" | "tty" | "rawjson".
Progress string
// Stdout / Stderr receive build output. nil means os.Stdout /
// os.Stderr; pass io.Discard to silence.
Stdout io.Writer
Stderr io.Writer
// Logger receives informational messages.
Logger func(format string, args ...any)
}
BuildServiceImagesInputs feeds BuildServiceImages.
type BuildServiceImagesResult ¶
type BuildServiceImagesResult struct {
// Images maps service name → built image reference. Only contains
// services whose `build:` was honored.
Images map[string]string
// Built lists service names actually built (vs skipped because
// they had no `build:`).
Built []string
}
BuildServiceImagesResult records the per-service image after building.
func BuildServiceImages ¶
func BuildServiceImages(ctx context.Context, in BuildServiceImagesInputs) (*BuildServiceImagesResult, error)
BuildServiceImages walks every service of proj that declares a `build:` block, builds it with BuildKit's dockerfile.v0 frontend, and loads the result into the Docker daemon. Returns service-name → resulting tag.
Tag resolution per service:
- When the service's `build:` declares its own `tags:`, the first entry is used (additional tags are still applied via -t).
- Else when the service declares `image:`, that's the tag.
- Else a deterministic `devcontainer-builder/compose-svc-<project>-<service>:<unix-nano>` is generated.
The function is safe to call without a Host: it connects to BuildKit itself. The Host's Up wraps it for convenience but embedders that own the project lifecycle can call it directly.
type ContainerInfo ¶
type ContainerInfo struct {
ID string
Service string
Image string
Running bool
StartedAt string
CreatedAt string
Primary bool
Labels map[string]string
}
ContainerInfo is a per-container projection.
type ExecRequest ¶
type ExecRequest struct {
// TerminalSize sets the initial PTY size [rows, columns] when TTY is true.
TerminalSize *[2]uint
ContainerID string
Cmd []string
User string
WorkDir string
Env map[string]string
TTY bool
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}
ExecRequest is the per-container exec call; same shape as the docker host's so embedders moving between modes have one mental model.
type ExecResult ¶
ExecResult mirrors docker host's: captured output is returned only when the corresponding writer was nil.
type Host ¶
type Host struct {
// contains filtered or unexported fields
}
Host is the per-daemon connection. Safe for concurrent use.
func New ¶
func New(c *dockerclient.Client, opts Options) *Host
New wraps an existing docker client. Lifetime of the client is the caller's responsibility.
func (*Host) Client ¶
func (h *Host) Client() *dockerclient.Client
Client returns the underlying docker client so embedders can issue ad-hoc calls.
func (*Host) Exec ¶
func (h *Host) Exec(ctx context.Context, req ExecRequest) (*ExecResult, error)
Exec runs a command inside an existing project container.
func (*Host) Execer ¶
Execer returns a runner.Execer for the given container ID. Use the primary service's container ID to drive lifecycle commands.
func (*Host) Inspect ¶
Inspect returns the state of every container belonging to the compose project for the supplied workspace path. Returns ErrProjectNotFound if no containers match.
func (*Host) InspectPrimary ¶
InspectPrimary returns just the primary service's container for the workspace — the one editor extensions and the upstream `devcontainers/cli` discover by the `devcontainer.local_folder` label. The lookup mirrors the single-container docker host's Inspect, so the same workspace-path → container handoff works regardless of which mode the spec is in. Returns ErrProjectNotFound when no project exists for the workspace, or ErrPrimaryNotFound when a project exists but no container carries the primary marker label (e.g. a stale partial up).
func (*Host) Remove ¶
Remove tears the project down: stops + removes every container, then removes project-owned networks and volumes. External resources are left alone. A project with another workspace's labelled container is refused before any container or resource is changed.
func (*Host) RemoveProject ¶
RemoveProject tears down a label-selected project without consulting config.
func (*Host) RemoveRuntime ¶
RemoveRuntime removes only projects identified by recorded object ownership or existing container labels. It never reads a workspace's default configuration.
func (*Host) Stop ¶
Stop stops every container in the workspace's project. It refuses a project with a container labelled for another workspace before stopping anything. Idempotent on already-stopped containers.
func (*Host) Up ¶
Up brings the compose project up: build override, load+merge project, ensure networks/volumes, find-or-create each service in dependency order, then run lifecycle on the primary. Idempotent.
func (*Host) Watch ¶
func (h *Host) Watch(ctx context.Context, req WatchRequest) error
Watch loops over every service in the project that declares `develop.watch`, polls each trigger's Path for filesystem changes, and fires the configured action against the running container.
Action coverage:
- sync: changed files are tarred and pushed via the docker CopyToContainer API. Deleted files trigger an `rm -rf` exec inside the target container.
- restart: the container is restarted (graceful stop, then start).
- sync+restart: sync, then restart.
- sync+exec: sync, then run the trigger's `exec:` command.
- rebuild: not honored — would need the build pipeline, which is out of scope for the watch loop. Returns an error if any active trigger uses it.
Include/ignore are matched with path.Match against the path relative to Trigger.Path, with `**` interpreted as match-any-suffix. Watch blocks until ctx is cancelled or any session errors out.
type LoadInputs ¶
type LoadInputs struct {
// Spec is the parsed devcontainer.json. Must be in compose mode.
Spec *spec.DevContainer
// Workspace is the host workspace path; used for the default project name
// and the upstream CLI working directory for the .env name lookup.
Workspace string
// LocalEnv is the host environment forwarded to compose's
// `${VAR}` interpolation. Pass an empty map (not nil) for none.
LocalEnv map[string]string
// Override is an additional YAML layer appended to the merge chain.
// Optional: callers that don't need overrides can leave it nil.
// When the package builds an internal override (derived image,
// runtime labels, etc.) it appends it here.
Override []byte
}
LoadInputs are the parameters needed to merge a compose project for a devcontainer.
type Options ¶
type Options struct {
// RegistryAuth supplies the same native pull credentials as the Docker
// host, and the credentials of Up's service builds. A value that also
// implements buildkit.RegistryAuth (such as a *registryauth.Store or a
// registryauth.Static) answers the builds directly; any other value
// answers them through its EngineAuth values. When nil, pulls are
// anonymous and service builds read the docker CLI's configuration.
RegistryAuth interface{ EngineAuth(string) (string, error) }
// UserDataFolder selects the parent for private materialized configs/secrets.
UserDataFolder string
// TerminalSize is the optional lifecycle PTY size [rows, columns].
TerminalSize *[2]uint
// Logger receives informational messages. nil discards.
Logger func(format string, args ...any)
// Stdout / Stderr default to nil. Lifecycle command output goes
// here unless the per-call request supplies its own writers.
Stdout io.Writer
Stderr io.Writer
// StopTimeout bounds graceful shutdown. Defaults to 10s.
StopTimeout time.Duration
// DependencyTimeout bounds how long Up will wait for any single
// `depends_on` entry to reach its declared condition
// (service_healthy / service_completed_successfully). Defaults to
// 5 minutes; the condition is rechecked every 500ms.
DependencyTimeout time.Duration
// SkipServiceBuild disables the auto-build pass that walks the
// project for non-primary services with a `build:` block and
// builds them with BuildKit before bring-up. Embedders that
// pre-build their own images can set this to skip it.
SkipServiceBuild bool
// NoRecreate, when true, preserves an existing container even if
// its config-hash label disagrees with the current spec. Default
// behavior (false) mirrors `docker compose up`: a config-hash
// mismatch (or missing label) triggers a stop+remove+create cycle
// so the container picks up the new spec.
NoRecreate bool
}
Options tunes a Host. All fields are optional.
type OverrideInputs ¶
type OverrideInputs struct {
// Spec is the parsed devcontainer.json (must be compose mode).
Spec *spec.DevContainer
// PrimaryImage, when non-empty, replaces the primary service's
// `image:` (used after a derived feature build).
PrimaryImage string
// RemoteEnv is layered onto the primary service's environment.
// Values flow from devcontainer.json's `remoteEnv`.
RemoteEnv map[string]string
// OverrideCommand: when true (matching the spec's default in compose
// mode), the primary service's command is replaced by a long-running
// keepalive so lifecycle commands and exec attach have a live
// container regardless of the image's ENTRYPOINT/CMD. When false,
// the original entrypoint/command are preserved.
OverrideCommand bool
// Entrypoints are the features' entrypoint contributions, run by the
// keepalive command when OverrideCommand is true.
Entrypoints []string
// Labels merged onto the primary service.
Labels map[string]string
}
OverrideInputs feeds OverrideYAML.
type ProjectConflict ¶
type ProjectConflict struct {
Name string `json:"name"`
ID string `json:"id"`
LocalFolder string `json:"localFolder"`
}
ProjectConflict identifies a project container owned by another workspace. ID is the full Docker ID; LocalFolder is devcontainer.local_folder.
type ProjectConflictError ¶
type ProjectConflictError struct {
Project string
Workspace string
Conflicts []ProjectConflict
}
ProjectConflictError carries all conflicting containers so callers can offer both text diagnostics and structured error results.
func (*ProjectConflictError) Error ¶
func (e *ProjectConflictError) Error() string
type ProjectInfo ¶
type ProjectInfo struct {
Name string
Workspace string
Containers []ContainerInfo
}
ProjectInfo is a small projection of a compose project's runtime state.
type UpRequest ¶
type UpRequest struct {
// ContainerDataFolder selects lifecycle and dotfiles marker storage.
ContainerDataFolder string
// ContainerSystemDataFolder selects the upstream system patch marker folder.
ContainerSystemDataFolder string
// GPUAvailability controls implicit hostRequirements.gpu reservations. Empty means detect.
GPUAvailability string
// OmitConfigRemoteEnvFromMetadata omits the current config remoteEnv from new labels.
OmitConfigRemoteEnvFromMetadata bool
// Spec is the parsed devcontainer.json (must be in compose mode).
Spec *spec.DevContainer
// SpecPath is the host-side path the spec was loaded from. Used
// for the devcontainer.config_file label on every container.
SpecPath string
// LocalWorkspace is the host workspace path; absolute. Used for
// project identity and local workspace substitution.
LocalWorkspace string
// ContainerWorkspace is the in-container workspace folder. When
// empty, falls back to spec.WorkspaceFolder, then "/" like upstream.
// Used for lifecycle commands and substitution; Compose owns the mounts.
ContainerWorkspace string
// PrimaryImage, when set, overrides the primary service's image
// in the override layer. Used to point compose at a feature-built
// derived image.
PrimaryImage string
// ImageBuilt means PrimaryImage contains the complete current config and
// feature metadata produced by BuildPrimaryImage.BuildResult, not only a
// Compose service build. Such contributions must not be collected twice.
ImageBuilt bool
// SkipLifecycle suppresses all lifecycle commands for this invocation.
SkipLifecycle bool
// SkipPostAttach suppresses postAttachCommand for this invocation.
SkipPostAttach bool
// Dotfiles installs the user's dotfiles after postCreateCommand unless
// SkipLifecycle is set.
Dotfiles runner.Dotfiles
// Lifecycle selects lifecycle stop points and prebuild behavior.
Lifecycle runner.LifecycleControls
// RemoteEnv is the caller's remote environment for lifecycle commands
// and the dotfiles install (upstream --remote-env). The configuration's
// remoteEnv wins for the same name, as upstream. It is not stored.
RemoteEnv map[string]string
// DefaultUserEnvProbe selects the shell probe when userEnvProbe is not configured.
DefaultUserEnvProbe string
// Secrets are secret environment variables for lifecycle commands and
// the dotfiles install (upstream --secrets-file). They win over every
// other layer and are never stored in container configuration, labels
// or files.
Secrets map[string]string
// Features as resolved by pkg/features. Their containerEnv and
// lifecycle commands are merged into the primary service.
Features []features.Resolved
// LocalEnv is forwarded to compose's `${VAR}` interpolation and
// to ${localEnv:VAR} substitution in the spec. It's also the
// lookup table for `environment:` source secrets/configs.
LocalEnv map[string]string
// Profiles activates compose service profiles. Services whose
// `profiles:` are set to a non-empty list are excluded unless one
// matches an entry here (or "*" is supplied). The primary service
// (spec.Service) is always kept; its declared profiles are folded
// into the active set so its own dependencies-by-profile come up.
Profiles []string
// Mounts are added to the primary service after the metadata mounts, in
// devcontainer mount syntax (a CLI --mount). A named volume is a project
// volume unless marked external=true. Up adds no host path that is not in
// the configuration or here.
Mounts []string
// IDLabels, when non-empty, are set on the primary container and seed
// ${devcontainerId} in place of the workspace labels, as upstream
// --id-label does. The workspace labels stay on the primary so project
// ownership checks and workspace-scoped Stop/Remove still apply.
IDLabels map[string]string
// AllowProjectConflict permits Up to reuse/recreate a project containing
// another workspace's containers, matching upstream. The default refuses.
AllowProjectConflict bool
}
UpRequest is everything Up needs. The caller resolves features (typically via pkg/features) and optionally supplies a derived image from BuildPrimaryImage. Otherwise the primary Compose service selects the image.
type UpResult ¶
type UpResult struct {
// ProjectName is the resolved compose project name.
ProjectName string
// PrimaryContainerID is the ID of the container the spec's
// `service` runs in.
PrimaryContainerID string
// ContainerIDs maps service name → container ID for every service
// that was started this call (or reused).
ContainerIDs map[string]string
// CreatedThisCall enumerates services whose container was created
// this call (vs reused).
CreatedThisCall []string
// StartedThisCall enumerates services whose container had to be
// started this call (vs already running).
StartedThisCall []string
// RecreatedThisCall enumerates services whose container was
// destroyed and recreated this call because its config-hash label
// disagreed with the current spec.
RecreatedThisCall []string
// PhasesRun lists lifecycle phases that actually ran on the
// primary (markers may have skipped some).
PhasesRun []lifecycle.Hook
}
UpResult reports what happened.
type WatchRequest ¶
type WatchRequest struct {
// Spec is the parsed devcontainer.json (must be in compose mode).
Spec *spec.DevContainer
// SpecPath is the host path the spec was loaded from. Used only
// for diagnostics.
SpecPath string
// LocalWorkspace is the absolute host workspace path. Used as
// the project name source so the active project lookup matches
// what Up brought up.
LocalWorkspace string
// LocalEnv is forwarded to compose's `${VAR}` interpolation.
LocalEnv map[string]string
// PollInterval governs the host-side mtime sweep cadence.
// Defaults to 1 second; smaller values are CPU-hungry on deep
// trees.
PollInterval time.Duration
// OnEvent receives one callback per fired trigger. Optional;
// useful for progress UIs and tests. The slice of changed
// relative paths is supplied for `sync` and `sync+*` actions;
// `restart` and `rebuild` pass nil.
OnEvent func(service string, action types.WatchAction, changed []string)
}
WatchRequest drives Host.Watch.