acgo

package module
v0.0.0-...-babac0d Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

README

acgo

acgo logo

Go SDK for Apple Container. Talks to socktainer over a Unix socket, gives you a containerd v2-flavored API.

go get github.com/memohai/acgo

How it works

graph TB
    App["Your Go Code"]
    Client["acgo.Client"]
    Sock["socktainer"]
    Apple["Containerization + Virtualization.framework"]

    App -->|"acgo.New() / Pull() / NewContainer() ..."| Client
    Client -->|"HTTP/JSON over Unix socket"| Sock
    Sock -->|"apple/container + apple/containerization"| Apple

    style App fill:none,stroke:#555
    style Client fill:none,stroke:#555
    style Sock fill:none,stroke:#555
    style Apple fill:none,stroke:#555

acgo is a go client library. It doesn't manage daemons, doesn't shell out, doesn't vendor Swift code. It speaks the Docker API that socktainer already exposes.

Requirements

  • macOS 26 on Apple Silicon
  • Go 1.25+
  • socktainer (brew tap socktainer/tap && brew install socktainer)

Quick start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/memohai/acgo"
)

func main() {
    client, err := acgo.New()
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    ctx := context.Background()

    // pull
    img, err := client.Pull(ctx, "docker.io/library/alpine:latest")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("pulled:", img.Name(), img.Size())

    // create + start
    ctr, err := client.NewContainer(ctx, "hello",
        acgo.WithImage("alpine:latest"),
        acgo.WithCmd("echo", "hello from acgo"),
        acgo.WithAutoRemove(),
    )
    if err != nil {
        log.Fatal(err)
    }
    _ = ctr.Start(ctx)

    // wait + logs
    resCh, _ := ctr.Wait(ctx, "not-running")
    <-resCh

    rc, _ := ctr.Logs(ctx)
    defer rc.Close()
    // io.Copy(os.Stdout, rc)
}

Managing socktainer

acgo ships a socktainer.Manager in a separate sub-package. It's optional -- use it when you want your Go program to own the daemon lifecycle instead of relying on a system-wide process.

package main

import (
    "context"
    "log"

    "github.com/memohai/acgo"
    "github.com/memohai/acgo/socktainer"
)

func main() {
    ctx := context.Background()

    // Start socktainer if not already running.
    // If the socket is already alive, this is a no-op.
    mgr := socktainer.NewManager()
    if err := mgr.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer mgr.Stop() // only kills what it started

    // Wire the socket path into the client.
    client, err := acgo.New(acgo.WithSocketPath(mgr.SocketPath()))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    ok, _ := client.IsServing(ctx)
    log.Println("serving:", ok)
}

Manager options:

socktainer.NewManager(
    socktainer.WithBinary("/opt/homebrew/bin/socktainer"), // default: exec.LookPath
    socktainer.WithSocket("/tmp/my.sock"),                 // default: ~/.socktainer/container.sock
    socktainer.WithStartTimeout(15 * time.Second),         // default: 30s
)

Behavior:

  • Start checks the socket with /_ping. If alive, records it as external and returns immediately.
  • Start with a dead socket finds the binary, spawns it, polls until ready.
  • Stop sends SIGTERM only if this Manager started the process. External daemons are left alone.

Connecting to an existing socket

If socktainer (or anything Docker-API-compatible) is already running somewhere:

client, _ := acgo.New(acgo.WithSocketPath("/var/run/my-container.sock"))

API reference

Client
func New(opts ...Opt) (*Client, error)
func (c *Client) Close() error
func (c *Client) IsServing(ctx) (bool, error)
func (c *Client) Version(ctx) (system.Version, error)
func (c *Client) Info(ctx) (system.Info, error)
func (c *Client) DiskUsage(ctx) (system.DiskUsage, error)
func (c *Client) Events(ctx, ...EventsOpt) (<-chan system.Event, <-chan error)
Container lifecycle
func (c *Client) NewContainer(ctx, id, ...CreateOpt) (Container, error)
func (c *Client) LoadContainer(ctx, id) (Container, error)
func (c *Client) Containers(ctx, ...ListOpt) ([]Container, error)
func (c *Client) PruneContainers(ctx) ([]string, error)
func (c *Client) ContainerService() containers.Store
type Container interface {
    ID() string
    Info(ctx) (containers.Container, error)
    Image(ctx) (Image, error)
    Labels(ctx) (map[string]string, error)
    Start(ctx, ...StartOpt) error
    Stop(ctx, ...StopOpt) error
    Kill(ctx, ...KillOpt) error
    Restart(ctx, ...RestartOpt) error
    Delete(ctx, ...DeleteOpt) error
    Wait(ctx, condition) (<-chan WaitResult, <-chan error)
    Exec(ctx, cmd, ...ExecOpt) (ExecResult, error)
    Logs(ctx, ...LogsOpt) (io.ReadCloser, error)
    Stats(ctx, ...StatsOpt) (system.Stats, error)
    Inspect(ctx) (containers.Container, error)
}
Images
func (c *Client) Pull(ctx, ref, ...PullOpt) (Image, error)
func (c *Client) Push(ctx, ref, ...PushOpt) error
func (c *Client) Build(ctx, io.Reader, ...BuildOpt) error
func (c *Client) GetImage(ctx, ref) (Image, error)
func (c *Client) ListImages(ctx, ...ImageListOpt) ([]Image, error)
func (c *Client) DeleteImage(ctx, ref, ...ImageDeleteOpt) error
func (c *Client) TagImage(ctx, source, target) error
func (c *Client) PruneImages(ctx) error
func (c *Client) ImageService() images.Store
type Image interface {
    Name() string
    ID() string
    RepoTags() []string
    RepoDigests() []string
    Labels() map[string]string
    Size() int64
    Created() time.Time
    Info(ctx) (images.Image, error)
    Delete(ctx, ...ImageDeleteOpt) error
    Tag(ctx, repo, tag) error
}
Networks
func (c *Client) CreateNetwork(ctx, name, ...NetworkOpt) (network.Network, error)
func (c *Client) DeleteNetwork(ctx, id) error
func (c *Client) ListNetworks(ctx) ([]network.Network, error)
func (c *Client) InspectNetwork(ctx, id) (network.Network, error)
func (c *Client) ConnectNetwork(ctx, networkID, containerID) error
func (c *Client) DisconnectNetwork(ctx, networkID, containerID, force) error
func (c *Client) PruneNetworks(ctx) error
Volumes
func (c *Client) CreateVolume(ctx, name, ...VolumeOpt) (volume.Volume, error)
func (c *Client) DeleteVolume(ctx, name) error
func (c *Client) ListVolumes(ctx) ([]volume.Volume, error)
func (c *Client) InspectVolume(ctx, name) (volume.Volume, error)
func (c *Client) PruneVolumes(ctx) error
Registry
func (c *Client) RegistryLogin(ctx, username, password, server) error

Functional options

// container creation
acgo.WithImage("nginx:latest")
acgo.WithCmd("nginx", "-g", "daemon off;")
acgo.WithEntrypoint("/entrypoint.sh")
acgo.WithEnv("PORT", "8080")
acgo.WithPublish(8080, 80, "tcp")
acgo.WithVolume("/host", "/container")
acgo.WithNetwork("frontend")
acgo.WithLabel("app", "web")
acgo.WithTTY()
acgo.WithUser("nobody")
acgo.WithWorkdir("/app")
acgo.WithHostname("web-1")
acgo.WithAutoRemove()
acgo.WithPlatform("linux/arm64")
acgo.WithDNS("8.8.8.8")

// container operations
acgo.WithStopTimeout(10)
acgo.WithStopSignal("SIGTERM")
acgo.WithKillSignal("SIGKILL")
acgo.WithForceDelete()
acgo.WithRemoveVolumes()

// image pull
acgo.WithPullTag("3.19")
acgo.WithPullPlatform("linux/arm64")

// image build
acgo.WithBuildTag("myapp:latest")
acgo.WithDockerfile("build/Dockerfile")
acgo.WithNoCache()

// logs
acgo.WithLogsFollow()
acgo.WithLogsTail("100")
acgo.WithLogsSince("2025-01-01T00:00:00Z")

// exec
acgo.WithExecTTY()
acgo.WithExecStdin()
acgo.WithExecDetach()

// events
acgo.WithEventFilters(`{"type":["container"],"event":["start","die"]}`)

Store interfaces

For code that needs a testable abstraction over container/image CRUD:

func (c *Client) ContainerService() containers.Store
func (c *Client) ImageService() images.Store
// containers.Store
type Store interface {
    Get(ctx, id) (Container, error)
    List(ctx, ...filters) ([]Container, error)
    Create(ctx, Container) (Container, error)
    Delete(ctx, id) error
}

These follow the same interface pattern as containerd/v2/core/containers.Store and containerd/v2/core/images.Store.

  • Memoh - Multi-Member, Structured Long-Memor, Containerized AI Agent System ✨

License

Apache-2.0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsConflict

func IsConflict(err error) bool

IsConflict returns true if the error is a ConflictError or a 409 APIError.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound returns true if the error is a NotFoundError or a 404 APIError.

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
}

APIError represents an error response from the Docker-compatible API.

func (*APIError) Error

func (e *APIError) Error() string

type BuildOpt

type BuildOpt func(*buildConfig)

BuildOpt configures image build.

func WithBuildTag

func WithBuildTag(tag string) BuildOpt

WithBuildTag sets the tag for the built image.

func WithDockerfile

func WithDockerfile(path string) BuildOpt

WithDockerfile sets the Dockerfile path within the build context.

func WithNoCache

func WithNoCache() BuildOpt

WithNoCache disables build cache.

type Client

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

Client communicates with Apple Container via the socktainer Docker-compatible API.

func New

func New(opts ...Opt) (*Client, error)

New creates a Client that connects to a socktainer Unix socket. By default it connects to $HOME/.socktainer/container.sock. Use WithSocketPath to override.

func (*Client) Build

func (c *Client) Build(ctx context.Context, buildCtx io.Reader, opts ...BuildOpt) error

Build creates a new image from a build context (tar archive).

func (*Client) Close

func (c *Client) Close() error

Close releases resources held by the client.

func (*Client) ConnectNetwork

func (c *Client) ConnectNetwork(ctx context.Context, networkID, containerID string) error

ConnectNetwork connects a container to a network.

func (*Client) ContainerService

func (c *Client) ContainerService() containers.Store

ContainerService returns a Store backed by the Docker API.

func (*Client) Containers

func (c *Client) Containers(ctx context.Context, opts ...ListOpt) ([]Container, error)

Containers lists containers. Pass WithListAll() to include stopped containers.

func (*Client) CreateNetwork

func (c *Client) CreateNetwork(ctx context.Context, name string, opts ...NetworkOpt) (network.Network, error)

CreateNetwork creates a new network.

func (*Client) CreateVolume

func (c *Client) CreateVolume(ctx context.Context, name string, opts ...VolumeOpt) (volume.Volume, error)

CreateVolume creates a new volume.

func (*Client) DeleteImage

func (c *Client) DeleteImage(ctx context.Context, ref string, opts ...ImageDeleteOpt) error

DeleteImage removes an image by reference.

func (*Client) DeleteNetwork

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

DeleteNetwork removes a network.

func (*Client) DeleteVolume

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

DeleteVolume removes a volume.

func (*Client) DisconnectNetwork

func (c *Client) DisconnectNetwork(ctx context.Context, networkID, containerID string, force bool) error

DisconnectNetwork disconnects a container from a network.

func (*Client) DiskUsage

func (c *Client) DiskUsage(ctx context.Context) (system.DiskUsage, error)

DiskUsage returns disk usage statistics.

func (*Client) Events

func (c *Client) Events(ctx context.Context, opts ...EventsOpt) (<-chan system.Event, <-chan error)

Events returns a channel of engine events. The channel closes when the context is cancelled.

func (*Client) GetImage

func (c *Client) GetImage(ctx context.Context, ref string) (Image, error)

GetImage returns a handle to an image by reference.

func (*Client) ImageService

func (c *Client) ImageService() images.Store

ImageService returns a Store backed by the Docker API.

func (*Client) Info

func (c *Client) Info(ctx context.Context) (system.Info, error)

Info returns system-wide information.

func (*Client) InspectNetwork

func (c *Client) InspectNetwork(ctx context.Context, id string) (network.Network, error)

InspectNetwork returns details of a network.

func (*Client) InspectVolume

func (c *Client) InspectVolume(ctx context.Context, name string) (volume.Volume, error)

InspectVolume returns details of a volume.

func (*Client) IsServing

func (c *Client) IsServing(ctx context.Context) (bool, error)

IsServing returns true if the server is responding to pings.

func (*Client) ListImages

func (c *Client) ListImages(ctx context.Context, opts ...ImageListOpt) ([]Image, error)

ListImages returns all local images.

func (*Client) ListNetworks

func (c *Client) ListNetworks(ctx context.Context) ([]network.Network, error)

ListNetworks lists all networks.

func (*Client) ListVolumes

func (c *Client) ListVolumes(ctx context.Context) ([]volume.Volume, error)

ListVolumes lists all volumes.

func (*Client) LoadContainer

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

LoadContainer returns a handle to an existing container by ID.

func (*Client) NewContainer

func (c *Client) NewContainer(ctx context.Context, id string, opts ...CreateOpt) (Container, error)

NewContainer creates a new container and returns a handle to it.

func (*Client) PruneContainers

func (c *Client) PruneContainers(ctx context.Context) ([]string, error)

PruneContainers removes all stopped containers.

func (*Client) PruneImages

func (c *Client) PruneImages(ctx context.Context) error

PruneImages removes unused images.

func (*Client) PruneNetworks

func (c *Client) PruneNetworks(ctx context.Context) error

PruneNetworks removes unused networks.

func (*Client) PruneVolumes

func (c *Client) PruneVolumes(ctx context.Context) error

PruneVolumes removes unused volumes.

func (*Client) Pull

func (c *Client) Pull(ctx context.Context, ref string, opts ...PullOpt) (Image, error)

Pull fetches an image from a registry.

func (*Client) Push

func (c *Client) Push(ctx context.Context, ref string, opts ...PushOpt) error

Push pushes an image to a registry.

func (*Client) RegistryLogin

func (c *Client) RegistryLogin(ctx context.Context, username, password, server string) error

RegistryLogin authenticates with a container registry.

func (*Client) TagImage

func (c *Client) TagImage(ctx context.Context, source, target string) error

TagImage applies a new tag to an existing image.

func (*Client) Version

func (c *Client) Version(ctx context.Context) (system.Version, error)

Version returns version information from the server.

type ConflictError

type ConflictError struct {
	Resource string
	ID       string
	Message  string
}

ConflictError indicates a resource state conflict.

func (*ConflictError) Error

func (e *ConflictError) Error() string

type Container

type Container interface {
	ID() string
	Info(ctx context.Context) (containers.Container, error)
	Start(ctx context.Context, opts ...StartOpt) error
	Stop(ctx context.Context, opts ...StopOpt) error
	Kill(ctx context.Context, opts ...KillOpt) error
	Delete(ctx context.Context, opts ...DeleteOpt) error
	Restart(ctx context.Context, opts ...RestartOpt) error
	Wait(ctx context.Context, condition string) (<-chan WaitResult, <-chan error)
	Exec(ctx context.Context, cmd []string, opts ...ExecOpt) (ExecResult, error)
	Logs(ctx context.Context, opts ...LogsOpt) (io.ReadCloser, error)
	Stats(ctx context.Context, opts ...StatsOpt) (system.Stats, error)
	Inspect(ctx context.Context) (containers.Container, error)
	Image(ctx context.Context) (Image, error)
	Labels(ctx context.Context) (map[string]string, error)
}

Container represents a handle to a container managed by Apple Container.

type CreateOpt

type CreateOpt func(*createConfig) error

CreateOpt configures container creation.

func WithAutoRemove

func WithAutoRemove() CreateOpt

WithAutoRemove removes the container when it stops.

func WithCmd

func WithCmd(cmd ...string) CreateOpt

WithCmd sets the command to run.

func WithDNS

func WithDNS(nameservers ...string) CreateOpt

WithDNS sets custom DNS servers.

func WithDNSSearch

func WithDNSSearch(domains ...string) CreateOpt

WithDNSSearch sets DNS search domains.

func WithEntrypoint

func WithEntrypoint(ep ...string) CreateOpt

WithEntrypoint overrides the image entrypoint.

func WithEnv

func WithEnv(key, value string) CreateOpt

WithEnv adds an environment variable.

func WithHostname

func WithHostname(hostname string) CreateOpt

WithHostname sets the container hostname.

func WithImage

func WithImage(image string) CreateOpt

WithImage sets the container image.

func WithInteractive

func WithInteractive() CreateOpt

WithInteractive keeps stdin open.

func WithLabel

func WithLabel(key, value string) CreateOpt

WithLabel adds a label.

func WithMount

func WithMount(m mount.Mount) CreateOpt

WithMount adds a mount specification.

func WithName

func WithName(name string) CreateOpt

WithName is an alias handled by the Client; included for discoverability.

func WithNetwork

func WithNetwork(name string) CreateOpt

WithNetwork attaches the container to a network.

func WithPlatform

func WithPlatform(platform string) CreateOpt

WithPlatform sets the platform (e.g. "linux/arm64").

func WithPublish

func WithPublish(hostPort, containerPort uint16, proto string) CreateOpt

WithPublish adds a port mapping.

func WithTTY

func WithTTY() CreateOpt

WithTTY allocates a pseudo-TTY.

func WithUser

func WithUser(user string) CreateOpt

WithUser sets the user for the container process.

func WithVolume

func WithVolume(hostPath, containerPath string) CreateOpt

WithVolume adds a bind mount.

func WithWorkdir

func WithWorkdir(dir string) CreateOpt

WithWorkdir sets the working directory.

type DeleteOpt

type DeleteOpt func(*deleteConfig)

DeleteOpt configures container deletion.

func WithForceDelete

func WithForceDelete() DeleteOpt

WithForceDelete forces removal of a running container.

func WithRemoveVolumes

func WithRemoveVolumes() DeleteOpt

WithRemoveVolumes removes associated volumes.

type EventsOpt

type EventsOpt func(*eventsConfig)

EventsOpt configures event subscription.

func WithEventFilters

func WithEventFilters(filters string) EventsOpt

WithEventFilters sets a raw Docker filters JSON string for events.

type ExecOpt

type ExecOpt func(*execConfig)

ExecOpt configures container exec.

func WithExecDetach

func WithExecDetach() ExecOpt

WithExecDetach runs exec in detached mode.

func WithExecStdin

func WithExecStdin() ExecOpt

WithExecStdin attaches stdin.

func WithExecTTY

func WithExecTTY() ExecOpt

WithExecTTY allocates a TTY for exec.

type ExecResult

type ExecResult struct {
	ExecID string
	Output io.ReadCloser
}

ExecResult holds the output of an exec command.

type Image

type Image interface {
	Name() string
	ID() string
	RepoTags() []string
	RepoDigests() []string
	Labels() map[string]string
	Size() int64
	Created() time.Time
	Info(ctx context.Context) (images.Image, error)
	Delete(ctx context.Context, opts ...ImageDeleteOpt) error
	Tag(ctx context.Context, repo, tag string) error
}

Image represents a handle to a container image.

type ImageDeleteOpt

type ImageDeleteOpt func(*imageDeleteConfig)

ImageDeleteOpt configures image deletion.

type ImageListOpt

type ImageListOpt func(*imageListConfig)

ImageListOpt configures image listing.

type KillOpt

type KillOpt func(*killConfig)

KillOpt configures container kill behavior.

func WithKillSignal

func WithKillSignal(sig string) KillOpt

WithKillSignal sets the signal to send (default KILL).

type ListOpt

type ListOpt func(*listConfig)

ListOpt configures container listing.

func WithListAll

func WithListAll() ListOpt

WithListAll includes stopped containers.

func WithListFilters

func WithListFilters(filters string) ListOpt

WithListFilters sets a raw Docker filters JSON string.

type LogsOpt

type LogsOpt func(*logsConfig)

LogsOpt configures container log retrieval.

func WithLogsFollow

func WithLogsFollow() LogsOpt

WithLogsFollow streams logs continuously.

func WithLogsSince

func WithLogsSince(since string) LogsOpt

WithLogsSince shows logs since a timestamp.

func WithLogsTTY

func WithLogsTTY() LogsOpt

WithLogsTTY indicates the container has a TTY (raw log stream).

func WithLogsTail

func WithLogsTail(n string) LogsOpt

WithLogsTail limits the number of lines from the end.

type NetworkOpt

type NetworkOpt func(*networkConfig)

NetworkOpt configures network creation.

func WithNetworkGateway

func WithNetworkGateway(gw string) NetworkOpt

WithNetworkGateway sets the gateway for the network.

func WithNetworkLabel

func WithNetworkLabel(key, value string) NetworkOpt

WithNetworkLabel adds a label to the network.

func WithNetworkSubnet

func WithNetworkSubnet(subnet string) NetworkOpt

WithNetworkSubnet sets the subnet for the network.

type NotFoundError

type NotFoundError struct {
	Resource string
	ID       string
}

NotFoundError indicates the requested resource was not found.

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

type Opt

type Opt func(*clientOpts) error

Opt configures a Client.

func WithAPIVersion

func WithAPIVersion(version string) Opt

WithAPIVersion overrides the Docker API version prefix (default "v1.51").

func WithSocketPath

func WithSocketPath(path string) Opt

WithSocketPath sets the Unix socket path to connect to. Default: $HOME/.socktainer/container.sock

func WithTimeout

func WithTimeout(d time.Duration) Opt

WithTimeout sets a default timeout for API calls.

type PullOpt

type PullOpt func(*pullConfig)

PullOpt configures image pull.

func WithPullPlatform

func WithPullPlatform(platform string) PullOpt

WithPullPlatform sets the platform for the pull.

func WithPullTag

func WithPullTag(tag string) PullOpt

WithPullTag sets a specific tag to pull.

type PushOpt

type PushOpt func(*pushConfig)

PushOpt configures image push.

type RestartOpt

type RestartOpt func(*restartConfig)

RestartOpt configures container restart.

func WithRestartTimeout

func WithRestartTimeout(seconds int) RestartOpt

WithRestartTimeout sets the seconds to wait before killing during restart.

type StartOpt

type StartOpt func(*startConfig)

type StatsOpt

type StatsOpt func(*statsConfig)

StatsOpt configures container stats retrieval.

type StopOpt

type StopOpt func(*stopConfig)

StopOpt configures container stop behavior.

func WithStopSignal

func WithStopSignal(sig string) StopOpt

WithStopSignal sets the signal to send (default SIGTERM).

func WithStopTimeout

func WithStopTimeout(seconds int) StopOpt

WithStopTimeout sets the seconds to wait before killing.

type VolumeOpt

type VolumeOpt func(*volumeConfig)

VolumeOpt configures volume creation.

func WithVolumeDriver

func WithVolumeDriver(driver string) VolumeOpt

WithVolumeDriver sets the volume driver.

func WithVolumeLabel

func WithVolumeLabel(key, value string) VolumeOpt

WithVolumeLabel adds a label to the volume.

type WaitResult

type WaitResult struct {
	StatusCode int64
}

WaitResult holds the outcome of a container wait.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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