containuum

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 21, 2025 License: MIT Imports: 13 Imported by: 0

README

Containuum

Containuum is a library for subscribing to changes in container state. It monitors the event stream from docker, and emits deduplicated lists of containers to subscribers. It's intended to be used by tools that automatically generate config files based on container labels (e.g. for a reverse proxy), or perform other updates when a container starts/stops (e.g. adding DNS entries).

Basic usage

Containuum exposes a "Run" function which takes a context, a callback, and options. The Run function blocks until it fails or the context is cancelled.

package main

import (
	"context"
	"log/slog"

	"github.com/csmith/containuum"
)

func main() {
	err := containuum.Run(
		context.Background(),
		func(containers []containuum.Container) {
			slog.Info("Received containers", "count", len(containers))
		},
		containuum.WithFilter(containuum.LabelExists("web")),
	)
	if err != nil {
		slog.Error("Failed to monitor containers", "err", err)
	}
}

Options

The following options can be passed to Containuum:

  • WithDockerClient provides a specific Docker client to use. If not specified, one is created with default values. You can customise the behaviour of the default Docker client using env vars.
  • WithFilter applies a filter to containers that are returned. See the filters section below. Only one top-level filter may be applied.
  • WithDebounce configures the debounce on incoming container events. This can reduce how often the callback is invoked on exceptionally busy systems or when a container is misbehaving. Default: 100ms
  • WithMaxDebounceTime configures the maximum time events will be debounced for. This ensures that a constant stream of events emits updates at some point, rather than effectively becoming a denial-of-service attack. Default: 5s.
  • WithMaxIdleTime configures the period at which Continuum will refresh the containers even if it hasn't received an event. This is a useful fallback in case the event stream silently fails. Default: 30s.
  • WithAutoReconnect configures automatic reconnection to the event stream. If not specified, Containuum will error if the stream is disconnected, and clients must call Run() again to resume. Reconnection is performed with an exponential back-off, up to a maximum time limit.

Filters

If you are only interested in a subset of containers, you can filter them out by passing a filter to the WithFilter option. This occurs before deduplication, ensuring that changes to other containers don't result in your callback being invoked. The following filters are available:

  • Any(filter, filter, ...) - matches containers that matches any of the given filters
  • All(filter, filter, ...) - matches containers that matches all of the given filters
  • Not(filter) - matches containers that do not match the given filter
  • LabelExists(string) - matches containers that have the specified label, with any value
  • LabelEquals(string, string) - matches containers that have the specified label with the specified value
  • StateEquals(string) - matches contains in the given state (running, stopped, etc)

Only a single filter may be passed to WithFilter, but you can build complex filter chains using Any and/or All as required.

Provenance

This project was primarily created with Claude Code, but with a strong guiding hand. It's not "vibe coded", but an LLM was still the primary author of most lines of code. I believe it meets the same sort of standards I'd aim for with hand-crafted code, but some slop may slip through. I understand if you prefer not to use LLM-created software, and welcome human-authored alternatives (I just don't personally have the time/motivation to do so).

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Log func(msg string, keysAndValues ...any) = slog.Debug

Log is the logging function used by the library. It takes a message and optional key-value pairs for structured logging. Defaults to slog.Debug but can be overridden.

Functions

func Run

func Run(ctx context.Context, callback Callback, opts ...Option) error

Run monitors Docker containers and calls the callback when the filtered set changes. It emits the initial state immediately, then watches for changes. Blocks until the context is cancelled or an error occurs.

Types

type Callback

type Callback func(containers []Container)

Callback is invoked when the set of matching containers changes.

type Container

type Container struct {
	ID       string            // Full container ID
	Name     string            // Container name (without leading slash)
	Image    string            // Image name (e.g., "nginx:latest")
	State    string            // Container state (e.g., "running", "exited", "paused")
	Labels   map[string]string // Container labels
	Networks []Network         // All connected networks
	Ports    []Port            // Published port mappings
}

Container represents a Docker container's relevant state.

type DockerClient

type DockerClient interface {
	// Events returns a channel of Docker events and a channel of errors.
	Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error)

	// ContainerList returns a list of containers.
	ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error)

	// ContainerInspect returns detailed information about a container.
	ContainerInspect(ctx context.Context, containerID string) (container.InspectResponse, error)
}

DockerClient is the interface required from the Docker SDK. This is a subset of client.APIClient for easier testing and custom client injection.

type Filter

type Filter func(Container) bool

Filter is a function that determines whether a container should be included.

func All

func All(filters ...Filter) Filter

All returns a filter that matches if all given filters match (AND). Returns true if the filter list is empty.

func Any

func Any(filters ...Filter) Filter

Any returns a filter that matches if any given filter matches (OR). Returns false if the filter list is empty.

func LabelEquals

func LabelEquals(key, value string) Filter

LabelEquals returns a filter that matches containers where the given label equals the given value.

func LabelExists

func LabelExists(key string) Filter

LabelExists returns a filter that matches containers with the given label key.

func Not

func Not(filter Filter) Filter

Not returns a filter that inverts the result of the given filter.

func StateEquals

func StateEquals(state string) Filter

StateEquals returns a filter that matches containers in the given state.

type Network

type Network struct {
	Name       string   // Network name
	ID         string   // Network ID
	IPAddress  string   // IPv4 address on this network
	IP6Address string   // IPv6 address on this network (if any)
	Gateway    string   // Gateway for this network
	Aliases    []string // Container's DNS aliases on this network
}

Network represents a container's connection to a Docker network.

type Option

type Option func(*config)

Option configures the monitor.

func WithAutoReconnect

func WithAutoReconnect(minDelay, maxDelay time.Duration, maxRetries int) Option

WithAutoReconnect enables automatic reconnection on event stream errors. Uses exponential backoff starting at minDelay, doubling up to maxDelay. maxRetries of 0 means retry forever, otherwise stop after that many attempts. On successful reconnection, containers will be refreshed.

func WithDebounce

func WithDebounce(d time.Duration) Option

WithDebounce sets the debounce duration for coalescing rapid events. Default is 100ms.

func WithDockerClient

func WithDockerClient(client DockerClient) Option

WithDockerClient sets a custom Docker client. If not provided, a client will be created using default settings.

func WithFilter

func WithFilter(filter Filter) Option

WithFilter sets the filter for selecting containers. Use All() or Any() to combine multiple filters.

func WithMaxDebounceTime

func WithMaxDebounceTime(d time.Duration) Option

WithMaxDebounceTime sets the maximum time to wait when debouncing. This prevents indefinite delays when events keep arriving. Default is 5 seconds.

func WithMaxIdleTime

func WithMaxIdleTime(d time.Duration) Option

WithMaxIdleTime sets the maximum time to wait before polling for changes. Default is 30 seconds.

type Port

type Port struct {
	HostIP        string // Host IP (e.g., "0.0.0.0")
	HostPort      uint16 // Port on host
	ContainerPort uint16 // Port in container
	Protocol      string // "tcp" or "udp"
}

Port represents a port mapping.

Jump to

Keyboard shortcuts

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