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

docker

package
v0.2.0-rc.1 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package docker drives a container engine (Docker, Podman, Colima or OrbStack) through the Docker Engine API over its socket, with only the standard library. A Client finds its engine on first use; without one, Available is false and services fall back to metadata only.

Index

Constants

View Source
const (
	LabelManaged  = "pogi.managed"  // "true"
	LabelOwner    = "pogi.owner"    // the Client that made it: host/pid/random
	LabelService  = "pogi.service"  // e.g. rds
	LabelResource = "pogi.resource" // e.g. the DB instance id
	LabelData     = "pogi.data"     // with saved state: the absolute data dir the container belongs to
)

Labels on every container pogi runs.

Variables

View Source
var CallLimit = 2 * time.Minute

CallLimit is how long one engine call (create, start, inspect, remove, exec) may take before pogi gives up on it. Pulls have their own limits; Logs and Wait follow their contexts. Tests shorten it.

Functions

func DataInUse

func DataInUse(dir string) bool

DataInUse reports whether a pogi that still runs uses the data dir.

func EngineDown added in v0.2.0

func EngineDown(err error) bool

EngineDown reports whether err is the engine not answering (not running, cut off, or too slow).

func Name

func Name(service, resource string) string

Name is the container name of a resource, pogi-<service>-<resource>, with the characters Docker refuses replaced by '-'.

func NotFound added in v0.2.0

func NotFound(err error) bool

NotFound reports whether the engine said the container (or image) doesn't exist.

func Orphan

func Orphan(labels map[string]string) bool

Orphan reports whether something pogi made (a container or volume, by its labels) was left by a pogi that no longer runs. Nothing without the managed label counts, and nothing of a data dir in use: a container that a later run took over keeps the label of the run that made it.

func Plain added in v0.2.0

func Plain(err error) string

Plain turns an engine failure into a plain sentence, with Docker's own text after " — ". The sentences: Docker isn't running, the image wasn't found, the registry can't be reached, the disk is full, and the two download limits.

Types

type Client

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

Client runs the containers of one pogi instance.

func New

func New(o Options) *Client

New returns a Client; it looks for the engine on first use.

func (*Client) Addr

func (c *Client) Addr(hostPort int) string

Addr is host:port for a container's tcp port that was published on hostPort of the host. Nested, that port is not reachable from pogi's container, so it is the container's address on the pogi network and its own port.

func (*Client) Available

func (c *Client) Available() bool

Available reports whether an engine answers.

func (*Client) Close

func (c *Client) Close()

Close ends this pogi's containers (services remove their own transient ones before). With persisted state it stops them, and the next run starts them again; otherwise it removes them, and the volumes this Client made.

func (*Client) Commit

func (c *Client) Commit(ctx context.Context, id, repo, tag string) error

Commit saves a container's filesystem as the image repo:tag.

func (*Client) CopyFrom

func (c *Client) CopyFrom(ctx context.Context, id, path string) (io.ReadCloser, error)

CopyFrom returns a tar archive of a file or directory in a container (created, running or stopped); the caller closes it.

func (*Client) CopyTo

func (c *Client) CopyTo(ctx context.Context, id, dir string, tar io.Reader) error

CopyTo unpacks a tar archive into a directory of a container (created or running).

func (*Client) Create

func (c *Client) Create(ctx context.Context, ct *Container) (string, error)

Create makes a container, pulling its image when missing, and returns its id.

func (*Client) Engine

func (c *Client) Engine() (e Engine, ok bool)

Engine describes the engine in use; ok is false when none answers.

func (*Client) Exec

func (c *Client) Exec(ctx context.Context, id string, cmd ...string) ([]byte, int, error)

Exec runs a command in a running container and returns its output (stdout and stderr together) and exit code.

func (*Client) HasImage

func (c *Client) HasImage(ctx context.Context, image string) (bool, error)

HasImage reports whether the engine holds an image, without pulling it.

func (*Client) HasVolume added in v0.2.0

func (c *Client) HasVolume(ctx context.Context, name string) bool

HasVolume reports whether a named volume exists.

func (*Client) HostAddr

func (c *Client) HostAddr() string

HostAddr is the host containers reach pogi's listeners at. Engines behind a VM (Docker Desktop, OrbStack, Colima, Podman machine) forward host.docker.internal to this machine's loopback. A Linux engine on this kernel cannot route its bridges to 127.0.0.1, so there it is 127.0.0.1 and a container that calls pogi needs Network "host".

Nested (pogi runs in a container), it is pogi's address on the pogi network.

func (*Client) Inspect

func (c *Client) Inspect(ctx context.Context, id string) (*Info, error)

Inspect describes a container: its state and the host ports it got.

func (*Client) List

func (c *Client) List(ctx context.Context, labels ...string) ([]Summary, error)

List returns the containers, running or not, that carry every label (key=value).

func (*Client) ListenAddr

func (c *Client) ListenAddr() string

ListenAddr is the address to listen on for something a container calls: pogi's address on the pogi network when nested, else loopback.

func (*Client) Logs

func (c *Client) Logs(ctx context.Context, id string, follow bool, line func(string)) error

Logs calls line with each line a container wrote to stdout or stderr; with follow it reads on until the container stops (or ctx ends). ponytail: containers made with a TTY send raw streams; pogi makes none.

func (*Client) Mine

func (c *Client) Mine(ctx context.Context) []Summary

Mine lists this pogi's containers, running or not: with a data dir all those of it (an earlier run made some), else those this Client made. It finds none when no engine was ever used.

func (*Client) Pull

func (c *Client) Pull(ctx context.Context, image string) error

Pull pulls an image (its latest tag when it names none) with the credentials of ~/.docker/config.json, logging progress.

func (*Client) Remove

func (c *Client) Remove(ctx context.Context, id string) error

Remove deletes a container, running or not, with its anonymous volumes; a missing one is no error. When another call is already removing it (409), Remove waits until it is gone: until then its named volumes are still in use, and removing them right after would fail (a leaked volume).

func (*Client) RemoveImage

func (c *Client) RemoveImage(ctx context.Context, image string) error

RemoveImage deletes an image by name; a missing one, or one a container still uses, is no error.

func (*Client) RemoveLeftover added in v0.2.0

func (c *Client) RemoveLeftover(ctx context.Context, name string) error

RemoveLeftover removes the container called name, so that this pogi can make one of that name: a leftover of a crashed run, or one it replaces. A container of another pogi that still runs, or one pogi did not make, stays, and the error says so: two pogis on one machine must not take each other's containers.

func (*Client) RemoveVolume

func (c *Client) RemoveVolume(ctx context.Context, name string) error

RemoveVolume deletes a named volume; a missing or busy one is no error.

func (*Client) Resolve added in v0.2.0

func (c *Client) Resolve(service, image string) string

Resolve is the image a service runs for image: the docker.images override of "<service>.<image name>", and the images of cloud registries from pogi's own. Create uses it, and so does pogi pull.

func (*Client) Restart

func (c *Client) Restart(ctx context.Context, id string) error

Restart stops a container and starts it again, and returns once the engine says which host port publishes each of its ports (see published).

func (*Client) Run

func (c *Client) Run(ctx context.Context, ct *Container) (string, error)

Run creates a container and starts it; one that fails to start is removed.

func (*Client) Start

func (c *Client) Start(ctx context.Context, id string) error

Start starts a created or stopped container, and returns once the engine says which host port publishes each of its ports (see published).

func (*Client) Stop

func (c *Client) Stop(ctx context.Context, id string) error

Stop stops a container, killing it after its stop timeout.

func (*Client) Sweep

func (c *Client) Sweep()

Sweep removes the containers and volumes that a pogi which no longer runs left behind; with persisted state they stay, as services resume them. pogi calls it at startup.

func (*Client) Tasks added in v0.2.0

func (c *Client) Tasks() *Tasks

Tasks returns the tasks of this client.

func (*Client) Track added in v0.2.0

func (c *Client) Track(service, resource, kind, what string) *Tracker

Track starts a task: kind is "download" or "start", what the image.

func (*Client) Volumes

func (c *Client) Volumes(ctx context.Context, labels ...string) ([]Volume, error)

Volumes returns the volumes that carry every label (key=value).

func (*Client) Wait

func (c *Client) Wait(ctx context.Context, id string) (int, error)

Wait blocks until a container stops and returns its exit code.

func (*Client) Watch added in v0.2.0

func (c *Client) Watch(ctx context.Context, id string, exited func(note string))

Watch calls exited once, with a plain sentence, when the container stops on its own: "killed: out of memory (raise Docker's memory limit)", or "stopped: exit <code> — <last log line>". It says nothing when ctx ends, or when the engine can't be asked (then nothing is known). Call it after the container starts.

type Container

type Container struct {
	Name       string            // see Name; empty: the engine picks one
	Image      string            // pulled when missing; docker.images in pogi.yaml may override it
	Service    string            // pogi.service label, and the prefix of image overrides
	Resource   string            // pogi.resource label
	Labels     map[string]string // more labels
	Env        []string          // KEY=value
	Cmd        []string
	Entrypoint []string
	WorkDir    string
	Ports      map[int]int // container tcp port → host port on 127.0.0.1; 0 picks a free one
	Binds      []string    // host-path:container-path[:ro], or volume:container-path
	ExtraHosts []string    // name:ip
	Network    string      // default: the pogi network; "host" shares the host's
	Aliases    []string    // more DNS names on the network
	Memory     int64       // bytes; 0: no limit
	CPUs       float64     // 0: no limit

	Privileged bool              // every device and capability of the host (k3s)
	CapAdd     []string          // more capabilities, e.g. NET_ADMIN
	Tmpfs      map[string]string // container path → mount options ("" for defaults)
}

Container is what Create makes. Only Image is required.

type Engine

type Engine struct {
	Name    string // Docker Desktop, OrbStack, Colima, Podman or Docker
	Socket  string // where it answered: unix:///… or tcp://…
	Version string // engine version
	API     string // Engine API version in use
}

Engine is the container engine a Client talks to.

type Info

type Info struct {
	ID    string `json:"Id"`
	Name  string
	Image string
	State struct {
		Status    string // created, running, exited…
		Running   bool
		ExitCode  int
		OOMKilled bool // the engine killed it for lack of memory
	}
	Config struct {
		Labels map[string]string
	}
	HostConfig struct {
		NetworkMode  string
		PortBindings map[string][]struct{ HostIp, HostPort string } // what was asked for: HostPort "" means any free one
	}
	Mounts          []Mount
	NetworkSettings struct {
		Ports    map[string][]struct{ HostIp, HostPort string }
		Networks map[string]struct {
			IPAddress string
			Aliases   []string
		}
	}
}

Info is what Inspect tells about a container.

func (*Info) HostPort

func (i *Info) HostPort(port int) int

HostPort is the host port that publishes a container's tcp port, or 0.

type Mount

type Mount struct {
	Type        string // bind, volume, tmpfs
	Name        string // of a volume
	Source      string // on the engine's host
	Destination string // in the container
}

Mount is a mount of a container, as Inspect reports it.

type Options

type Options struct {
	Host    string            // engine socket or URL; empty: $DOCKER_HOST, then the usual sockets
	Network string            // network of managed containers; default "pogi"
	Images  map[string]string // image overrides by "<service>.<image name>", e.g. rds.postgres
	Keep    bool              // state is persisted: Close stops containers (the next run starts them again) and Sweep leaves them
	DataDir string            // with Keep: the absolute data dir; containers are labelled with it, so a later run finds them
	ECR     string            // pogi's registry, which serves the images of the registries in registryHosts, e.g. localhost:4510
	Log     *slog.Logger
}

Options configure a Client; the zero value finds the engine the docker CLI would.

type Summary

type Summary struct {
	ID     string `json:"Id"`
	Names  []string
	Image  string
	State  string
	Labels map[string]string
	Ports  []struct {
		PrivatePort, PublicPort int
		Type                    string
	}
	NetworkSettings struct {
		Networks map[string]struct{ IPAddress string }
	}
}

Summary is a container in a List.

type Task added in v0.2.0

type Task struct {
	ID       string    `json:"id"`
	Service  string    `json:"service"`
	Resource string    `json:"resource"`
	Kind     string    `json:"kind"` // download or start
	What     string    `json:"what"` // the image
	Done     int64     `json:"done"`
	Total    int64     `json:"total"`
	State    string    `json:"state"` // running, done or failed
	Error    string    `json:"error"` // a plain sentence; Docker's own text may follow " — "
	Since    time.Time `json:"since"`
	// contains filtered or unexported fields
}

Task is background work for the console: an image download, or a container start that has not yet answered. Done and Total are bytes (Total 0: not known).

func (Task) Finished added in v0.2.0

func (t Task) Finished() time.Time

Finished is when a done or failed task ended.

type Tasks added in v0.2.0

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

Tasks is the list of a Client's tasks.

func (*Tasks) List added in v0.2.0

func (ts *Tasks) List() []Task

List is what GET /_pogi/tasks shows: running tasks, and finished ones for 60 seconds.

func (*Tasks) Recent added in v0.2.0

func (ts *Tasks) Recent(maxAge time.Duration) []Task

Recent lists the running tasks and those finished within the last maxAge, oldest first. The console's task list uses a minute; the bell looks back further.

type Tracker added in v0.2.0

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

Tracker updates one task.

func (*Tracker) End added in v0.2.0

func (tr *Tracker) End(err error)

End finishes the task; err (when not nil) is shown as a plain sentence. Only the first call counts.

func (*Tracker) Progress added in v0.2.0

func (tr *Tracker) Progress(done, total int64)

Progress records the bytes done of total (0: not known).

type Volume

type Volume struct {
	Name   string
	Labels map[string]string
}

Volume is a Docker volume in Volumes.

Directories

Path Synopsis
Package dockertest fakes the Docker Engine API, so tests of services that run containers pass without an engine.
Package dockertest fakes the Docker Engine API, so tests of services that run containers pass without an engine.

Jump to

Keyboard shortcuts

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