docker

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AutomaticTaskInterval = 24 * time.Hour
	HealthCheckPath       = "/up"
)
View Source
const (
	BackupDataDir   = "data"
	BackupRetention = 30 * 24 * time.Hour
)
View Source
const (
	DefaultHTTPPort    = 80
	DefaultHTTPSPort   = 443
	DefaultMetricsPort = 1318
)
View Source
const ContainerLogMaxSize = "10m"
View Source
const (
	DefaultLogBufferSize = 10000
)
View Source
const DefaultNamespace = "once"

Variables

View Source
var (
	ErrApplicationExists  = errors.New("application already exists")
	ErrHostnameInUse      = errors.New("hostname already in use")
	ErrHostRequired       = errors.New("host is required")
	ErrInvalidBackup      = errors.New("invalid backup archive")
	ErrBackupPathRelative = errors.New("backup path must be absolute")
	ErrSetupFailed        = errors.New("setup failed")
	ErrPullFailed         = &describedError{
		msg:         "pull failed",
		description: "Failed to download the application image. Check that the image name is correct and try again.",
	}
	ErrDeployFailed       = errors.New("deploy failed")
	ErrVerificationFailed = &describedError{
		msg:         "verification failed",
		description: "The application did not respond to a health check after starting. It may have crashed or need longer to start up.",
	}
	ErrUnpauseFailed = errors.New("failed to unpause container after backup")
)
View Source
var (
	ErrProxyPortInUse = &describedError{
		msg:         "proxy port conflict",
		description: "Something else is using the web ports on this machine. You'll need to stop that service, and then try deploying again.",
	}
	ErrAppNotStarted = &describedError{
		msg:         "application did not start",
		description: "The application did not start within the time limit. Check the application logs for errors.",
	}
)
View Source
var AppVolumeMountTargets = []string{"/storage", "/rails/storage"}

AppVolumeMountTargets defines the paths where the app data volume is mounted inside the container. The first entry is the primary path used for backups.

View Source
var ErrInvalidNamespace = errors.New("invalid namespace: must contain only lowercase letters, digits, and hyphens, and must not start with a hyphen")
View Source
var ErrVolumeNotFound = errors.New("volume not found")

Functions

func ContainerLogConfig

func ContainerLogConfig() container.LogConfig

func ContainerRandomID

func ContainerRandomID() (string, error)

func ErrorMessage added in v0.1.2

func ErrorMessage(err error) string

func IsLocalhost

func IsLocalhost(host string) bool

func NameFromImageRef

func NameFromImageRef(imageRef string) string

Types

type AppState

type AppState struct {
	LastBackup OperationResult `json:"lastBackup"`
	LastUpdate OperationResult `json:"lastUpdate"`
}

func (*AppState) LastBackupResult

func (as *AppState) LastBackupResult() *OperationResult

func (*AppState) LastUpdateResult

func (as *AppState) LastUpdateResult() *OperationResult

type Application

type Application struct {
	Settings     ApplicationSettings
	Running      bool
	RunningSince time.Time
	// contains filtered or unexported fields
}

func NewApplication

func NewApplication(ns *Namespace, settings ApplicationSettings) *Application

func (*Application) Backup

func (a *Application) Backup(ctx context.Context) error

func (*Application) BackupName

func (a *Application) BackupName() string

func (*Application) BackupToFile

func (a *Application) BackupToFile(ctx context.Context, dir string, name string) error

func (*Application) ContainerName

func (a *Application) ContainerName(ctx context.Context) (string, error)

func (*Application) Deploy

func (a *Application) Deploy(ctx context.Context, progress DeployProgressCallback) error

func (*Application) Destroy

func (a *Application) Destroy(ctx context.Context, destroyVolumes bool) error

func (*Application) Remove

func (a *Application) Remove(ctx context.Context, removeData bool) error

func (*Application) Restore

func (a *Application) Restore(ctx context.Context, volSettings ApplicationVolumeSettings, volumeData []byte) (returnErr error)

func (*Application) Start

func (a *Application) Start(ctx context.Context) error

func (*Application) Stop

func (a *Application) Stop(ctx context.Context) error

func (*Application) TrimBackups

func (a *Application) TrimBackups() error

func (*Application) URL

func (a *Application) URL() string

func (*Application) Update

func (a *Application) Update(ctx context.Context, progress DeployProgressCallback) (bool, error)

func (*Application) VerifyHTTP

func (a *Application) VerifyHTTP(ctx context.Context) error

func (*Application) Volume

func (a *Application) Volume(ctx context.Context) (*ApplicationVolume, error)

type ApplicationSettings

type ApplicationSettings struct {
	Name       string             `json:"name"`
	Image      string             `json:"image"`
	Host       string             `json:"host"`
	DisableTLS bool               `json:"disableTLS"`
	EnvVars    map[string]string  `json:"env"`
	SMTP       SMTPSettings       `json:"smtp"`
	Resources  ContainerResources `json:"resources"`
	AutoUpdate bool               `json:"autoUpdate"`
	Backup     BackupSettings     `json:"backup"`
}

func UnmarshalApplicationSettings

func UnmarshalApplicationSettings(s string) (ApplicationSettings, error)

func (ApplicationSettings) BuildEnv

func (ApplicationSettings) Equal

func (ApplicationSettings) Marshal

func (s ApplicationSettings) Marshal() string

func (ApplicationSettings) TLSEnabled

func (s ApplicationSettings) TLSEnabled() bool

type ApplicationVolume

type ApplicationVolume struct {
	Settings ApplicationVolumeSettings
	// contains filtered or unexported fields
}

func CreateVolume

func CreateVolume(ctx context.Context, ns *Namespace, name string, settings ApplicationVolumeSettings) (*ApplicationVolume, error)

func FindVolume

func FindVolume(ctx context.Context, ns *Namespace, name string) (*ApplicationVolume, error)

func (*ApplicationVolume) Destroy

func (v *ApplicationVolume) Destroy(ctx context.Context) error

func (*ApplicationVolume) Name

func (v *ApplicationVolume) Name() string

func (*ApplicationVolume) SecretKeyBase

func (v *ApplicationVolume) SecretKeyBase() string

type ApplicationVolumeSettings

type ApplicationVolumeSettings struct {
	SecretKeyBase   string `json:"secretKeyBase"`
	VAPIDPublicKey  string `json:"vapidPublicKey"`
	VAPIDPrivateKey string `json:"vapidPrivateKey"`
}

func UnmarshalApplicationVolumeSettings

func UnmarshalApplicationVolumeSettings(s string) (ApplicationVolumeSettings, error)

func (ApplicationVolumeSettings) Marshal

func (s ApplicationVolumeSettings) Marshal() string

type BackupSettings

type BackupSettings struct {
	Path       string `json:"path,omitempty"`
	AutoBackup bool   `json:"autoBackup,omitempty"`
}

type ContainerResources

type ContainerResources struct {
	CPUs     int `json:"cpus,omitempty"`
	MemoryMB int `json:"memoryMB,omitempty"`
}

type DeployOptions

type DeployOptions struct {
	AppName string
	Target  string
	Host    string
	TLS     bool
}

type DeployProgress

type DeployProgress struct {
	Stage      DeployStage
	Percentage int
}

type DeployProgressCallback

type DeployProgressCallback func(DeployProgress)

type DeployStage

type DeployStage int
const (
	DeployStageDownloading DeployStage = iota
	DeployStageStarting
	DeployStageFinished
)

type DescribedError added in v0.1.2

type DescribedError interface {
	error
	Description() string
}

type EventWatcher

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

func NewEventWatcher

func NewEventWatcher(c *client.Client, namespace string) *EventWatcher

func (*EventWatcher) Watch

func (w *EventWatcher) Watch(ctx context.Context) <-chan struct{}

Watch returns a channel that signals when a container in this namespace changes state. The channel is closed when the context is cancelled.

type ExecResult

type ExecResult struct {
	Stdout   string
	Stderr   string
	ExitCode int
}

type LogLine

type LogLine struct {
	Content  string
	IsStderr bool
}

type LogStreamer

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

func NewLogStreamer

func NewLogStreamer(ns *Namespace, settings LogStreamerSettings) *LogStreamer

func (*LogStreamer) Count

func (s *LogStreamer) Count() int

func (*LogStreamer) Fetch

func (s *LogStreamer) Fetch(n int) []LogLine

Fetch returns the last n lines in chronological order (oldest first).

func (*LogStreamer) Ready

func (s *LogStreamer) Ready() bool

func (*LogStreamer) Start

func (s *LogStreamer) Start(ctx context.Context, containerName string)

func (*LogStreamer) Stop

func (s *LogStreamer) Stop()

func (*LogStreamer) Version

func (s *LogStreamer) Version() uint64

type LogStreamerSettings

type LogStreamerSettings struct {
	BufferSize int
}

type Namespace

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

func NewNamespace

func NewNamespace(name string, opts ...NamespaceOption) (*Namespace, error)

func RestoreNamespace

func RestoreNamespace(ctx context.Context, name string) (*Namespace, error)

func (*Namespace) Application

func (n *Namespace) Application(name string) *Application

func (*Namespace) ApplicationExists

func (n *Namespace) ApplicationExists(ctx context.Context, name string) (bool, error)

func (*Namespace) Applications

func (n *Namespace) Applications() []*Application

func (*Namespace) DockerRootDir

func (n *Namespace) DockerRootDir(ctx context.Context) (string, error)

func (*Namespace) EnsureNetwork

func (n *Namespace) EnsureNetwork(ctx context.Context) error

func (*Namespace) EventWatcher

func (n *Namespace) EventWatcher() *EventWatcher

func (*Namespace) HostInUse

func (n *Namespace) HostInUse(host string) bool

func (*Namespace) HostInUseByAnother

func (n *Namespace) HostInUseByAnother(host string, excludeApp string) bool

func (*Namespace) LoadState

func (n *Namespace) LoadState(ctx context.Context) (*State, error)

func (*Namespace) Name

func (n *Namespace) Name() string

func (*Namespace) Proxy

func (n *Namespace) Proxy() *Proxy

func (*Namespace) Refresh

func (n *Namespace) Refresh(ctx context.Context) error

func (*Namespace) Restore

func (n *Namespace) Restore(ctx context.Context, r io.Reader) (*Application, error)

func (*Namespace) SaveState

func (n *Namespace) SaveState(ctx context.Context, state *State) error

func (*Namespace) Setup

func (n *Namespace) Setup(ctx context.Context) error

func (*Namespace) Teardown

func (n *Namespace) Teardown(ctx context.Context, destroyVolumes bool) error

func (*Namespace) UniqueName

func (n *Namespace) UniqueName(base string) (string, error)

type NamespaceOption

type NamespaceOption func(*Namespace)

func WithApplications

func WithApplications(apps ...ApplicationSettings) NamespaceOption

type OperationResult

type OperationResult struct {
	At    time.Time `json:"at"`
	Error string    `json:"error"`
}

type Proxy

type Proxy struct {
	Settings *ProxySettings
	// contains filtered or unexported fields
}

func NewProxy

func NewProxy(ns *Namespace) *Proxy

func (*Proxy) Boot

func (p *Proxy) Boot(ctx context.Context, settings ProxySettings) error

func (*Proxy) Deploy

func (p *Proxy) Deploy(ctx context.Context, opts DeployOptions) error

func (*Proxy) Destroy

func (p *Proxy) Destroy(ctx context.Context) error

func (*Proxy) Exec

func (p *Proxy) Exec(ctx context.Context, cmd []string) error

func (*Proxy) ExecOutput

func (p *Proxy) ExecOutput(ctx context.Context, cmd []string) (string, error)

func (*Proxy) LoadState

func (p *Proxy) LoadState(ctx context.Context) (*State, error)

func (*Proxy) Remove

func (p *Proxy) Remove(ctx context.Context, appName string) error

func (*Proxy) SaveState

func (p *Proxy) SaveState(ctx context.Context, state *State) error

type ProxySettings

type ProxySettings struct {
	HTTPPort    int `json:"httpPort"`
	HTTPSPort   int `json:"httpsPort"`
	MetricsPort int `json:"metricsPort"`
}

func UnmarshalProxySettings

func UnmarshalProxySettings(s string) (ProxySettings, error)

func (ProxySettings) Marshal

func (s ProxySettings) Marshal() string

type RingBuffer

type RingBuffer[T any] struct {
	// contains filtered or unexported fields
}

RingBuffer is a fixed-size circular buffer. It is not thread-safe; callers must synchronize access externally.

func NewRingBuffer

func NewRingBuffer[T any](size int) *RingBuffer[T]

func (*RingBuffer[T]) Add

func (b *RingBuffer[T]) Add(item T)

func (*RingBuffer[T]) FetchNewestFirst

func (b *RingBuffer[T]) FetchNewestFirst(n int) []T

FetchNewestFirst returns up to n items in reverse chronological order (newest first).

func (*RingBuffer[T]) FetchOldestFirst

func (b *RingBuffer[T]) FetchOldestFirst(n int) []T

FetchOldestFirst returns up to n items in chronological order (oldest first).

func (*RingBuffer[T]) Len

func (b *RingBuffer[T]) Len() int

type SMTPSettings

type SMTPSettings struct {
	Server   string `json:"server,omitempty"`
	Port     string `json:"port,omitempty"`
	Username string `json:"username,omitempty"`
	Password string `json:"password,omitempty"`
	From     string `json:"from,omitempty"`
}

func (SMTPSettings) BuildEnv

func (s SMTPSettings) BuildEnv() []string

type Sample

type Sample struct {
	Timestamp   time.Time
	CPUPercent  float64
	MemoryBytes uint64
}

Sample represents CPU and memory stats for a single scrape interval

type Scraper

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

Scraper collects Docker container stats using persistent streaming connections. Background goroutines maintain streams for each container and update latest stats. Scrape() snapshots the current values without blocking on Docker API calls.

func NewScraper

func NewScraper(ns *Namespace, settings ScraperSettings) *Scraper

func (*Scraper) Fetch

func (s *Scraper) Fetch(appName string, n int) []Sample

Fetch returns the last n samples for an app, ordered from newest to oldest. If fewer than n samples exist, only the available samples are returned.

func (*Scraper) LastError

func (s *Scraper) LastError() error

func (*Scraper) Scrape

func (s *Scraper) Scrape(ctx context.Context)

Scrape snapshots the latest stats from streaming connections and records samples. It also ensures streams are running for all current containers.

type ScraperSettings

type ScraperSettings struct {
	BufferSize int
}

ScraperSettings configures the docker stats scraper

type State

type State struct {
	Apps           map[string]*AppState `json:"apps"`
	LastSelfUpdate OperationResult      `json:"lastSelfUpdate"`
}

func (*State) AppState

func (s *State) AppState(appName string) *AppState

func (*State) BackupDue

func (s *State) BackupDue(appName string) bool

func (*State) RecordBackup

func (s *State) RecordBackup(appName string, err error)

func (*State) RecordSelfUpdate

func (s *State) RecordSelfUpdate(err error)

func (*State) RecordUpdate

func (s *State) RecordUpdate(appName string, err error)

func (*State) SelfUpdateDue

func (s *State) SelfUpdateDue() bool

func (*State) UpdateDue

func (s *State) UpdateDue(appName string) bool

Jump to

Keyboard shortcuts

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