services

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package services coordinates DB records with Docker containers.

Index

Constants

This section is empty.

Variables

View Source
var ValidStatuses = map[string]bool{
	"created":   true,
	"running":   true,
	"stopped":   true,
	"deploying": true,
	"failed":    true,
	"error":     true,
	"crashed":   true,
}

ValidStatuses is the set of recognised service status values.

Functions

func ValidateDNSName

func ValidateDNSName(name string) error

ValidateDNSName checks that a service name can produce a valid DNS label. Returns nil if OK, or an apierr.ValidationError describing the problem.

func ValidateEnvVars

func ValidateEnvVars(vars map[string]string) error

ValidateEnvVars checks env var keys and values for format and safety.

func ValidateImage

func ValidateImage(tenantID, img string) error

ValidateImage checks that an image reference is allowed.

Types

type CreateRequest

type CreateRequest struct {
	Name  string            `json:"name"`
	Image string            `json:"image"`
	Port  int               `json:"port"`
	Env   map[string]string `json:"env"`
}

CreateRequest holds parameters for creating a new service.

type Manager

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

Manager coordinates service lifecycle between DB and Docker.

func NewManager

func NewManager(db *sql.DB, docker docker.Client, masterKey []byte, baseDomain, traefikConfigDir string, deployStore *deployments.Store) *Manager

NewManager creates a service manager.

func (*Manager) Create

func (m *Manager) Create(ctx context.Context, tenantID string, req CreateRequest) (*Service, error)

Create inserts a new service record (status=created, not yet running). Enforces tenant quota (max_services).

func (*Manager) Delete

func (m *Manager) Delete(ctx context.Context, tenantID, serviceID string) error

Delete stops and removes the container, then deletes the DB record.

func (*Manager) DeleteEnv

func (m *Manager) DeleteEnv(ctx context.Context, tenantID, serviceID, key string) error

DeleteEnv removes a single environment variable.

func (*Manager) Deploy

func (m *Manager) Deploy(ctx context.Context, tenantID, serviceID string) error

Deploy pulls the image, reads env vars, creates and starts the container. Uses a bounded semaphore with a bounded queue for backpressure.

func (*Manager) DeployImage

func (m *Manager) DeployImage(ctx context.Context, tenantID, serviceID, imageTag, buildID string) error

DeployImage deploys a pre-built image (from nixpacks build) for a service. Similar to Deploy but skips image pull (image is already local or in registry). buildID links this deployment to the originating build record (may be empty).

func (*Manager) Get

func (m *Manager) Get(ctx context.Context, tenantID, serviceID string) (*Service, error)

Get returns a single service by ID, scoped to tenant.

func (*Manager) GetEnv

func (m *Manager) GetEnv(ctx context.Context, tenantID, serviceID string, reveal bool) (map[string]string, error)

GetEnv returns env var keys for a service. If reveal is true, returns decrypted values. Audit logs reveal operations for security monitoring.

func (*Manager) List

func (m *Manager) List(ctx context.Context, tenantID string) ([]*Service, error)

List returns all services for a tenant.

func (*Manager) ListPaginated

func (m *Manager) ListPaginated(ctx context.Context, tenantID string, limit, offset int, statusFilter ...string) ([]*Service, error)

ListPaginated returns services for a tenant with limit and offset. An optional statusFilter restricts results to services whose status matches one of the given values. Pass nil or an empty slice to list all.

func (*Manager) Logs

func (m *Manager) Logs(ctx context.Context, tenantID, serviceID string, follow bool, tail int) (io.ReadCloser, error)

Logs returns a reader for the service container logs.

func (*Manager) ResetCircuitBreaker

func (m *Manager) ResetCircuitBreaker(ctx context.Context, tenantID, serviceID string) error

ResetCircuitBreaker resets the circuit breaker for a service, allowing it to restart.

func (*Manager) Restart

func (m *Manager) Restart(ctx context.Context, tenantID, serviceID string) (retErr error)

Restart recreates the service container so that updated env vars take effect. Docker container env is immutable after creation; a stop+start does NOT apply env var changes. This method stops the old container, removes it, then runs a fresh container using the current image and env vars from the DB.

func (*Manager) SetEnv

func (m *Manager) SetEnv(ctx context.Context, tenantID, serviceID string, vars map[string]string) error

SetEnv sets or updates environment variables for a service.

func (*Manager) SetExternalTLSTerminated

func (m *Manager) SetExternalTLSTerminated(enabled bool)

SetExternalTLSTerminated configures routes for deployments where a trusted upstream proxy terminates public TLS before traffic reaches Traefik. Enabling it assumes public requests reach these routes only through that configured proxy; the route middleware then sets X-Forwarded-Proto to https.

func (*Manager) Start

func (m *Manager) Start(ctx context.Context, tenantID, serviceID string) error

Start starts a stopped service container. If the container no longer exists in Docker (e.g., after a circuit breaker reset), it clears the stale container_id and returns a clear error directing the user to redeploy.

func (*Manager) Stop

func (m *Manager) Stop(ctx context.Context, tenantID, serviceID string) error

Stop stops a running service container.

func (*Manager) StopAllForTenant

func (m *Manager) StopAllForTenant(ctx context.Context, tenantID string)

StopAllForTenant stops and removes all containers belonging to a tenant. Also cleans up any split-brain orphan containers by label.

func (*Manager) UpdateName

func (m *Manager) UpdateName(ctx context.Context, tenantID, serviceID, name string) (*Service, error)

UpdateName renames a service, updates its DNS label and Traefik route, and returns the updated service record. The name must be 1-128 characters and produce a valid DNS label when baseDomain is configured.

type Service

type Service struct {
	ID            string `json:"id"`
	TenantID      string `json:"tenant_id"`
	Name          string `json:"name"`
	DNSLabel      string `json:"dns_label,omitempty"`
	Status        string `json:"status"`
	Image         string `json:"image"`
	ContainerID   string `json:"container_id,omitempty"`
	Port          int    `json:"port"`
	URL           string `json:"url,omitempty"`
	LastError     string `json:"last_error,omitempty"`
	CrashCount    int    `json:"crash_count"`
	CircuitOpen   bool   `json:"circuit_open"`
	LastCrashedAt int64  `json:"last_crashed_at,omitempty"`
	CreatedAt     int64  `json:"created_at"`
	UpdatedAt     int64  `json:"updated_at"`
}

Service represents a deployed service.

Jump to

Keyboard shortcuts

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