containerkit

module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: MIT

README

containerkit

Go Reference Go Report Card Go Version License

Define Docker stacks in Go. The same *containerkit.Container feeds either the in-process Compose SDK or the Docker Engine SDK. Compose does not shell out to docker compose.

go get github.com/aptd3v/containerkit@latest

Two packages

Package Import Role
Compose + fluent config github.com/aptd3v/containerkit/pkg/containerkit Project, Container, NewCompose, option structs (Up, Down, …)
Engine client github.com/aptd3v/containerkit/pkg/client Thin Docker SDK wrapper; per-op structs (Remove, Exec, ImageBuild, …)

Quick start

package main

import (
	"context"
	"log"
	"os"

	"github.com/aptd3v/containerkit/pkg/containerkit"
)

func main() {
	project := containerkit.NewProject("hello-world")
	project.WithService("hello",
		containerkit.NewContainer().
			Image("alpine:latest").
			Command("echo", "Hello from containerkit!"),
	)

	app := containerkit.NewCompose(project)
	if err := app.Up(context.Background(), &containerkit.Up{Writer: os.Stdout}); err != nil {
		log.Fatal(err)
	}
}

Nil compose options mean defaults (writer is os.Stdout).

Compose stack

project := containerkit.NewProject("my-app")
project.
	WithNetwork("backend").
	WithVolume("data").
	WithService("api",
		containerkit.NewContainer().
			Image("alpine:latest").
			Command("sleep", "inf").
			PortBinding(containerkit.PortBinding{Protocol: containerkit.TCP, HostIP: "0.0.0.0", HostPort: "8080", ContainerPort: "8080"}).
			RWNamedVolumeMount("data", "/data").
			Endpoint("backend"),
		containerkit.DependsOn("db"),
	)

if err := project.Validate(); err != nil {
	log.Fatal(err)
}

app := containerkit.NewCompose(project)
if err := app.Up(ctx, &containerkit.Up{
	Detach:        true,
	RemoveOrphans: true,
	Writer:        os.Stdout,
}); err != nil {
	log.Fatal(err)
}
defer app.Down(ctx, &containerkit.Down{RemoveVolumes: true, Writer: os.Stdout})

Export YAML when you want a file:

if err := project.Export("./docker-compose.yaml", 0644); err != nil {
	log.Fatal(err)
}

Engine client

A container name is optional for a Compose service and required for ContainerCreate. Construction options stay funcs on client.

cli, err := client.NewClient(client.FromEnv(), client.WithAPIVersionNegotiation())
if err != nil {
	log.Fatal(err)
}

ctr := containerkit.NewContainer("my-api")
ctr.Image("alpine:latest").Command("sleep", "inf")

resp, err := cli.ContainerCreate(ctx, ctr)
if err != nil {
	log.Fatal(err)
}
_ = cli.ContainerRemove(ctx, resp.ID, &client.Remove{Force: true, Volumes: true})

The same *containerkit.Container can be passed to the Engine client or added as a Compose service.

Dockerfile

NewDockerFile writes a Dockerfile in Go. WithInline attaches it as a Compose build. Export writes the file for the Engine client.

df := containerkit.NewDockerFile().
	FromAs("alpine:latest", "build").
	Run("echo ok > /out/app").
	From("alpine", "latest").
	Copy("/out/app", "/app", containerkit.CopyOpts{From: "build"})

if err := df.Export("Dockerfile", 0644); err != nil {
	log.Fatal(err)
}

project.WithService("app",
	containerkit.NewContainer().Image("my-image:tag"),
	df.WithInline(),
)

Fluent configuration

Methods live on *containerkit.Container. Nested objects (health, mount, build) and Compose command options are structs. Service extras (DependsOn, Profiles, BuildSpec) are extra args to WithService.

project.WithService("api",
	containerkit.NewContainer("my-api").
		Imagef("ubuntu:%s", tag).
		PortBinding(containerkit.PortBinding{Protocol: containerkit.TCP, HostIP: "0.0.0.0", HostPort: "8080", ContainerPort: "80"}).
		Endpoint("my-network").
		Architecture("amd64"),
	containerkit.DependsOn("db"),
	containerkit.Profiles("full"),
	containerkit.BuildSpec{Context: ".", Dockerfile: "Dockerfile"},
)

You can also mix in Docker SDK structs. See examples/structs.

Conditionals

Use an ordinary Go if inside the factory.

c := containerkit.NewContainer().Image("node:latest")
if runtime.GOOS == "linux" {
	c.RWNamedVolumeMount("data", "/app")
} else {
	c.VolumeBinds("./:/app/:rw")
}

Profiles

containerkit.Profiles on a service is Compose’s profiles: key. To start those services, pass the same names on the command (Up.Profiles, Down.Profiles, Kill.Profiles, …). If the project has profiled services and the command omits Profiles, compose returns an error.

project.WithService("worker",
	containerkit.NewContainer().Image("alpine:latest"),
	containerkit.Profiles("full"),
)
_ = app.Up(ctx, &containerkit.Up{Profiles: []string{"full"}, Writer: os.Stdout})

Examples

Run from the repo root.

Path Path type What it shows
examples/simple Compose Minimal NewProject → Up
examples/wordpress Compose Multi-service, OS-conditional mounts, logs, signal Down
examples/profiles Compose Profiles mirrored on Up / Kill
examples/events Compose Events channel + healthcheck
examples/compose_commands Compose Build, Ps, Start, Stop, Restart, Exec, Config, Images, Top, Pause, Run
examples/nginx Hybrid client.ImageBuild then compose Up
examples/image_inline Hybrid Inline Dockerfile; Engine inspect skips a rebuild when the tag exists
examples/dockerfile Client Multi-stage NewDockerFile, Export, ImageBuild, ContainerCreate
examples/mongo_replica Hybrid Compose Up with Wait, then client exec to init a replica set
examples/terminal Client Interactive TTY exec + resize
examples/structs Config Mix Docker SDK structs with fluent methods
examples/supabase Compose Full multi-profile stack. See its README
go run ./examples/simple/
go run ./examples/supabase/                    # minimal
go run ./examples/supabase/ -profile full
go run ./examples/supabase/ -resource-limits

Prerequisites

  • Go 1.26.8+
  • Docker Engine
  • Linux, macOS, or Windows

Compose is linked in-process. A docker compose binary is not required.

Migrating from go-contain

This project was renamed from go-contain. The public API is two packages; the old option-func packages are gone.

Old New
github.com/aptd3v/go-contain github.com/aptd3v/containerkit
pkg/create, cc.WithImage, … pkg/containerkit, fluent .Image(), …
pkg/compose, up.WithRemoveOrphans() containerkit.NewCompose + &containerkit.Up{…}
pkg/client/options/** per-op structs on pkg/client (Remove, Exec, …)

License

MIT. See LICENSE.

Contributing

Issues and pull requests are welcome: issues · discussions

Directories

Path Synopsis
examples
compose_commands command
This example demonstrates compose CLI commands: Build, Ps, Start, Stop, Restart, Exec, Config, Images, Top, Pause, Unpause, and Run.
This example demonstrates compose CLI commands: Build, Ps, Start, Stop, Restart, Exec, Config, Images, Top, Pause, Unpause, and Run.
dockerfile command
Write a multi-stage Dockerfile with NewDockerFile, build it with the Engine client, and serve it.
Write a multi-stage Dockerfile with NewDockerFile, build it with the Engine client, and serve it.
events command
This example shows how to use the events API to get real-time updates about the state of a service.
This example shows how to use the events API to get real-time updates about the state of a service.
image_inline command
Build a tagged image from an inline Dockerfile, then run it.
Build a tagged image from an inline Dockerfile, then run it.
mongo_replica command
This example demonstrates how to create a MongoDB replica set with x members and a Mongo Express instance to manage the replica set.
This example demonstrates how to create a MongoDB replica set with x members and a Mongo Express instance to manage the replica set.
nginx command
profiles command
this example shows how to use profiles to start a service with a specific profile
this example shows how to use profiles to start a service with a specific profile
simple command
This is a simple example of how to use containerkit to create a simple project.
This is a simple example of how to use containerkit to create a simple project.
structs command
this example shows how to use the structs to create a service if you prefer to use them
this example shows how to use the structs to create a service if you prefer to use them
supabase command
Package main: write embedded Supabase volume files to disk for the example.
Package main: write embedded Supabase volume files to disk for the example.
terminal command
in this example we will create a container and run a command in it to demonstrate the use of the terminal exec attach
in this example we will create a container and run a command in it to demonstrate the use of the terminal exec attach
wordpress command
pkg
client/response
Package response provides thin wrappers around the docker client response types.
Package response provides thin wrappers around the docker client response types.
client/terminal
Package terminal attaches a local terminal to a hijacked container stream.
Package terminal attaches a local terminal to a hijacked container stream.
containerkit
Package containerkit defines Compose projects and runs them through the Docker Compose SDK.
Package containerkit defines Compose projects and runs them through the Docker Compose SDK.

Jump to

Keyboard shortcuts

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