pgdocker

package module
v0.7.1 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 11 Imported by: 0

README

Documentation

Overview

Package pgdocker manages PostgreSQL instances in Docker: start, stop, inspect, list, snapshot, and initialize — the engine behind a database-lifecycle CLI. The host port is an instance's identity; every container and volume the package touches carries namespaced labels, and all discovery filters on those labels server-side. Snapshots are physical PGDATA volume clones, so they are bound to the PostgreSQL major version that wrote them.

The library holds no port-based policy: defaults are explicit and non-destructive — a fresh volume on start, volumes kept on stop — and a consumer that wants an opinionated posture (a CLI's durable-vs-ephemeral port convention, for instance) passes explicit VolumeSource and Retention choices per call.

Index

Constants

View Source
const (
	ErrAlreadyRunning   errs.Const = "an instance already occupies this port"
	ErrCloneFailed      errs.Const = "cloning the data volume failed"
	ErrInvalidSpec      errs.Const = "invalid specification"
	ErrNoDataVolume     errs.Const = "no data volume exists for this port"
	ErrNotReady         errs.Const = "the database did not become ready in time"
	ErrNotRunning       errs.Const = "no running instance on this port"
	ErrSnapshotExists   errs.Const = "a snapshot with this name already exists"
	ErrSnapshotNotFound errs.Const = "no such snapshot"
	ErrSnapshotSkew     errs.Const = "snapshot postgres major version differs from the requested image"
)

Sentinel errors this package emits, matchable with errors.Is. The Const mechanism is owned by gomatic/go-error. Keep sorted alphabetically.

Engine-level failures (daemon unreachable, conflicts, missing resources) pass through from go-docker and stay matchable against that package's sentinels; the constants here name this package's own lifecycle semantics.

View Source
const DefaultImage docker.ImageRef = "postgres:17-alpine"

DefaultImage is the PostgreSQL image started when a spec names none.

View Source
const DefaultPort docker.Port = 5432

DefaultPort is the PostgreSQL default port, used when a spec names none.

Variables

This section is empty.

Functions

This section is empty.

Types

type Clock

type Clock func() time.Time

Clock supplies the current time; injectable so naming and labels are deterministic under test. It matches time.Now.

type DataDir

type DataDir docker.MountTarget

DataDir is the PGDATA mount target inside the container. The default matches the official postgres images through major 17; postgres 18+ images move the volume to /var/lib/postgresql.

type DatabaseName

type DatabaseName string

DatabaseName is the PostgreSQL database an instance serves.

type Engine

type Engine interface {
	CreateContainer(ctx context.Context, spec docker.ContainerSpec) (docker.ContainerID, error)
	StartContainer(ctx context.Context, id docker.ContainerID) error
	StopContainer(ctx context.Context, id docker.ContainerID, grace docker.StopSeconds) error
	RemoveContainer(ctx context.Context, id docker.ContainerID, options docker.RemovalOptions) error
	InspectContainer(ctx context.Context, id docker.ContainerID) (docker.ContainerDetails, error)
	Containers(ctx context.Context, query docker.ContainerQuery) ([]docker.ContainerSummary, error)
	WaitContainer(
		ctx context.Context,
		id docker.ContainerID,
		condition docker.WaitCondition,
	) (docker.ExitCode, error)
	ContainerLogs(
		ctx context.Context,
		id docker.ContainerID,
		options docker.LogOptions,
		stdout, stderr io.Writer,
	) error
	Exec(
		ctx context.Context,
		id docker.ContainerID,
		command docker.Command,
		options docker.ExecOptions,
	) (docker.ExitCode, error)
	PullImage(ctx context.Context, image docker.ImageRef, options docker.PullOptions) error
	ImageExists(ctx context.Context, image docker.ImageRef) (bool, error)
	CreateVolume(ctx context.Context, spec docker.VolumeSpec) (docker.VolumeDetails, error)
	Volumes(ctx context.Context, query docker.VolumeQuery) ([]docker.VolumeDetails, error)
	RemoveVolume(ctx context.Context, name docker.VolumeName, options docker.VolumeRemoval) error
}

Engine is the slice of the Docker Engine client this package drives. It is the package's one external seam: production passes a docker.Client, tests pass a fake, and nothing here ever reaches the daemon another way.

type Entropy

type Entropy io.Reader

Entropy supplies random bytes for volume-name suffixes; injectable so naming is deterministic under test. Production uses crypto/rand.

type InitSQLDir

type InitSQLDir string

InitSQLDir is a host directory of *.sql/*.sh first-boot provisioning scripts, mounted read-only at /docker-entrypoint-initdb.d.

type InitSpec

type InitSpec struct {
	Output   io.Writer
	Image    docker.ImageRef
	Database DatabaseName
	User     UserName
	Password Password
	Command  docker.Command
	Env      docker.Env
	Port     docker.Port
}

InitSpec describes an initialization run: a caller-supplied image and command executed against a running instance — migrations, seeds, schema loads. The init container joins the instance's network namespace, so it reaches the server at localhost:5432 on every platform; no host.docker.internal, no host networking.

type Instance

type Instance struct {
	Labels    docker.Labels
	Name      docker.ContainerName
	ID        docker.ContainerID
	Image     docker.ImageRef
	Volume    docker.VolumeName
	Status    docker.ContainerStatus
	Port      docker.Port
	IsRunning bool
}

Instance is a started (or inspected) managed PostgreSQL instance. It states facts about the instance only — no connection URL is derived, because roles, databases, and passwords belong to initialization and later administration, not to the lifecycle record.

type ListenAddress

type ListenAddress docker.HostIP

ListenAddress is the host interface the instance's port binds. The default is loopback — a managed development database is not reachable from other machines unless the caller widens this deliberately.

type Manager

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

Manager drives PostgreSQL instances on one Docker daemon. The zero value is not usable; construct with New. Manager is a value: it holds only configuration and the injected engine, so it is safe to copy.

func New

func New(options ...ManagerOption) (Manager, error)

New assembles a Manager. An engine must be supplied — production wraps a docker.Client in WithEngine; there is no implicit daemon connection here, so construction is deterministic and never touches the network.

func (Manager) Init

func (m Manager) Init(ctx context.Context, spec InitSpec) (docker.ExitCode, error)

Init runs the spec's container against the port's running instance and returns the command's exit code. Infrastructure failures are errors; a non-zero exit from the init command itself is a result, not an error.

func (Manager) Inspect

func (m Manager) Inspect(ctx context.Context, port docker.Port) (Report, error)

Inspect reports one port's managed container and volumes. A port with volumes but no container is a stopped-but-retained database; a port with neither yields an empty report.

func (Manager) List

func (m Manager) List(ctx context.Context) ([]Report, error)

List reports every managed port on the daemon, ordered by port.

func (Manager) SnapshotCreate

func (m Manager) SnapshotCreate(ctx context.Context, spec SnapshotSpec) (Snapshot, error)

SnapshotCreate clones the port's newest data volume into a labeled snapshot volume. Snapshots are physical PGDATA copies: consistent only when the database is stopped, so a running instance on the port is refused, and a snapshot boots only on the PostgreSQL major that wrote it.

func (Manager) SnapshotDelete

func (m Manager) SnapshotDelete(ctx context.Context, name SnapshotName) error

SnapshotDelete removes a snapshot's volume.

func (Manager) SnapshotList

func (m Manager) SnapshotList(ctx context.Context) ([]Snapshot, error)

SnapshotList reports every snapshot in the namespace, sorted by name.

func (Manager) Start

func (m Manager) Start(ctx context.Context, spec StartSpec) (Instance, error)

Start provisions and starts a PostgreSQL instance for the spec's port, waits until the server answers pg_isready, and returns the running instance. Starting a port that already has a managed container fails with ErrAlreadyRunning.

Start is atomic on its container: if the launch or readiness wait fails, the container it created is force-removed before the error returns, so a failed Start never leaves a container running. The data volume is kept — it is durable and reusable, and inspecting it is often how a failure is diagnosed.

func (Manager) Stop

func (m Manager) Stop(ctx context.Context, spec StopSpec) (StopReport, error)

Stop stops the port's managed containers and applies volume retention: the explicit spec choice first, then the container's recorded label, then the non-destructive keep default. Stopping a port with nothing running still applies retention to leftover volumes.

type ManagerOption

type ManagerOption interface {
	// contains filtered or unexported methods
}

ManagerOption adjusts Manager construction. Options are concrete types — Namespace, WithEngine, WithClock, WithEntropy.

type Namespace

type Namespace string

Namespace prefixes every container name, volume name, and label key this package writes, so multiple consumers of the library coexist on one daemon without seeing each other's instances.

const DefaultNamespace Namespace = "pgdocker"

DefaultNamespace marks instances managed by an unconfigured Manager.

type Password

type Password string

Password is the role's password; empty selects trust auth (a development posture — the instance accepts any local connection).

type PostgresMajor

type PostgresMajor string

PostgresMajor is a PostgreSQL major version ("17"); empty means unknown.

type Report

type Report struct {
	Instance     Instance
	Volumes      []docker.VolumeName
	Port         docker.Port
	HasContainer bool
}

Report is the inspected state of one managed port: its container (when one exists) and every managed data volume, newest first.

type Retention

type Retention string

Retention selects what happens to an instance's data volume on stop. The zero value defaults to RetainKeep: the library never destroys data unless told to. A container label records the choice made at start so stop honors it without being told again.

const (
	RetainKeep   Retention = "keep"
	RetainRemove Retention = "remove"
)

Retention policies.

type SettingKey

type SettingKey string

SettingKey is a PostgreSQL parameter name.

type SettingValue

type SettingValue string

SettingValue is a PostgreSQL parameter value.

type Settings

type Settings map[SettingKey]SettingValue

Settings are PostgreSQL server parameters delivered as "-c key=value" command arguments — no configuration files are staged or mounted. Caller settings overlay the defaults; an empty value removes the key entirely.

type Snapshot

type Snapshot struct {
	Labels     docker.Labels
	Name       SnapshotName
	Volume     docker.VolumeName
	Major      PostgresMajor
	CreatedAt  docker.VolumeCreatedAt
	SourcePort docker.Port
}

Snapshot describes one stored snapshot.

type SnapshotName

type SnapshotName string

SnapshotName identifies a snapshot within the manager's namespace.

type SnapshotSpec

type SnapshotSpec struct {
	// Labels ride onto the snapshot volume for the caller's own
	// provenance or discovery; namespaced managed keys always win a
	// collision.
	Labels    docker.Labels
	Name      SnapshotName
	CopyImage docker.ImageRef
	Port      docker.Port
}

SnapshotSpec describes a snapshot to create.

type StartSpec

type StartSpec struct {
	Settings            Settings
	Labels              docker.Labels
	Volume              VolumeSource
	Retain              Retention
	Image               docker.ImageRef
	Platform            docker.Platform
	Snapshot            SnapshotName
	Database            DatabaseName
	Listen              ListenAddress
	Password            Password
	User                UserName
	InitSQL             InitSQLDir
	Data                DataDir
	Env                 docker.Env
	ReadyTimeout        time.Duration
	ReadyInterval       time.Duration
	Port                docker.Port
	SnapshotSkewEnabled bool
}

StartSpec describes an instance to start. The zero value starts a loopback trust-auth postgres on the default port with the tuned development settings.

type StopReport

type StopReport struct {
	Stopped        []docker.ContainerName
	RemovedVolumes []docker.VolumeName
	KeptVolumes    []docker.VolumeName
}

StopReport is the outcome of a stop: what was stopped and what happened to each managed volume on the port.

type StopSpec

type StopSpec struct {
	// Retain overrides retention; zero defers to the label the container
	// recorded at start, then to the non-destructive keep default.
	Retain Retention
	Grace  docker.StopSeconds
	Port   docker.Port
}

StopSpec adjusts an instance stop.

type UserName

type UserName string

UserName is the PostgreSQL role an instance authenticates.

type VolumeSource

type VolumeSource string

VolumeSource selects where a starting instance's data volume comes from. The zero value defaults to VolumeFresh; reusing existing state is an explicit choice.

const (
	VolumeReuse VolumeSource = "reuse"
	VolumeFresh VolumeSource = "fresh"
)

Volume sources.

type WithClock

type WithClock struct {
	Clock Clock
}

WithClock injects the time source.

type WithEngine

type WithEngine struct {
	Engine Engine
}

WithEngine injects the Docker Engine seam; tests pass a fake.

type WithEntropy

type WithEntropy struct {
	Entropy Entropy
}

WithEntropy injects the randomness source for name suffixes.

Jump to

Keyboard shortcuts

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