Documentation
¶
Overview ¶
Package compose: service toggle helper.
Compose-aware plugin enable/disable for Model A.
For Model A plugins (compose-managed services), enable/disable means commenting or uncommenting the service block in docker-compose.yml. We do this with a textual scanner rather than a full YAML parse so the operation is reversible and survives surrounding hand-edits.
Conventions:
- A service block runs from the `<service-name>:` line at indentation 2 (two spaces) to the next service header (also at indentation 2) or the next top-level key.
- To DISABLE: prefix every line of the service block with `# ` (the existing indentation is preserved). A `# nself-disabled: <name>` marker line is inserted immediately above the block so we can find it again.
- To ENABLE: locate the marker line, strip the `# ` prefix from each subsequent block line, and remove the marker.
Idempotency: ToggleService is safe to call repeatedly with the same target state. ToggleService(yaml, "claw", false) on an already-disabled service returns the input unchanged.
Index ¶
- Constants
- Variables
- func CatalogNames() []string
- func DigestForContent(b []byte) string
- func IsValidDigest(s string) bool
- func LoadImageDigests(projectDir string) error
- func NormalizeDigest(s string) (string, error)
- func PinImage(imageTag, digest string) string
- func ResolveImage(service, image string) string
- func SaveImageDigests(projectDir string, digests map[string]string) error
- func SplitImageRef(ref string) (name, tag, digest string)
- func ToggleService(yaml, serviceName string, enable bool) (string, bool, error)
- func ValidProfiles() []string
- type BuildConfig
- type CatalogEntry
- type DepOn
- type DeployConfig
- type DockerCompose
- type Generator
- type Healthcheck
- type LoggingConfig
- type NetworkConfig
- type ProfileName
- type ResourceLimits
- type Resources
- type ServiceConfig
- type ServiceSecurity
- type ServiceSet
- type ServiceTier
- type VolumeConfig
Constants ¶
const AdminImagePath = "nself/nself-admin"
AdminImagePath is the Docker Hub image name for the nSelf Admin GUI service. It uses the Docker Hub nself/ namespace (NOT GitHub Container Registry). Intentionally referencing nself/nself-admin (Docker Hub) — never github.com/nself-org/ paths.
const DigestConfigFile = ".nself-image-digests.json"
DigestConfigFile is the filename where image digests are stored.
const DigestLength = 64
DigestLength is the hex length of a sha256 digest.
const DigestPrefix = "sha256:"
DigestPrefix is the fixed algorithm prefix for OCI image digests.
const NginxConfDDir = "nginx/conf.d"
NginxConfDDir is the host-side directory for env-specific nginx conf.d files. Hand-managed, safe to edit directly.
const NginxSitesDir = "nginx/sites"
NginxSitesDir is the host-side directory for generated nginx site configs. GENERATED by nself build — never hand-edit.
Variables ¶
var DefaultImageVersions = map[string]string{ "postgres": "pgvector/pgvector:pg16", "hasura": "hasura/graphql-engine:v2.44.0", "auth": "nhost/hasura-auth:0.36.0", "nginx": "nginx:1.25-alpine", "redis": "redis:7.2-alpine", "minio": "minio/minio:RELEASE.2024-01-16T16-07-38Z", "functions": "nhost/functions:0.3.7", "mailpit": "axllent/mailpit:v1.15", "meilisearch": "getmeili/meilisearch:v1.6", "typesense": "typesense/typesense:0.25.2", "admin": AdminImagePath + ":latest", "mlflow": "ghcr.io/mlflow/mlflow:v2.10.0", }
DefaultImageVersions maps service name to pinned image:tag. Update with each nSelf release.
var ImageDigests = map[string]string{}
ImageDigests maps service name to sha256 digest for image pinning. When a digest is available, ResolveImage appends @sha256:... to the tag. Populated by LoadImageDigests from the project config directory.
Functions ¶
func CatalogNames ¶ added in v1.3.0
func CatalogNames() []string
CatalogNames returns every catalogued service name, sorted.
func DigestForContent ¶ added in v1.0.9
DigestForContent returns the sha256 hex digest for the given bytes. Primarily useful for tests and for computing digests of content the CLI itself generates (manifests, configs). NOT a replacement for pulling an authoritative digest from a registry — that requires talking to the registry API.
func IsValidDigest ¶ added in v1.0.9
IsValidDigest returns true if s is a well-formed sha256 digest (64 hex chars, with or without the "sha256:" prefix).
func LoadImageDigests ¶ added in v1.0.6
LoadImageDigests reads digest pins from the project config directory. Missing file is not an error (digests are opt-in via `nself update images`).
func NormalizeDigest ¶ added in v1.0.9
NormalizeDigest strips a leading "sha256:" prefix and lower-cases the hex. Returns an error if the input is not a valid sha256 digest.
func PinImage ¶ added in v1.0.9
PinImage returns the fully-pinned image reference for the given image:tag and digest. If digest is empty the image is returned unchanged (no pin).
PinImage("postgres:16", "abc...") -> "postgres:16@sha256:abc..."
PinImage("postgres:16", "") -> "postgres:16"
If the image already contains an @sha256: suffix, the existing pin is replaced with the new one (trust the caller — they asked to repin).
func ResolveImage ¶
ResolveImage returns the image tag for a service, optionally with a sha256 digest suffix when available.
Precedence: a non-empty caller-supplied image (built from env/config such as POSTGRES_VERSION / HASURA_VERSION) ALWAYS wins. The DefaultImageVersions pin applies only when the caller supplies no image. Pins overriding configured versions force-migrated existing deployments on upgrade (P1 EOP staging incident 2026-06-10: postgres:16-alpine volume recreated as pgvector pg16).
func SaveImageDigests ¶ added in v1.0.6
SaveImageDigests writes digest pins to the project config directory.
func SplitImageRef ¶ added in v1.0.9
SplitImageRef splits an image reference into its constituent parts:
SplitImageRef("postgres:16@sha256:abc...")
-> name="postgres", tag="16", digest="abc..."
SplitImageRef("ghcr.io/foo/bar:v1")
-> name="ghcr.io/foo/bar", tag="v1", digest=""
SplitImageRef("alpine")
-> name="alpine", tag="latest", digest=""
Registries with port numbers (localhost:5000/foo:v1) are handled by scanning right-to-left for the tag separator.
func ToggleService ¶ added in v1.0.16
ToggleService comments or uncomments the named service block in the supplied docker-compose YAML text. It returns the new YAML text and a bool reporting whether the file was changed.
enable=true → uncomment a previously disabled block (no-op if already enabled) enable=false → comment out an enabled block (no-op if already disabled)
func ValidProfiles ¶ added in v1.1.11
func ValidProfiles() []string
ValidProfiles returns the list of known profile names in deterministic order. Used by --help text and shell completions.
Types ¶
type BuildConfig ¶
type BuildConfig struct {
Context string `yaml:"context"`
Dockerfile string `yaml:"dockerfile,omitempty"`
}
BuildConfig represents the build context for a service.
type CatalogEntry ¶ added in v1.3.0
type CatalogEntry struct {
// Name is the compose service name, matching the key in DockerCompose.Services.
Name string
// Tier is required or optional.
Tier ServiceTier
// Purpose is a one-line description for docs and `service list`.
Purpose string
// EnableEnv is the environment variable that switches an optional service
// on. Empty for required services, which have no off switch.
EnableEnv string
// VersionEnv is the environment variable that overrides the image tag.
VersionEnv string
// DefaultImage is the pinned image used when VersionEnv is unset. Resolved
// from DefaultImageVersions so version bumps have a single home.
DefaultImage string
// ImageKey overrides the DefaultImageVersions lookup key when the compose
// service name differs from it (nself-admin is pinned under "admin").
ImageKey string
}
CatalogEntry describes one service in the stack.
func CatalogEntryFor ¶ added in v1.3.0
func CatalogEntryFor(name string) (CatalogEntry, bool)
CatalogEntryFor looks a service up by compose name.
func CoreServices ¶ added in v1.3.0
func CoreServices() []CatalogEntry
CoreServices returns the services present in every app-profile stack.
func OptionalServices ¶ added in v1.3.0
func OptionalServices() []CatalogEntry
OptionalServices returns the services that require a config gate.
func ServiceCatalog ¶ added in v1.3.0
func ServiceCatalog() []CatalogEntry
ServiceCatalog returns every catalogued service with its default image resolved from DefaultImageVersions.
type DepOn ¶
type DepOn struct {
Condition string `yaml:"condition"`
}
DepOn represents a service dependency with a condition.
type DeployConfig ¶
type DeployConfig struct {
Resources *Resources `yaml:"resources,omitempty"`
}
DeployConfig represents deployment constraints for a service.
type DockerCompose ¶
type DockerCompose struct {
Name string `yaml:"name"`
Networks map[string]NetworkConfig `yaml:"networks"`
Volumes map[string]VolumeConfig `yaml:"volumes"`
Services map[string]ServiceConfig `yaml:"-"`
ServiceOrder []string `yaml:"-"`
}
DockerCompose represents a complete docker-compose.yml file. Services are stored as a map for fast lookup, but ServiceOrder tracks insertion order so that MarshalYAML emits them in dependency order (init containers before their dependents, postgres before hasura, nginx last).
func (*DockerCompose) AddService ¶
func (dc *DockerCompose) AddService(name string, svc ServiceConfig)
AddService inserts a service into the compose file, preserving insertion order via ServiceOrder. If the service name already exists, it is replaced in-place without changing the order.
func (*DockerCompose) MarshalYAML ¶
func (dc *DockerCompose) MarshalYAML() (interface{}, error)
MarshalYAML outputs the compose file with services in ServiceOrder rather than Go's default alphabetical map ordering. This ensures init containers appear before services that depend on them, which Docker Compose v5 requires.
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator builds a docker-compose.yml from project configuration.
func NewGenerator ¶
NewGenerator creates a compose Generator from the given config using the default "app" profile (full service set — no regression from pre-profile builds).
func NewGeneratorWithProfile ¶ added in v1.1.11
func NewGeneratorWithProfile(cfg *config.Config, name ProfileName) *Generator
NewGeneratorWithProfile creates a compose Generator that emits only the services permitted by the named profile. Unknown profile names fall back to ProfileApp and are not treated as hard errors here (the caller should warn).
Purpose: enable curated deployments (e.g. ProfileOps for an observability server) without touching the config layer. Inputs: cfg — project configuration; name — profile selected by the user. Outputs: *Generator with profile gate set.
type Healthcheck ¶
type Healthcheck struct {
Test []string `yaml:"test"`
Interval string `yaml:"interval,omitempty"`
Timeout string `yaml:"timeout,omitempty"`
Retries int `yaml:"retries,omitempty"`
StartPeriod string `yaml:"start_period,omitempty"`
}
Healthcheck represents a service health check configuration.
type LoggingConfig ¶
type LoggingConfig struct {
Driver string `yaml:"driver"`
Options map[string]string `yaml:"options,omitempty"`
}
LoggingConfig represents the logging driver and options for a service.
type NetworkConfig ¶
type NetworkConfig struct {
Driver string `yaml:"driver,omitempty"`
// Name pins the real Docker network name. Without it, compose prefixes the
// project name (e.g. key "myproj_network" becomes "myproj_myproj_network"),
// which split recreated services onto a new network on existing deployments
// (P1 EOP prod incident 2026-06-10: nginx 502 on api.nself.org).
Name string `yaml:"name,omitempty"`
}
NetworkConfig represents a docker-compose network definition.
type ProfileName ¶ added in v1.1.11
type ProfileName string
ProfileName identifies a named service profile.
const ( // ProfileApp is the default profile: every service enabled by config // is included. Identical to pre-profile behaviour — no regression. ProfileApp ProfileName = "app" // ProfileOps is the observability + CI + functions + registry profile. // Core data services (postgres, hasura, auth, nginx) plus the monitoring // stack are included. App-specific services (minio, mailpit, admin, // functions-v8 SaaS, search, nself-admin) are excluded. // // Reserve service name stubs for ops-only services whose compose fragments // will be contributed by dedicated plugins (forgejo, container-registry, // functions-v8). Listing them here documents the intended topology even // before those plugins exist. ProfileOps ProfileName = "ops" )
type ResourceLimits ¶
type ResourceLimits struct {
Memory string `yaml:"memory,omitempty"`
CPUs string `yaml:"cpus,omitempty"`
Pids int64 `yaml:"pids,omitempty"`
}
ResourceLimits represents CPU and memory limits.
type Resources ¶
type Resources struct {
Limits *ResourceLimits `yaml:"limits,omitempty"`
Reservations *ResourceLimits `yaml:"reservations,omitempty"`
}
Resources represents resource constraints.
type ServiceConfig ¶
type ServiceConfig struct {
Image string `yaml:"image,omitempty"`
Build *BuildConfig `yaml:"build,omitempty"`
ContainerName string `yaml:"container_name,omitempty"`
Restart string `yaml:"restart,omitempty"`
ShmSize string `yaml:"shm_size,omitempty"`
User string `yaml:"user,omitempty"`
Networks []string `yaml:"networks,omitempty"`
DependsOn map[string]DepOn `yaml:"depends_on,omitempty"`
Environment map[string]string `yaml:"environment,omitempty"`
Volumes []string `yaml:"volumes,omitempty"`
Ports []string `yaml:"ports,omitempty"`
Expose []string `yaml:"expose,omitempty"`
Command interface{} `yaml:"command,omitempty"`
Entrypoint interface{} `yaml:"entrypoint,omitempty"`
Healthcheck *Healthcheck `yaml:"healthcheck,omitempty"`
Deploy *DeployConfig `yaml:"deploy,omitempty"`
Logging *LoggingConfig `yaml:"logging,omitempty"`
SecurityOpt []string `yaml:"security_opt,omitempty"`
CapDrop []string `yaml:"cap_drop,omitempty"`
CapAdd []string `yaml:"cap_add,omitempty"`
StopGrace string `yaml:"stop_grace_period,omitempty"`
Labels map[string]string `yaml:"labels,omitempty"`
Profiles []string `yaml:"profiles,omitempty"`
ReadOnly bool `yaml:"read_only,omitempty"`
Tmpfs []string `yaml:"tmpfs,omitempty"`
Privileged bool `yaml:"privileged,omitempty"`
WorkingDir string `yaml:"working_dir,omitempty"`
StdinOpen bool `yaml:"stdin_open,omitempty"`
Tty bool `yaml:"tty,omitempty"`
// CapDropComment is an optional comment injected into the generated YAML
// above cap_add when cap_drop is intentionally omitted. Not serialized as
// a YAML field — rendered as a comment via MarshalYAML.
CapDropComment string `yaml:"-"`
}
ServiceConfig represents a single service in docker-compose.yml.
type ServiceSecurity ¶
type ServiceSecurity struct {
CapDrop []string
CapAdd []string
SecurityOpt []string
ReadOnly bool
Tmpfs []string
User string
}
ServiceSecurity holds Docker security configuration for a service.
func DefaultSecurity ¶
func DefaultSecurity() ServiceSecurity
DefaultSecurity returns the security config applied to most services. read_only root FS with /tmp and /run as tmpfs.
func MinioSecurity ¶ added in v1.0.6
func MinioSecurity() ServiceSecurity
MinioSecurity returns the security config for the MinIO service. MinIO needs CHOWN/SETUID/SETGID for data directory ownership.
func NginxSecurity ¶ added in v1.0.6
func NginxSecurity() ServiceSecurity
NginxSecurity returns the security config for the Nginx service. Nginx needs NET_BIND_SERVICE for ports 80/443 when running non-root.
func PostgresSecurity ¶
func PostgresSecurity() ServiceSecurity
PostgresSecurity returns the security config for the PostgreSQL service. PostgreSQL needs IPC_LOCK for shared memory and CHOWN/SETUID/SETGID for initdb. Root FS is read-only; data dir is a writable volume.
func RedisSecurity ¶ added in v1.0.6
func RedisSecurity() ServiceSecurity
RedisSecurity returns the security config for the Redis service.
type ServiceSet ¶ added in v1.1.11
type ServiceSet struct {
// CoreDB enables postgres (unless EmbeddedPG is active).
CoreDB bool
// Hasura enables the Hasura GraphQL engine.
Hasura bool
// Auth enables the nhost/hasura-auth service.
Auth bool
// Nginx enables the nginx reverse proxy (always last in the compose file).
Nginx bool
// Redis enables the Redis cache/queue service (when cfg.Redis.Enabled).
Redis bool
// Minio enables the MinIO object storage service (when cfg.Minio.Enabled).
Minio bool
// Mailpit enables the Mailpit dev SMTP server (when cfg.Mailpit.Enabled).
Mailpit bool
// AdminUI enables the nSelf Admin web UI (when cfg.Admin.Enabled).
AdminUI bool
// Functions enables the Functions runtime (when cfg.Functions.Enabled).
Functions bool
// Search enables the search engine (meilisearch/typesense) when configured.
Search bool
// Monitoring enables the monitoring stack (prometheus, grafana, loki, etc.)
// when cfg.Monitoring.Enabled. The compose services are contributed by the
// nself-monitoring plugin; this flag only gates the config rendering step.
Monitoring bool
// OpsServices is true when ops-profile-specific reserved service stubs are
// declared. Actual compose fragments for forgejo, container-registry, and
// functions-v8 are contributed by dedicated plugins; this flag marks intent.
//
// Reserved ops service names (F08-SERVICE-INVENTORY):
// - forgejo (lightweight Gitea-compatible forge for CI/CD)
// - container-registry (OCI-compatible image registry, e.g. Zot/Distribution)
// - functions-v8 (Deno V8-isolate function runtime, ops-server variant)
OpsServices bool
}
ServiceSet describes which service families are allowed in a profile. Every bool field corresponds to a builder or conditional block in generator.go. Fields default to false; set only what the profile needs.
func ProfileForName ¶ added in v1.1.11
func ProfileForName(name ProfileName) (ServiceSet, bool)
ProfileForName returns the ServiceSet for the given profile name. Falls back to the ProfileApp set if the name is unrecognised, and returns false as the second value so callers can warn the user.
Callers: compose.Generator, build.Build.
type ServiceTier ¶ added in v1.3.0
type ServiceTier string
ServiceTier says whether a service is part of every stack or opt-in.
const ( // TierRequired services are present in every app profile. Removing one // produces a stack that cannot serve a request. TierRequired ServiceTier = "required" // TierOptional services are added only when their config gate is enabled. TierOptional ServiceTier = "optional" )
type VolumeConfig ¶
type VolumeConfig struct {
Driver string `yaml:"driver,omitempty"`
}
VolumeConfig represents a docker-compose volume definition.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package monitoring — alert rule and Alertmanager config generators.
|
Package monitoring — alert rule and Alertmanager config generators. |