docker

package
v1.5.2 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package docker is a Docker-backed provider.Provider. It maps each ctrlplane Instance to one Docker container, named "cp-<instanceID>" so lookups by ID are O(1) inspect calls.

Index

Constants

This section is empty.

Variables

View Source
var ErrLogsNotImplemented = errors.New("docker: logs not implemented")

ErrLogsNotImplemented is returned when log streaming is requested but the docker exec/logs path hasn't been wired yet.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Host is the Docker daemon address (e.g., unix:///var/run/docker.sock).
	Host string `env:"CP_DOCKER_HOST" json:"host"`

	// Network is the Docker network to attach containers to.
	Network string `default:"bridge" env:"CP_DOCKER_NETWORK" json:"network"`

	// Registry is the default image registry prefix.
	Registry string `env:"CP_DOCKER_REGISTRY" json:"registry,omitempty"`
}

Config holds configuration for the Docker provider.

type Option added in v1.3.0

type Option func(*Provider) error

Option configures a Docker provider.

func WithConfig added in v1.3.0

func WithConfig(cfg Config) Option

WithConfig applies all non-zero fields from a Config struct. This is useful when loading configuration from files or environment variables.

func WithHost added in v1.3.0

func WithHost(host string) Option

WithHost sets the Docker daemon address (e.g., "unix:///var/run/docker.sock").

func WithNetwork added in v1.3.0

func WithNetwork(network string) Option

WithNetwork sets the Docker network to attach containers to.

func WithRegistry added in v1.3.0

func WithRegistry(registry string) Option

WithRegistry sets the default image registry prefix.

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider is a Docker-based infrastructure provider. Each Instance becomes one container; the container name encodes the instance ID for stateless lookups (no per-instance ProviderRef storage needed beyond the canonical "docker:<container_name>" string).

func New

func New(opts ...Option) (*Provider, error)

New creates a new Docker provider. Uses standard docker env (DOCKER_HOST, DOCKER_TLS_VERIFY, etc.) by default; pass WithHost to pin a specific socket. Network defaults to "bridge" but should be overridden to a named network when the provider is colocated with a router (e.g. Traefik) that needs to reach containers by DNS name.

func (*Provider) Capabilities

func (p *Provider) Capabilities() []provider.Capability

Capabilities returns the set of features this provider supports.

func (*Provider) Deploy

Deploy applies a new image / env to an existing container by recreating it. Docker doesn't support in-place image swap, so the implementation is: stop+remove the current container, then create a fresh one with the new spec. Same name, same network, new image.

For the initial provision case (where Provision already ran with the right image) Deploy is effectively a no-op — the container stays as-is. The caller (ctrlplane deploy.Service) treats success here as "release applied" and bumps the deployment state. Deploy applies per-service image / env updates by recreating only the targeted containers within the live project network. Services not listed in req.Services keep running unchanged.

Per-service rollout for a multi-container project is "stop & replace each targeted container in turn" — Docker doesn't support in-place image swap. The Compose-project network stays up across the recreation so sibling services don't drop their network namespace.

func (*Provider) Deprovision

func (p *Provider) Deprovision(ctx context.Context, instanceID id.ID) error

Deprovision tears down every container in the project + the project network. Not-found is treated as success so deprovision is convergent — the goal is "project gone", not strict accounting.

func (*Provider) Exec

Exec is not yet implemented.

func (*Provider) HealthCheck added in v1.5.1

func (p *Provider) HealthCheck(ctx context.Context) (*provider.HealthStatus, error)

HealthCheck pings the docker daemon and reports reachability. The HealthChecker contract is "is this provider's control plane reachable" — so we use cli.Ping (which round-trips to the daemon) rather than docker info / version which load more state.

func (*Provider) Info

func (p *Provider) Info() provider.ProviderInfo

Info returns metadata about this provider. Local Docker has a fixed region of "local" with a default localhost location so studio catalog endpoints surface a usable region in dev environments where no datacenters have been registered yet.

func (*Provider) Logs

func (p *Provider) Logs(ctx context.Context, instanceID id.ID, opts provider.LogOptions) (io.ReadCloser, error)

Logs returns a stream of structured JSON log events (one {"ts":..., "stream":"stdout"|"stderr", "line":"..."} per line) from the container's stdout + stderr. When opts.Follow is true the stream stays open and emits new lines as the container writes them; the caller closes the returned ReadCloser to stop.

Honours opts.Tail (last N lines, "0" = all), opts.Since (only lines newer than this UTC time), and opts.Follow. Multiplexed docker frames are demuxed by demuxedDockerStream.

func (*Provider) Provision

Provision pulls the image, creates a container with the requested ports/env/labels, starts it, and returns the resulting endpoints.

Endpoints are emitted in two flavours per declared port:

  • in-network: http://cp-<instanceID>:<containerPort> — reachable from other containers on the same docker network. Preferred for service-to-service routing (Traefik joins this network and uses these URLs upstream).
  • public: http://localhost:<hostPort> — the random host port docker assigned. Useful when hitting a workspace from outside the docker network without a host-side proxy.

Re-provisioning the same instance ID is idempotent: any existing container with the same name is force-removed first so the create succeeds with the fresh config.

func (*Provider) Resources

func (p *Provider) Resources(ctx context.Context, instanceID id.ID) (*provider.ResourceUsage, error)

Resources returns a one-shot point-in-time sample of the container's CPU / memory / network usage via the docker stats API. The non-streaming variant gives us a single JSON document per call, which is what the metrics poller wants — it calls us every N seconds and stores the result in its own ring buffer.

Returns a zero-valued ResourceUsage (no error) when the container doesn't exist or the stats response is empty — the metrics poller treats "missing sample" as a gap, not a failure, so transient container-restart windows don't show up as poller errors.

func (*Provider) Restart

func (p *Provider) Restart(ctx context.Context, instanceID id.ID) error

Restart cycles every Main + Sidecar container in the project. Inits stay completed — restart is for live workload bouncing, not init re-runs.

func (*Provider) Rollback

func (p *Provider) Rollback(_ context.Context, _ id.ID, _ id.ID) error

Rollback is a no-op today — docker has no built-in release history, so rollback would have to recreate using the previous image which the deploy service already knows about and could route through Deploy.

func (*Provider) Scale

func (p *Provider) Scale(_ context.Context, _ id.ID, _ provider.ResourceSpec) error

Scale is a no-op for the docker provider — single-container instances don't have a horizontal scale axis. The kubernetes provider is the right home for replica scaling.

func (*Provider) Start

func (p *Provider) Start(ctx context.Context, instanceID id.ID) error

Start starts every Main + Sidecar container in the project. Init services are not restarted — they ran-once during provision.

func (*Provider) Status

func (p *Provider) Status(ctx context.Context, instanceID id.ID) (*provider.InstanceStatus, error)

Status aggregates inspect across every container in the project. Worst-of state wins (any Failed → Failed; otherwise any Restarting → Starting; otherwise any not-Running → Stopped). Ready is true only when every Main + Sidecar reports Running. Init containers don't gate readiness once they've completed (they appear as Stopped/exited 0 — the non-Init aggregation ignores them).

func (*Provider) Stop

func (p *Provider) Stop(ctx context.Context, instanceID id.ID) error

Stop sends SIGTERM to every Main + Sidecar container in the project. Default docker timeout (~10s) per container.

Jump to

Keyboard shortcuts

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