Help us shape the future of Go! Take the 2026 Go Developer Survey

compose

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2026 License: BSD-3-Clause Imports: 25 Imported by: 0

README

compose

Docs CI Go Reference status

Multi-container applications for the go-wasmcontainers engine, whose containers are WASI preview 1 (wasip1) WebAssembly modules: wctr compose reads an application described by the Compose Specification and runs it through the engine's API. Compose files are accepted in three formats — YAML, JSON and HCL2 — which load to the same model. Pure Go (CGO_ENABLED=0); it builds for GOOS=js and GOOS=wasip1, because it runs in the browser playground too.

Status: M1. Loading is complete — discovery, YAML/JSON/HCL2, interpolation, .env, merging of several files, extends, include, profiles, validation against the specification's schema — and the application runs on the engine: up, down, ps, logs, start, stop, restart, rm, pull, images, build, config — services reach each other by service name and aliases, on as many networks as they declare, ports are published on the engine's host, restart policies are applied, and healthchecks run, service_healthy dependencies waiting for them (engine v0.28.0 or later). What is not applied is listed in Limitations.

Demo

A one-shot service fills a volume, a server serves it read-only on the project's network, a client fetches it by the server's name — the TestLab integration test, run against an in-process engine:

name: lab
services:
  init:
    image: labapp
    command: [write, /data/msg, "hello from a volume"]
    volumes: [data:/data]
  web:
    image: labapp
    command: [serve, "8080", /data/msg]
    environment: [GREETING]
    volumes: ["data:/data:ro"]
    depends_on:
      init: {condition: service_completed_successfully}
  client:
    image: labapp
    command: [get, "http://web:8080/"]
    depends_on: [web]
volumes:
  data: {}
$ GREETING=hi wctr compose up -d
 Network lab_default  Created
 Volume lab_data  Created
 Container lab-init-1  Created
 Container lab-init-1  Started
 Container lab-init-1  Exited (0)
 Container lab-web-1  Created
 Container lab-web-1  Started
 Container lab-client-1  Created
 Container lab-client-1  Started
$ wctr compose logs client
lab-client-1 | got: hello from a volume (greeting hi)
$ wctr compose down -v

labapp is a stock Go wasip1 program using stealthrocket/net (testdata/wasm/labapp).

config validates a file and prints the normalised model, here from HCL2 to YAML:

$ go install github.com/go-wasmcontainers/compose/cmd/wctr-compose@latest
$ cat compose.hcl
variable "TAG" {
  default = "1.0"
}

service "web" {
  image = "localhost:5000/lab/web:${var.TAG}"
  network "front" {
    aliases = ["www"]
  }
  depends_on "db" {
    condition = "service_healthy"
  }
}

service "db" {
  image = "localhost:5000/lab/db:1"
  volume {
    type   = "volume"
    source = "data"
    target = "/var/lib/db"
  }
}

network "front" {}
volume "data" {}
$ TAG=1.2 wctr-compose config --format yaml
name: lab
services:
  db:
    image: localhost:5000/lab/db:1
    networks:
      default: {}
    volumes:
      - type: volume
        source: data
        target: /var/lib/db
  web:
    depends_on:
      db:
        condition: service_healthy
        required: true
    image: localhost:5000/lab/web:1.2
    networks:
      front:
        aliases:
          - www
networks:
  default:
    name: lab_default
  front:
    name: lab_front
volumes:
  data:
    name: lab_data

wctr-compose is the command on its own (-H names the engine's socket, as for wctr); inside wctr it is wctr compose, wired through wctr's cli.Options.Extra with wctr's own engine connection (natively its -H, in the playground the in-process transport).

Compose files in three formats

File Format
compose.yaml, compose.yml YAML 1.2, with anchors, aliases and << merge keys
compose.json JSON
compose.hcl HCL2 native syntax: service "web" { ... } blocks, var.NAME variables in a static context

docs/HCL.md specifies the HCL2 mapping, with one application written side by side in the three formats; a test loads the three to the identical model, and config --format yaml|json|hcl output loads back to the same model (tested and fuzzed). Files of different formats merge: -f compose.yaml -f override.hcl.

Commands

wctr compose [-f FILE]... [-p NAME] [--profile P]... [--project-directory DIR] [--env-file FILE]... COMMAND

The global flags come before the command, as in the compose CLI: -f is --file there, and --follow after logs.

Command Flags
up [SERVICE...] -d/--detach, --force-recreate, --build, --remove-orphans. Builds or pulls missing images (see Builds), creates the project's networks and volumes, creates and starts containers dependencies first; a container whose configuration hash and image did not change is kept (started again if it stopped). Without -d, follows the logs until every container exits; an interrupt stops them
down -v/--volumes (never external ones). Works with -p NAME alone, with no Compose file
ps [SERVICE...] -a/--all, -q/--quiet
logs [SERVICE...] -f/--follow; lines prefixed with the container's name
start, stop, restart [SERVICE...] dependencies first (stop: dependents first); stop also stops a container waiting to restart, and ends its restart policy until the next start
rm [SERVICE...] -s/--stop; stopped containers only otherwise; -f accepted (there is no question)
pull [SERVICE...]
images [SERVICE...]
build [SERVICE...] --no-cache
config [SERVICE...] --format yaml|json|hcl (default yaml), -q/--quiet (validate only), --services (names only)

Builds. A service's build: section is built with go-wasmcontainers/build v0.2.1 through the engine (its exported builder.Build; package imagebuild here): context (a directory of the project, resolved from the Compose file's directory; its .containerignore, else .dockerignore, applies), dockerfile (relative to the context, inside the project; default Containerfile, else Dockerfile), dockerfile_inline, args (a name alone takes the environment's value, else is left unset), target, tags, no_cache. The image is named by the service's image, else <project>-<service>. up builds an image that is missing (a service with an image is pulled first and built if the pull fails, as build.md says), up --build and compose build always build — through the builder's cache, so an unchanged build gives the same image and the containers are kept. Natively the cache is wctr build's ($XDG_CACHE_HOME/wasmcontainers/build-cache.json); in a browser the host passes one (cli.Options.BuildCache).

Resources are named and labelled as the specification says: containers <project>-<service>-<n> (or container_name), networks and volumes <project>_<key> (or name; external ones by their key), every one labelled com.docker.compose.project, containers also com.docker.compose.service, .container-number, .config-hash, .image, .oneoff, .depends_on, networks .network, volumes .volume. The engine lists a project's resources by that label itself (Docker's filters parameter).

Networks: a container joins every network its service declares, at creation; on each it answers to its own name, to the service's name and to the aliases it has there — an alias or a service name shared by several replicas resolves to all of them. Services on no common network cannot reach each other (tested: a front-only service cannot resolve a back-only one).

Dependencies: service_started waits for the dependency's containers to be started; service_completed_successfully waits for them to exit and fails up if one exited non-zero; service_healthy waits for the dependency's health check (run by the engine in the container: CMD, CMD-SHELL — which needs a /bin/sh in the image, e.g. ghcr.io/go-wasmcontainers/shell — or NONE/disable: true) to report healthy. The wait follows the engine's events (health_status, and the container's own), with a one-second safety poll; it fails at once when the check reports unhealthy (quoting the last probe's output), when the container stops first, or when it has no check, and after --wait-timeout (default 5 min) when it is still starting. A dependency with required: false that fails any of these is a warning, and up carries on.

Without -f, the project directory is searched for compose.yaml, compose.yml, compose.json, compose.hcl, then the specification's legacy names, and the first compose.override.{yaml,yml,json,hcl} found is merged on top. The project name is -p, else COMPOSE_PROJECT_NAME, else the top-level name, else the project directory's name.

What is loaded

Everything the specification defines is parsed; what this engine applies:

  • Services: image, build (context, dockerfile, dockerfile_inline, args, target, tags, no_cache), command, entrypoint, environment, env_file (with required and format: raw), working_dir, volumes (named volumes), networks (with aliases), ports (short and long syntax), expose, network_mode: none, depends_on (service_started, service_healthy, service_completed_successfully, required, restart), healthcheck, deploy.replicas / scale (at most 64), labels, profiles, container_name, restart (no, always, on-failure[:N], unless-stopped) and deploy.restart_policy (condition none/on-failure/any → no/on-failure/always, max_attempts; it wins over restart, as deploy.md says; delay and window are warned about: the engine's backoff, 100 ms doubling to 1 min, applies), x- extensions.
  • Top level: name, services, networks (name, external, internal, labels), volumes (name, external, labels), include, x- extensions; version is obsolete (warning).
  • Loading rules: interpolation (${VAR}, :-, -, :?, ?, :+, +, $$) per file from the explicit environment over .env; merging (!reset, !override, volumes by target); extends (in the file or another one); include (each its own project); profiles (--profile, COMPOSE_PROFILES).
  • Validation: an attribute the specification does not define is an error (the specification's JSON schema, embedded, says which); one it defines that this engine does not apply (cap_add, logging, ...) is a warning, printed by every command. References (services, networks, volumes), dependency cycles, label prefixes, restart policies, durations are checked. Every error carries file:line:column.

The specification's own examples (75 Compose files in its text) go through both the official JSON schema and this loader in the tests: whatever the schema refuses is refused; what only this loader refuses is a deliberate refusal listed below.

Library

p, err := compose.Load(compose.Options{
	FS:          os.DirFS("lab"),          // nothing outside it is read
	Environment: map[string]string{"TAG": "1.2"},
	Profiles:    []string{"debug"},
})
out, err := compose.Marshal(p, compose.HCL)  // or compose.YAML, compose.JSON
Package What it does
compose Load (discovery, interpolation, merge, extends, include, profiles, validation) into Project; Marshal in the three formats; Runner drives the engine through its API client only (Up, Down, Start, Stop, Restart, Rm, Pull, Logs, Attach, Containers)
tree the position-carrying document the three readers produce: ParseYAML, ParseJSON, ParseHCL, all bounded
interp the specification's variable interpolation, bounded, never executing anything
dotenv env files in the specification's syntax
schema the embedded official JSON schema: which attributes exist where
imagebuild New(Options) compose.BuildFunc: builds build: sections with go-wasmcontainers/build, the context read from the project's file system only
cli the cobra command tree, Command(Options) *cobra.Command, for wctr compose
cmd/wctr-compose the command on its own

Performance

BenchmarkLoad50 loads a 50-service file (each with a command, environment, labels, two networks, a volume, a dependency and a health check). One core, Apple M4 Max, go1.27.1 — the machine's 1-minute load was 35–50, so the numbers are indicative:

Format Size Time Allocations
YAML 34 KB 2.1 ms 20k
JSON 51 KB 0.93 ms 11k
HCL2 33 KB 6.4–7.3 ms 59k (the HCL lexer's token buffer dominates)

The reference loader, compose-go v2.16.2, takes 49 ms and 674k allocations on the same YAML file (it also runs the full JSON-schema validation, which here runs in the tests). In a GOOS=js build, loading and writing the three formats weighed 5.4 MB over a baseline program, of which HCL2 (hcl + go-cty) is most; compose-go plus HCL2 would weigh 8.1 MB (docs/REFERENCES.md). Since the package also holds the engine driver, a program using it links the engine's API client (net/http) too: 11.5 MB in all against 4.4 MB for the baseline — inside wctr, which links that client already, the loader is the difference.

Security

Compose files are untrusted input: a teacher hands one to a class, the playground loads one from a page.

  • Bounded readers: 4 MiB per file, 64 levels of nesting, 262144 nodes after YAML alias expansion (the "billion laughs" document is refused, not expanded), 1 MiB per scalar, 64 MiB for all interpolations of a file together, 64 files per load (with include and extends), 8 levels of include, 16 of extends, 1000 services, 64 replicas per service, 256 containers per project.
  • HCL2 static context: no functions, no for; bracket nesting and the number of operators are checked on the tokens before the parser runs (it recurses on them); interpolations × the longest variable are bounded.
  • No execution: interpolation looks values up in a map; nothing is ever run by a shell.
  • No file outside the project: every path a Compose file names (env_file, include, extends.file, --env-file) resolves inside the project directory; absolute paths and .. past the top are refused, and natively the directory is opened with os.OpenRoot, so a symbolic link cannot leave it either. Build contexts and dockerfile paths too; remote (Git URL) build contexts are refused. No host bind mounts: a WebAssembly engine has no host filesystem to share (in a browser there is none).
  • Fuzzed in CI: the YAML, JSON and HCL2 readers, the interpolator, the env-file parser, and Load with its round trip through the three formats. govulncheck runs on every change.

Limitations

  • Health checks: what a healthcheck leaves unset (even test) comes from the image's own check, which the engine merges field by field, as Docker does; the engine's minimum interval is 100 ms.
  • Ports differ from the specification on one point, on purpose: a port that names no host address ("8080:80", or long syntax without host_ip) is published on 127.0.0.1, the engine's default, not on every interface (0.0.0.0) as the specification says — a lab container should not become a service on the machine's network by accident. Write "0.0.0.0:8080:80" (or host_ip: 0.0.0.0) when that is meant. mode, name and app_protocol are kept in the model and have no effect.
  • Builds: remote (Git URL) contexts, additional_contexts, cache_from / cache_to, platforms, secrets, ssh, build labels and the other build attributes are accepted with a warning and not applied; what the builder itself does not do yet is in go-wasmcontainers/build's README (shell-form RUN needs process spawning).
  • An engine older than v0.14.0 does not filter lists by label; compose refuses to act on what such an engine lists for another project (it checks every answer's label) rather than touch it.
  • wctr compose -f FILE ... needs wctr's root command to set cobra's TraverseChildren (global flags before the subcommand); the standalone wctr-compose sets it.
  • Refused on purpose: host bind mounts, tmpfs/image/npipe mounts, anonymous volumes, network_mode other than none, network drivers other than bridge, volume drivers other than local, files outside the project directory, image: oci:<dir> (an OCI layout on the host: wctr pull it first, then name the image), infinities and NaN.
  • Accepted with a warning and not applied: secrets, configs, models, and every other attribute the engine has no use for.
  • include conflicts are errors (the specification asks for a warning).
  • An x- extension whose name is not an HCL identifier cannot be written in HCL2 (config --format hcl says so).

References

Every format and rule is implemented from its specification; the list, with what each decides, is in docs/REFERENCES.md. "Compose Specification" is the name of the open specification at compose-spec.io; the label names it mandates (com.docker.compose.project, ...) are used as the specification says. Docker is a trademark of Docker, Inc.; this project is not affiliated with it.

License

BSD 3-Clause, see LICENSE. schema/compose-spec.json and testdata/compose-spec/ are the Compose Specification's, Apache-2.0 (their LICENSE files are beside them).

Documentation

Overview

Package compose loads Compose files — YAML, JSON or HCL2 — into the Compose Specification's application model, and runs that model on a go-wasmcontainers engine through its API.

Loading follows the specification (compose-spec/compose-spec): file discovery and override files, interpolation per file, merge rules (!reset, !override, unique keys), extends, include, profiles. Every input is bounded: a Compose file is untrusted.

Index

Constants

View Source
const (
	MaxServices   = 1000
	MaxReplicas   = 64
	MaxContainers = 256 // the engine's default --max-containers

)

Bounds of a project, beyond those of one file.

View Source
const (
	LabelProject         = "com.docker.compose.project"
	LabelService         = "com.docker.compose.service"
	LabelContainerNumber = "com.docker.compose.container-number"
	LabelConfigHash      = "com.docker.compose.config-hash"
	LabelImage           = "com.docker.compose.image"
	LabelOneoff          = "com.docker.compose.oneoff"
	LabelNetwork         = "com.docker.compose.network"
	LabelVolume          = "com.docker.compose.volume"
	LabelDependsOn       = "com.docker.compose.depends_on"
)

The labels a project's resources carry. The specification mandates the first two and reserves the prefix (02-model.md, container_spec.md); the others are the reference implementation's names (docs/REFERENCES.md).

View Source
const (
	ServiceStarted               = "service_started"
	ServiceHealthy               = "service_healthy"
	ServiceCompletedSuccessfully = "service_completed_successfully"
)

Dependency conditions (workload_spec.md, depends_on long syntax).

View Source
const DefaultHealthTimeout = 5 * time.Minute

DefaultHealthTimeout bounds the wait for one dependency to become healthy (UpOptions.HealthTimeout overrides it).

View Source
const ReservedLabelPrefix = "com.docker.compose"

ReservedLabelPrefix is the label prefix the specification reserves for the implementation (container_spec.md, labels).

Variables

View Source
var DefaultFileNames = []string{
	"compose.yaml", "compose.yml", "compose.json", "compose.hcl",
	"docker-compose.yaml", "docker-compose.yml",
}

DefaultFileNames are tried in order when no file is named: the specification's canonical names, ours, then its legacy ones.

View Source
var DefaultOverrideNames = []string{
	"compose.override.yaml", "compose.override.yml", "compose.override.json", "compose.override.hcl",
	"docker-compose.override.yaml", "docker-compose.override.yml",
}

DefaultOverrideNames are merged after the discovered file.

View Source
var ErrNoBuilder = errors.New("this service must be built, and no builder is configured")

ErrNoBuilder is returned when a build is needed and the Runner has no BuildFunc.

View Source
var ErrUnhealthy = errors.New("unhealthy")

ErrUnhealthy is a dependency whose health check reported unhealthy, or that stopped before it was healthy.

Functions

func ConfigHash

func ConfigHash(p *Project, s *Service) (string, error)

ConfigHash is a digest of everything that makes a service's container: a container whose label differs is recreated by up.

func Marshal

func Marshal(p *Project, f Format) ([]byte, error)

Marshal writes the normalised model in a format; loading the result gives the same model back (the round trip is tested for all three).

func NormalizeProjectName

func NormalizeProjectName(s string) string

NormalizeProjectName makes a directory name a project name: lowercase, only [a-z0-9_-], no leading '-' or '_' (as the reference loader does).

Types

type Build

type Build struct {
	// Context is the build context's directory in the project's file
	// system (resolved from the Compose file's directory).
	Context string `json:"context"`
	// Dockerfile is relative to Context (default Containerfile, else
	// Dockerfile); DockerfileInline is the file's content instead.
	Dockerfile       string             `json:"dockerfile,omitempty"`
	DockerfileInline string             `json:"dockerfile_inline,omitempty"`
	Args             map[string]*string `json:"args,omitempty"`
	Target           string             `json:"target,omitempty"`
	// Tags name the built image besides the service's image name.
	Tags    []string `json:"tags,omitempty"`
	NoCache bool     `json:"no_cache,omitempty"`
}

Build is a service's build section (build.md), built by go-wasmcontainers/build through the engine.

type BuildFunc added in v0.2.0

type BuildFunc func(ctx context.Context, p *Project, s *Service, noCache bool) (string, error)

BuildFunc builds a service's image (tagged with p.ImageName(s) and its build tags) and returns its ID. Package imagebuild provides one, over go-wasmcontainers/build; the loader itself does not link a builder.

type Command

type Command []string

Command is a command line: nil is "the image's", an empty non-nil one clears the image's.

type Container

type Container struct {
	api.ContainerSummary
	Name    string
	Service string
	Number  int
}

Container is a project's container as the engine lists it.

func (Container) Live added in v0.5.0

func (c Container) Live() bool

Live says whether a container runs or waits to run again under its restart policy (the engine's "restarting" state): stop and rm treat both as running, start and up leave both alone.

type Dependency

type Dependency struct {
	Condition string `json:"condition"`
	Restart   bool   `json:"restart,omitempty"`
	Required  bool   `json:"required"`
}

Dependency is one depends_on entry.

type Format

type Format string

Format is a Compose file format.

const (
	YAML Format = "yaml"
	JSON Format = "json"
	HCL  Format = "hcl"
)

The formats a project can be written in.

type Healthcheck

type Healthcheck struct {
	Test          []string       `json:"test,omitempty"`
	Interval      *time.Duration `json:"interval,omitempty"`
	Timeout       *time.Duration `json:"timeout,omitempty"`
	StartPeriod   *time.Duration `json:"start_period,omitempty"`
	StartInterval *time.Duration `json:"start_interval,omitempty"`
	Retries       *int64         `json:"retries,omitempty"`
	Disable       bool           `json:"disable,omitempty"`
}

Healthcheck is a service's health check.

type Mount

type Mount struct {
	Type     string `json:"type"`
	Source   string `json:"source"`
	Target   string `json:"target"`
	ReadOnly bool   `json:"read_only,omitempty"`
}

Mount is a volume mounted into a service's containers. Only named volumes exist on this engine (Type "volume").

type Network

type Network struct {
	// Name is the network's name in the engine: "<project>_<key>" unless
	// set, the key itself when external.
	Name       string            `json:"name"`
	External   bool              `json:"external,omitempty"`
	Driver     string            `json:"driver,omitempty"`
	Internal   bool              `json:"internal,omitempty"`
	Labels     map[string]string `json:"labels,omitempty"`
	Extensions map[string]any    `json:"-"`
}

Network is a top-level network.

type Options

type Options struct {
	// FS holds the project; every path below is slash-separated and
	// relative to it, and nothing outside it is ever read. Natively, the
	// CLI roots it at the project directory (os.OpenRoot, so symbolic
	// links cannot leave it either); in a browser it is the page's files.
	FS fs.FS
	// WorkingDir is the project directory in FS (default ".").
	WorkingDir string
	// Files are the Compose files (-f), in merge order. Empty: discover
	// compose.yaml (or .yml, .json, .hcl, or a legacy name) and its
	// compose.override.* in WorkingDir.
	Files []string
	// ProjectName overrides every other source of the name (-p).
	ProjectName string
	// DefaultName is the name when no other source gives one (default:
	// WorkingDir's base name, normalised).
	DefaultName string
	// Environment is the explicit environment interpolation reads, over
	// the env files (natively the CLI passes its process environment; a
	// browser has none).
	Environment map[string]string
	// EnvFiles replace the default ".env" of WorkingDir (--env-file).
	EnvFiles []string
	// Profiles are the active profiles (with COMPOSE_PROFILES).
	Profiles []string
	// Limits bound each file read; zero fields take tree.DefaultLimits.
	Limits tree.Limits
}

Options say what to load.

type Port added in v0.4.0

type Port struct {
	// Target is the container port or range ("80", "80-81").
	Target string `json:"target"`
	// Published is the host port or range; empty for one the system
	// picks.
	Published string `json:"published,omitempty"`
	// HostIP is the host address; empty is the engine's default,
	// 127.0.0.1 (the specification says 0.0.0.0: see the README).
	HostIP string `json:"host_ip,omitempty"`
	// Protocol is "tcp" (default) or "udp".
	Protocol    string `json:"protocol,omitempty"`
	Name        string `json:"name,omitempty"`
	AppProtocol string `json:"app_protocol,omitempty"`
	Mode        string `json:"mode,omitempty"`
}

Port is a published port (workload_spec.md, ports, long syntax).

func (Port) Spec added in v0.4.0

func (p Port) Spec() string

Spec is the port as `wctr run -p` writes it: [IP:][HOST:]CONTAINER/PROTO.

type Project

type Project struct {
	// Name is the project name: lowercase letters, digits, '-' and '_'.
	Name string `json:"name"`
	// WorkingDir is the project directory (in Options.FS).
	WorkingDir string `json:"-"`
	// Files are the Compose files read, in order.
	Files []string `json:"-"`
	// Services are the enabled services; DisabledServices those whose
	// profiles are not active.
	Services         map[string]*Service `json:"services"`
	DisabledServices map[string]*Service `json:"-"`
	Networks         map[string]*Network `json:"networks,omitempty"`
	Volumes          map[string]*Volume  `json:"volumes,omitempty"`
	// Extensions are the top-level `x-` keys.
	Extensions map[string]any `json:"-"`
	// Environment is what interpolation read (explicit environment over
	// .env), with COMPOSE_PROJECT_NAME.
	Environment map[string]string `json:"-"`
	// Warnings are what was accepted but is not applied (unsupported
	// attributes, unset variables).
	Warnings []string `json:"-"`
}

Project is a loaded, merged and validated Compose application model.

func Load

func Load(opt Options) (*Project, error)

Load reads, merges and validates a project.

func (*Project) ContainerName

func (p *Project) ContainerName(s *Service, n int) string

ContainerName is the name of a service's container number n.

func (*Project) EnableServices

func (p *Project) EnableServices(names ...string) error

EnableServices activates services named on a command line, with their profiles (Compose Specification, profiles: an explicitly targeted service is enabled), and the dependencies they pull in.

func (*Project) ImageName added in v0.2.0

func (p *Project) ImageName(s *Service) string

ImageName is the image a service's containers run: its `image`, else "<project>-<service>" for a service that is built (as the reference implementation names it; build.md lets an implementation compute one).

func (*Project) Order

func (p *Project) Order() []string

Order returns the enabled services, dependencies first (ties by name).

func (*Project) ServiceNames

func (p *Project) ServiceNames() []string

ServiceNames returns the enabled services' names, sorted.

func (*Project) Tree

func (p *Project) Tree() *tree.Node

Tree returns the normalised model as a document: long syntax everywhere, keys sorted, defaults made explicit.

type RestartPolicy added in v0.5.0

type RestartPolicy struct {
	Condition   string `json:"condition"`
	MaxAttempts *int64 `json:"max_attempts,omitempty"`
}

RestartPolicy is deploy.restart_policy (deploy.md): condition none, on-failure or any (default), max_attempts (absent: never give up).

type Runner

type Runner struct {
	Client *api.Client
	// Build builds a service's image (nil: services that need building
	// fail with ErrNoBuilder).
	Build BuildFunc
	// Out receives progress and logs; Err warnings.
	Out, Err io.Writer
}

Runner drives an engine through its API, as the compose CLI drives a daemon: it never reaches the engine any other way.

func (*Runner) Attach

func (r *Runner) Attach(ctx context.Context, p *Project, services []string) error

Attach follows the logs of the project's containers until they have all exited, or ctx is done (then they are stopped): `up` without -d.

func (*Runner) BuildServices added in v0.2.0

func (r *Runner) BuildServices(ctx context.Context, p *Project, services []string, noCache bool) error

BuildServices builds the services that have a build section (all of them when none is named): `compose build`.

func (*Runner) Containers

func (r *Runner) Containers(ctx context.Context, project string) ([]Container, error)

Containers lists the project's containers (all states), sorted by service then number; the engine filters them by the project's label.

func (*Runner) Down

func (r *Runner) Down(ctx context.Context, p *Project, volumes bool) error

Down stops and removes the project's containers and networks, and with volumes its volumes (never external ones).

func (*Runner) Logs

func (r *Runner) Logs(ctx context.Context, p *Project, services []string, follow bool) error

Logs writes the containers' logs, each line prefixed by the container's name; with follow it returns when every stream has ended (each container exited) or ctx is done.

func (*Runner) Pull

func (r *Runner) Pull(ctx context.Context, p *Project, services []string) error

Pull pulls the services' images.

func (*Runner) Restart

func (r *Runner) Restart(ctx context.Context, p *Project, services []string) error

Restart restarts the services' containers.

func (*Runner) Rm

func (r *Runner) Rm(ctx context.Context, p *Project, services []string, stop bool) error

Rm removes the services' stopped containers (running ones too with stop).

func (*Runner) Start

func (r *Runner) Start(ctx context.Context, p *Project, services []string) error

Start starts the services' existing containers, dependencies first.

func (*Runner) Stop

func (r *Runner) Stop(ctx context.Context, p *Project, services []string) error

Stop stops the services' running (or restarting) containers, dependents first; a stop ends a restart policy until the next start.

func (*Runner) Up

func (r *Runner) Up(ctx context.Context, p *Project, o UpOptions) error

Up creates what is missing and (re)starts the project's containers, dependencies first; a container whose configuration did not change is kept (started again if it stopped).

type Service

type Service struct {
	Name        string            `json:"-"`
	Image       string            `json:"image,omitempty"`
	Build       *Build            `json:"build,omitempty"`
	Command     Command           `json:"command,omitempty"`
	Entrypoint  Command           `json:"entrypoint,omitempty"`
	Environment map[string]string `json:"environment,omitempty"`
	WorkingDir  string            `json:"working_dir,omitempty"`
	Volumes     []Mount           `json:"volumes,omitempty"`
	Ports       []Port            `json:"ports,omitempty"`
	// Expose are container ports reachable on the service's networks and
	// not published ("80", "8000-8010/udp").
	Expose      []string                   `json:"expose,omitempty"`
	Networks    map[string]*ServiceNetwork `json:"networks,omitempty"`
	NetworkMode string                     `json:"network_mode,omitempty"`
	DependsOn   map[string]Dependency      `json:"depends_on,omitempty"`
	Healthcheck *Healthcheck               `json:"healthcheck,omitempty"`
	Restart     string                     `json:"restart,omitempty"`
	// RestartPolicy is deploy.restart_policy; it wins over Restart
	// (deploy.md: restart applies when restart_policy is not set).
	RestartPolicy *RestartPolicy    `json:"restart_policy,omitempty"`
	Replicas      int               `json:"replicas"`
	Labels        map[string]string `json:"labels,omitempty"`
	Profiles      []string          `json:"profiles,omitempty"`
	ContainerName string            `json:"container_name,omitempty"`
	Extensions    map[string]any    `json:"-"`
}

Service is one service.

func (*Service) EngineRestart added in v0.5.0

func (s *Service) EngineRestart() (name string, maxRetries int)

EngineRestart is the engine's restart policy for the service: deploy.restart_policy when set, else restart. Name is "" when the service sets neither (the engine's default, no restart).

type ServiceNetwork

type ServiceNetwork struct {
	Aliases []string `json:"aliases,omitempty"`
}

ServiceNetwork is a service's place on a network.

type UpOptions

type UpOptions struct {
	// Services limits up to these services and their dependencies.
	Services []string
	// ForceRecreate recreates containers even when nothing changed.
	ForceRecreate bool
	// Build asks to build images first (needs the builder).
	Build bool
	// RemoveOrphans removes containers of services no longer defined.
	RemoveOrphans bool
	// HealthTimeout bounds the wait for each service_healthy dependency
	// (0: DefaultHealthTimeout).
	HealthTimeout time.Duration
}

UpOptions are `up`'s.

type Volume

type Volume struct {
	Name       string            `json:"name"`
	External   bool              `json:"external,omitempty"`
	Driver     string            `json:"driver,omitempty"`
	Labels     map[string]string `json:"labels,omitempty"`
	Extensions map[string]any    `json:"-"`
}

Volume is a top-level named volume.

Directories

Path Synopsis
Package cli is the `wctr compose` command tree: an exported cobra command the engine's wctr wires as a subcommand, and that cmd/wctr-compose runs on its own.
Package cli is the `wctr compose` command tree: an exported cobra command the engine's wctr wires as a subcommand, and that cmd/wctr-compose runs on its own.
cmd
wctr-compose command
Command wctr-compose is `wctr compose` on its own: the same command tree (package cli), until the engine's wctr wires it as a subcommand.
Command wctr-compose is `wctr compose` on its own: the same command tree (package cli), until the engine's wctr wires it as a subcommand.
Package dotenv reads env files in the Compose Specification's format (container_spec.md, "Env_file format"): `VAR=VAL` lines, `#` comments, unquoted and double-quoted values interpolated, single-quoted values literal, `\` escapes, an optional `export ` prefix; a line with a bare `VAR` takes VAR from the lookup, or leaves it unset.
Package dotenv reads env files in the Compose Specification's format (container_spec.md, "Env_file format"): `VAR=VAL` lines, `#` comments, unquoted and double-quoted values interpolated, single-quoted values literal, `\` escapes, an optional `export ` prefix; a line with a bare `VAR` takes VAR from the lookup, or leaves it unset.
Package imagebuild builds the images of a Compose project's `build:` sections with go-wasmcontainers/build, through the engine's API: the context is read from the project's file system (never outside it), the Containerfile (or Dockerfile, or dockerfile_inline) with it.
Package imagebuild builds the images of a Compose project's `build:` sections with go-wasmcontainers/build, through the engine's API: the context is read from the project's file system (never outside it), the Containerfile (or Dockerfile, or dockerfile_inline) with it.
Package interp implements the Compose Specification's variable interpolation: `$VAR`, `${VAR}`, `${VAR:-default}`, `${VAR-default}`, `${VAR:?error}`, `${VAR?error}`, and the reference implementation's `${VAR:+replacement}` and `${VAR+replacement}`; `$$` is a literal `$`.
Package interp implements the Compose Specification's variable interpolation: `$VAR`, `${VAR}`, `${VAR:-default}`, `${VAR-default}`, `${VAR:?error}`, `${VAR?error}`, and the reference implementation's `${VAR:+replacement}` and `${VAR+replacement}`; `$$` is a literal `$`.
Package schema embeds the Compose Specification's JSON schema (compose-spec/compose-spec, schema/compose-spec.json, Apache-2.0; see LICENSE in this directory) and answers which attributes it defines where.
Package schema embeds the Compose Specification's JSON schema (compose-spec/compose-spec, schema/compose-spec.json, Apache-2.0; see LICENSE in this directory) and answers which attributes it defines where.
Package tree is the format-neutral document a Compose file is read into: mappings (ordered, unique keys), sequences and scalars, each carrying the file, line and column it came from.
Package tree is the format-neutral document a Compose file is read into: mappings (ordered, unique keys), sequences and scalars, each carrying the file, line and column it came from.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL