Documentation
¶
Overview ¶
Package config — user-level telemetry preference management.
Telemetry preference is stored in ~/.nself/config.toml under [telemetry]. This file does NOT ship a telemetry client at v1.0.9. The preference is persisted now so the v1.1.0 client can respect choices made today.
Env var NSELF_TELEMETRY_OPT_OUT=1 always takes precedence over the file.
Index ¶
- Constants
- Variables
- func BuildJWTSecret(cfg *Config) (string, error)
- func BuildServiceURL(subdomain, baseDomain string) string
- func DefaultFor(key string) string
- func DetectMonorepoRoot(dir string) string
- func EnvCascadeOrder(envName string, legacy bool) []string
- func FindNSelfRoot(startDir string) (string, error)
- func KnownEnvVars() []string
- func LegacyOrderActive() bool
- func QuoteEnvValue(v string) string
- func RouteToFQDN(route, baseDomain string) (string, error)
- func SanitizeDBName(input string) (string, error)
- func SanitizeDomain(input string) (string, error)
- func SanitizeName(input string) (string, error)
- func SetTelemetryEnabled(enabled bool) error
- func UnquoteEnvValue(v string) string
- func Validate(cfg *Config) error
- func ValidateHasuraDevMode(cfg *Config) error
- func ValidateMinioCredentials(cfg *Config) error
- func ValidateNginxInputs(cfg *Config) error
- func ValidateRedisPassword(cfg *Config) error
- type AdminConfig
- type ApiDocsConfig
- type AuthConfig
- type BackupConfig
- type CascadeFile
- type Config
- type CustomService
- type DRConfig
- type ElasticsearchConfig
- type EmailConfig
- type FrontendApp
- type FunctionsConfig
- type HasuraConfig
- type InternalRoute
- type LicenseConfig
- type Loader
- type MLflowConfig
- type MailpitConfig
- type MeiliSearchConfig
- type MinioConfig
- type MonitoringConfig
- type NginxConfig
- type PgBouncerConfig
- type PluginProConfig
- type PluginSystemConfig
- type PostgresConfig
- type RedisConfig
- type RemoteSchema
- type SearchConfig
- type SecretsConfig
- type TelemetryPreference
- type TenantConfig
- type TypesenseConfig
- type ValidatorFunc
- type ValidatorResult
Constants ¶
const LegacyEnvOrderVar = "NSELF_LEGACY_ENV_ORDER"
LegacyEnvOrderVar is the escape-hatch environment variable that restores the pre-CLI-R18 cascade order for exactly one minor version after the reorder ships. Every use prints a warning naming the variable and the version it will stop being honored in — see warnLegacyEnvOrder in loader.go.
Variables ¶
var AllCascadeFilenames = []string{
".env",
".env.dev",
".env.staging",
".env.prod",
".env.secrets",
".env.local",
".env.ai",
}
AllCascadeFilenames is the fixed superset of every filename that appears in either cascade order, across every environment name. Used by the migration shim to read every candidate file once regardless of which order or env is being analyzed.
Functions ¶
func BuildJWTSecret ¶
BuildJWTSecret constructs the HASURA_GRAPHQL_JWT_SECRET JSON string. If the environment variable HASURA_GRAPHQL_JWT_SECRET is already set, it is returned directly. Otherwise the secret is constructed from cfg.Hasura.JWTKey and cfg.Hasura.JWTType, which are the single source of truth also used by buildAuthService for AUTH_JWT_SECRET/AUTH_JWT_TYPE (JWT-ALGO-01) — this guarantees Hasura verifies tokens with the exact algorithm+key auth signed them with. A missing JWTKey is auto-generated (matching ApplyDefaults' HS256-default behavior); an empty JWTType defaults to HS256 for the same reason: no RSA keypair generator exists in this codebase, so RS256 can only be produced correctly when the caller already went through ApplyDefaults (which rejects RS256 without a supplied key).
func BuildServiceURL ¶
BuildServiceURL constructs a full HTTPS URL for a service subdomain against the given baseDomain. If baseDomain already starts with "subdomain.", that prefix is stripped first to avoid double-prefixing (e.g. "auth.auth.example.com").
Examples:
BuildServiceURL("auth", "auth.example.com") → "https://auth.example.com"
BuildServiceURL("auth", "example.com") → "https://auth.example.com"
func DefaultFor ¶
DefaultFor returns the documented default value for an env var, as a human-readable string. Returns "" when the var has no static default (e.g. generated secrets, or dynamic per-env defaults).
func DetectMonorepoRoot ¶
DetectMonorepoRoot checks whether dir is a monorepo root by looking for an nself backend sub-directory containing a .env file. It probes, in order:
- <dir>/backend/.env
- <dir>/.backend/.env
Returns the full path to the backend directory if found, or "" if dir does not appear to be a monorepo root. The function never returns an error: a missing or unreadable path is treated as "not found".
func EnvCascadeOrder ¶ added in v1.3.0
EnvCascadeOrder returns the ordered list of filenames (lowest precedence first; later entries win) consulted to resolve the given environment name.
Canonical order (legacy=false), approved 2026-08-23 GATE B:
.env → .env.{dev|staging|prod} → .env.secrets → .env.local
.env is the shared, committed base. Exactly one of .env.dev/.env.staging/ .env.prod loads, matching envName. .env.secrets never ships in git. .env.local is the personal override and always wins. .env.ai no longer exists as a cascade layer — its content is folded into .env.secrets at init/upgrade (see internal/setup/envai.go and internal/migrate/env_order.go).
Legacy order (legacy=true), restored only via NSELF_LEGACY_ENV_ORDER for exactly one minor version:
.env.dev → .env.{staging|prod} → .env.secrets → .env.local → .env → .env.ai
.env.dev always loaded as a base layer regardless of envName (a quirk the canonical order removes), with .env.staging/.env.prod layered on top only for those two envs, and bare .env / .env.ai winning last.
func FindNSelfRoot ¶
FindNSelfRoot walks up from startDir looking for a nself project root. It checks, at each directory level:
- startDir/.backend/.env → returns startDir/.backend (monorepo case)
- startDir/.env → returns startDir (already in backend dir)
Walking stops at $HOME, at /, or after 10 levels — whichever comes first. Returns an error if no project root is found.
func KnownEnvVars ¶
func KnownEnvVars() []string
KnownEnvVars returns the list of environment variable names that the CLI loader reads. Used by commands like `nself config list` to display known vars with their current values.
func LegacyOrderActive ¶ added in v1.3.0
func LegacyOrderActive() bool
LegacyOrderActive reports whether the NSELF_LEGACY_ENV_ORDER escape hatch is set to a truthy value in the current process environment.
func QuoteEnvValue ¶ added in v1.1.1
QuoteEnvValue wraps v in single quotes when v is a JSON object or array value. Non-JSON values are returned unchanged. Single-quoted values are also returned unchanged (idempotent).
Example:
QuoteEnvValue(`{"type":"HS256","key":"abc"}`) → `'{"type":"HS256","key":"abc"}'`
QuoteEnvValue("plain-value") → "plain-value"
QuoteEnvValue(`'already-quoted'`) → `'already-quoted'`
func RouteToFQDN ¶
RouteToFQDN constructs a valid FQDN from a route segment and base domain. It trims whitespace, removes leading/trailing dots and slashes from both inputs, lowercases both, and returns "route.domain". Returns error if either input is empty after normalization.
func SanitizeDBName ¶ added in v1.3.6
SanitizeDBName converts a Docker-compatible project name (as produced by SanitizeName: lowercase alphanumeric + hyphens) into a value that satisfies the stricter PostgreSQL unquoted-identifier syntax enforced by database.SanitizeIdentifier (start with a letter or underscore; only letters, digits, and underscores after that; max 63 bytes).
PROJECT_NAME and POSTGRES_DB have different validity domains — Docker container/network names allow hyphens and a leading digit, SQL identifiers allow neither — so the raw project name (e.g. from a hyphenated directory like "rls-pentest-project") cannot be reused verbatim as the database name. This normalizes it instead of rejecting it, so init always produces a working POSTGRES_DB regardless of the source directory name.
Returns ("", err) only if nothing usable remains after normalization (e.g. an input made entirely of characters outside [a-z0-9_-. ]).
func SanitizeDomain ¶
SanitizeDomain lowercases, trims whitespace, trims trailing dots, and validates that only hostname-safe characters remain: letters, digits, dots, and hyphens ([a-zA-Z0-9.-]). Any other character (semicolons, spaces, asterisks, dollar signs, newlines, etc.) causes an error to prevent nginx config injection and similar attacks. Returns ("", err) if the result is empty or contains invalid characters.
func SanitizeName ¶
SanitizeName lowercases, trims whitespace, replaces spaces/underscores with hyphens, removes all non-alphanumeric-hyphen characters, collapses consecutive hyphens, and trims leading/trailing hyphens. Returns ("", err) if the result is empty after normalization.
func SetTelemetryEnabled ¶ added in v1.0.11
SetTelemetryEnabled persists the telemetry preference to ~/.nself/config.toml. Creates the file and directory if they do not exist.
func UnquoteEnvValue ¶ added in v1.1.1
UnquoteEnvValue strips a single layer of wrapping single quotes from v when the entire value is single-quoted. It is the inverse of QuoteEnvValue.
Example:
UnquoteEnvValue(`'{"type":"HS256","key":"abc"}'`) → `{"type":"HS256","key":"abc"}`
UnquoteEnvValue("plain-value") → "plain-value"
func Validate ¶
Validate checks cfg for security issues, port conflicts, and route collisions by running all registered validators. All failures are collected and returned together so the caller sees the full picture.
Password and JWT validations are only enforced when Env is "staging" or "prod". In dev mode, weak passwords are acceptable (the caller is expected to auto-generate strong ones before reaching validation).
func ValidateHasuraDevMode ¶
ValidateHasuraDevMode returns an error if HASURA_GRAPHQL_DEV_MODE=true in prod. When the block fires it emits a structured slog.Error so that operators with centralised log aggregation (Loki/Datadog) can alert on accidental dev-mode exposure. The error is always returned; the log is a side effect.
func ValidateMinioCredentials ¶ added in v1.1.8
ValidateMinioCredentials enforces strong MinIO credentials in staging and production. In dev, minioadmin defaults are accepted without error.
Rules (staging/prod only):
- MINIO_ROOT_USER must not be empty or "minioadmin".
- MINIO_ROOT_PASSWORD must not be "minioadmin" and must be >=16 chars.
Returns nil for dev environments unconditionally.
func ValidateNginxInputs ¶
ValidateNginxInputs validates raw nginx template inputs that are interpolated without escaping. Prevents nginx directive injection via env vars.
func ValidateRedisPassword ¶
ValidateRedisPassword returns an error if Redis is enabled in staging/prod without a password.
Types ¶
type AdminConfig ¶
type AdminConfig struct {
Enabled bool `env:"NSELF_ADMIN_ENABLED"`
Version string `env:"NSELF_ADMIN_VERSION"` // latest
Port int `env:"NSELF_ADMIN_PORT"` // 3021
Route string `env:"NSELF_ADMIN_ROUTE"` // admin.{BD}
DevMode bool `env:"NSELF_ADMIN_DEV"` // false
DevPort int `env:"NSELF_ADMIN_DEV_PORT"` // 3000
SecretKey string `env:"ADMIN_SECRET_KEY"`
PasswordHash string `env:"ADMIN_PASSWORD_HASH"`
}
AdminConfig holds nSelf Admin GUI configuration.
type ApiDocsConfig ¶ added in v1.0.12
type ApiDocsConfig struct {
Enabled bool `env:"API_DOCS_ENABLED"` // default: true
Path string `env:"API_DOCS_PATH"` // serve path, default: /docs
Title string `env:"API_DOCS_TITLE"` // defaults to "<ProjectName> API"
Theme string `env:"API_DOCS_THEME"` // default | moon | purple | solarized
AuthEnvVar string `env:"API_DOCS_AUTH_ENV_VAR"` // env var with bearer token for try-out
HideEndpoints []string // paths to exclude from the spec
GraphQLEnabled bool `env:"API_DOCS_GRAPHQL_ENABLED"` // default: true
GraphQLEndpoint string `env:"API_DOCS_GRAPHQL_ENDPOINT"` // default: /v1/graphql
}
ApiDocsConfig holds the api_docs section from nself.yaml. Controls generation of the OpenAPI 3.1 spec and Scalar interactive docs page.
type AuthConfig ¶
type AuthConfig struct {
Version string `env:"AUTH_VERSION"` // 0.36.0
Port int `env:"AUTH_PORT"` // 4000
ClientURL string `env:"AUTH_CLIENT_URL"`
AccessTokenExpiry int `env:"AUTH_ACCESS_TOKEN_EXPIRES_IN"` // seconds
RefreshTokenExpiry int `env:"AUTH_REFRESH_TOKEN_EXPIRES_IN"` // seconds
Route string `env:"AUTH_ROUTE"`
SMTPHost string `env:"AUTH_SMTP_HOST"`
SMTPPort int `env:"AUTH_SMTP_PORT"`
SMTPUser string `env:"AUTH_SMTP_USER"`
SMTPPass string `env:"AUTH_SMTP_PASS"`
SMTPSecure bool `env:"AUTH_SMTP_SECURE"`
SMTPSender string `env:"AUTH_SMTP_SENDER"`
MemLimit string `env:"AUTH_MEM_LIMIT"` // 256m
CPULimit string `env:"AUTH_CPU_LIMIT"` // 0.25
ExtraRedirectURLs string `env:"AUTH_EXTRA_REDIRECT_URLS"` // comma-separated extra redirect URLs
WebAuthnEnabled bool `env:"AUTH_WEBAUTHN_ENABLED"`
MFATOTPEnabled bool `env:"AUTH_MFA_TOTP_ENABLED"` // false
LogLevel string `env:"AUTH_LOG_LEVEL"` // info
}
AuthConfig holds authentication service configuration.
type BackupConfig ¶
type BackupConfig struct {
Dir string `env:"BACKUP_DIR"` // ./backups — read by database/backup.go and restore.go
Enabled bool `env:"BACKUP_ENABLED"`
Schedule string `env:"BACKUP_SCHEDULE"` // legacy alias for BACKUP_SCHEDULE_FULL
RetentionDays int `env:"BACKUP_RETENTION_DAYS"` // legacy — use Daily/Weekly/Monthly instead
CloudProvider string `env:"BACKUP_CLOUD_PROVIDER"` // legacy — use Remote instead
// Cloud/remote storage
Remote string `env:"BACKUP_REMOTE"` // rclone remote path, e.g. s3://bucket/path
Encryption bool `env:"BACKUP_ENCRYPTION"` // enable age encryption
AgeRecipients string `env:"BACKUP_AGE_RECIPIENTS"` // age public key for encryption
ScheduleFull string `env:"BACKUP_SCHEDULE_FULL"` // cron expr for full backups (default: 0 3 * * *)
WALInterval int `env:"BACKUP_WAL_INTERVAL_SECONDS"` // WAL archive interval (default: 60)
RetentionDaily int `env:"BACKUP_RETENTION_DAILY"` // keep last N daily backups (default: 7)
RetentionWeekly int `env:"BACKUP_RETENTION_WEEKLY"` // keep last N weekly backups (default: 4)
RetentionMonthly int `env:"BACKUP_RETENTION_MONTHLY"` // keep last N monthly backups (default: 12)
RestoreTestSchedule string `env:"BACKUP_RESTORE_TEST_SCHEDULE"` // cron for restore tests (default: 0 5 * * 0)
AlertOnFailure bool `env:"BACKUP_ALERT_ON_FAILURE"` // send alert on backup failure
S3AccessKeyID string `env:"BACKUP_S3_ACCESS_KEY_ID"`
S3SecretAccessKey string `env:"BACKUP_S3_SECRET_ACCESS_KEY"`
S3Region string `env:"BACKUP_S3_REGION"`
S3Endpoint string `env:"BACKUP_S3_ENDPOINT"`
// CriticalTables overrides database.DefaultCriticalTables for the backup
// drill's smoke check (comma-separated table names, e.g.
// "users,licenses,audit_logs,plugins"). Empty (the default) keeps the
// np_-prefixed convention. Deployed schemas vary in whether they use
// nSelf's np_ multi-app-isolation prefix, so the drill's critical-table
// presence check must be project-configurable rather than hardcoded to
// one convention — see .claude/qa/bugs/drill-critical-tables-naming.md.
CriticalTables string `env:"BACKUP_CRITICAL_TABLES"`
}
BackupConfig holds backup and recovery configuration. Dir is read by internal/database/backup.go and restore.go for ad-hoc pg_dump/pg_restore. Scheduled, cloud, and retention features are managed via BACKUP_* env vars.
type CascadeFile ¶ added in v1.3.0
type CascadeFile struct {
// Name is the filename relative to the project directory, e.g. ".env.secrets".
Name string
// Path is Name joined with the project directory.
Path string
// Exists reports whether the file is present on disk.
Exists bool
}
CascadeFile describes one file consulted by the env cascade, in load order.
func EnvCascade ¶ added in v1.3.0
func EnvCascade(projectDir, envName string, legacy bool) []CascadeFile
EnvCascade resolves EnvCascadeOrder to on-disk paths under projectDir, with existence checked. Used by `nself env explain` and the migration shim; both need to know not just the order but which files are actually present.
type Config ¶
type Config struct {
// Core
ProjectName string `env:"PROJECT_NAME"`
BaseDomain string `env:"BASE_DOMAIN"`
Env string `env:"ENV"` // dev, staging, prod
ProjectDescription string `env:"PROJECT_DESCRIPTION"`
AdminEmail string `env:"ADMIN_EMAIL"`
DBEnvSeeds bool `env:"DB_ENV_SEEDS"`
// AppName is an OPTIONAL app-prefix used to namespace generated core
// nginx subdomains (gap #5): when set, routes render as
// "api.{AppName}.{BASE_DOMAIN}" / "auth.{AppName}.{BASE_DOMAIN}" instead
// of the bare "api.{BASE_DOMAIN}" / "auth.{BASE_DOMAIN}" scheme. Deliberately
// distinct from PROJECT_NAME (which is always set, for container/network
// naming) so existing single-app deployments (ummat, unity) that only set
// PROJECT_NAME are unaffected — AppName defaults to "" (bare scheme).
AppName string `env:"APP_NAME"`
// PostgreSQL
Postgres PostgresConfig
// Hasura
Hasura HasuraConfig
// Auth
Auth AuthConfig
// Nginx
Nginx NginxConfig
// SSL
SSLMode string `env:"SSL_MODE"` // local, letsencrypt, custom, none
SSLProvider string `env:"SSL_PROVIDER"` // cloudflare, route53, digitalocean, custom
SSLWildcardDomain string `env:"SSL_WILDCARD_DOMAIN"` // *.example.com
ExtraSSLDomains string `env:"EXTRA_SSL_DOMAINS"` // comma-separated
CloudflareAPIKey string `env:"CLOUDFLARE_API_KEY"` // DNS-01 challenge
// WAF
WAFMode string `env:"WAF_MODE"` // off, detection, blocking
// Optional Services
Redis RedisConfig
Minio MinioConfig
Mailpit MailpitConfig
Functions FunctionsConfig
MLflow MLflowConfig
Admin AdminConfig
Monitoring MonitoringConfig
// Search (provider-agnostic)
Search SearchConfig
// Email Provider
Email EmailConfig
// PgBouncer connection pooler
PgBouncer PgBouncerConfig
// Backup & Recovery
Backup BackupConfig
// Disaster Recovery
DR DRConfig
// Multi-Tenancy & Billing
Tenant TenantConfig
// License
License LicenseConfig
// Secrets Management
Secrets SecretsConfig
// Plugin Pro Configuration
PluginConfig PluginProConfig
// Plugin System
PluginSystem PluginSystemConfig
// API Docs (Scalar)
ApiDocs ApiDocsConfig
// Custom Services
CustomServices []CustomService // CS_1..CS_10
// Frontend Apps
FrontendApps []FrontendApp // FRONTEND_APP_1..FRONTEND_APP_20
// Remote Schemas
RemoteSchemas []RemoteSchema
// Internal Routes (up to 20)
InternalRoutes []InternalRoute
// Docker
DockerNetwork string `env:"DOCKER_NETWORK"`
DockerLogMaxSize string `env:"DOCKER_LOG_MAX_SIZE"` // 10m
DockerLogMaxFile string `env:"DOCKER_LOG_MAX_FILE"` // 3
DockerStopGrace string `env:"DOCKER_STOP_GRACE_PERIOD"` // 30s
DockerBuildTimeout int `env:"NSELF_DOCKER_BUILD_TIMEOUT"` // 300
// Start/Stop behavior
StartMode string `env:"NSELF_START_MODE"` // smart, fresh, force
HealthCheckTimeout int `env:"NSELF_HEALTH_CHECK_TIMEOUT"` // seconds
HealthCheckInterval int `env:"NSELF_HEALTH_CHECK_INTERVAL"`
HealthCheckRequired int `env:"NSELF_HEALTH_CHECK_REQUIRED"` // percentage
CleanupOnStart string `env:"NSELF_CLEANUP_ON_START"` // auto/always/never
AllowExposedPorts bool `env:"NSELF_ALLOW_EXPOSED_PORTS"`
ParallelLimit int `env:"NSELF_PARALLEL_LIMIT"` // 5
LogLevel string `env:"NSELF_LOG_LEVEL"` // info
SkipHealthChecks bool `env:"NSELF_SKIP_HEALTH_CHECKS"`
StopTimeout int `env:"NSELF_STOP_TIMEOUT"` // 30
// Federation — GraphQL Federation via Apollo Router (G05).
// When true, nself build injects Apollo Router (CS_7) and composes a
// supergraph schema from installed plugin subgraphs. Default: false.
FederationEnabled bool `env:"NSELF_FEDERATION"`
// EmbeddedPG — when true, nself build omits the Docker postgres service
// and instead relies on the pglite/wasmtime embedded runtime started by
// `nself start --embedded-pg`. Hasura is wired via a Unix-domain socket
// bridge. Default: false.
EmbeddedPG bool `env:"NSELF_EMBEDDED_PG"`
// Passthrough: arbitrary env vars matching patterns (AUTH_PROVIDER_*, REMOTE_SCHEMA_*, etc.)
Passthrough map[string]string
}
Config is the top-level configuration struct for an nSelf project. All fields are populated from the .env cascade and environment variables.
func ApplyDefaults ¶
ApplyDefaults fills every empty/zero field in cfg with the canonical default value. It never overrides a non-empty string, non-zero int, or explicitly-set boolean. Empty string "" is considered unset for string fields; zero is considered unset for int fields.
Environment-specific overrides (Console, DevMode, CORS, BindIP, SSL) are applied after all static defaults.
func Load ¶
Load reads the .env cascade from projectDir, populates a Config struct from os.Getenv, applies smart defaults, and returns the complete configuration.
Cascade order (later overrides earlier), approved 2026-08-23 GATE B (CLI-R18):
.env → .env.{dev|staging|prod} → .env.secrets → .env.local
.env is the shared, committed base; exactly one of .env.dev/.env.staging/ .env.prod loads, matching ENV; .env.secrets never ships in git; .env.local is the personal override and always wins. .env.ai no longer exists as a cascade layer — its content is folded into .env.secrets at init/upgrade (internal/setup/envai.go, internal/migrate/env_order.go).
Setting NSELF_LEGACY_ENV_ORDER=1 restores the pre-CLI-R18 order for exactly one minor version (see EnvCascadeOrder in cascade.go for both orders in full), printing a warning on every use. Run `nself migrate` to move a project off the escape hatch permanently.
Each file is optional. Missing files are silently skipped.
func (*Config) DatabaseURL ¶
DatabaseURL returns the computed PostgreSQL connection string using internal container networking (always port 5432, host "postgres"). The password is percent-encoded per RFC 3986 for safe URL inclusion.
func (*Config) EmbeddedPGDatabaseURL ¶ added in v1.1.3
EmbeddedPGDatabaseURL returns a PostgreSQL DSN that connects via the Unix-domain socket bridge created by the pglite/wasmtime embedded runtime. The host field is the runtimeDir path; sslmode=disable is required because the embedded runtime does not perform TLS termination.
Use this DSN only when cfg.EmbeddedPG is true and runtimeDir is the directory passed to embedded.NewEmbeddedPGRuntime.
func (*Config) IsProduction ¶
IsProduction reports whether the project environment is production. Both "prod" and "production" are treated as production; the loader normalises "production" → "prod" via normalizeEnv, so only "prod" is checked here.
type CustomService ¶
type CustomService struct {
Index int // 1-10
Name string // parsed from CS_N
Template string // express-ts, fastapi, etc.
Port int
Route string // empty = internal only
Public bool
Memory string
CPU string
TablePrefix string // CS_N_TABLE_PREFIX
ExtraEnv string // CS_N_ENV (raw key=val pairs, comma-separated)
BuildPath string // CS_N_PATH: overrides default ./services/{name} build context
// HealthCheck is CS_N_HEALTHCHECK: a path (e.g. "/auth/health"), a full
// "CMD ..." / "CMD-SHELL ..." override, or "disabled"/"none"/"false" to
// omit the healthcheck entirely. Empty keeps the default GET /health.
HealthCheck string
// EnvPassthrough is CS_N_ENV_PASSTHROUGH: a comma-separated allowlist of
// project .env var names to forward into this container in addition to
// the fixed core set from coreEnvVars. CS_N_ENV still wins on conflict.
EnvPassthrough string
// Image is CS_N_IMAGE: a pre-built image reference (optionally digest-pinned,
// e.g. "minio/minio:RELEASE.2024-01-16T16-07-38Z@sha256:...") to run instead
// of building from a Dockerfile. When set, the compose generator emits
// `image:` and omits `build:` entirely — mutually exclusive with
// CS_N_PATH (G-013: closes the gap where a pinned third-party image had
// no CS_N representation and had to be hand-authored into
// docker-compose.override.yml).
Image string
// EnvFile is CS_N_ENV_FILE: a project-relative path to a dotenv-format
// file whose KEY=VALUE lines are injected into this container. Unlike
// CS_N_ENV (a single comma-joined line), a file has no comma/newline
// escaping problem, so it is the right vehicle for many vars or values
// that themselves contain commas (e.g. SMTP credentials). Precedence:
// applied after CS_N_ENV_PASSTHROUGH, before CS_N_ENV (CS_N_ENV always
// wins on conflict, per the existing coreEnvVars contract). Same
// relative-path rules as BuildPath (no absolute paths, no "..").
EnvFile string
// Volumes is CS_N_VOLUMES: a comma-separated list of extra Docker volume
// mounts in "host:container[:mode]" form (e.g.
// "./email-templates:/app/templates:ro"), appended to the service's
// generated volume list. Closes the gap where a required bind mount
// (e.g. a template directory) had no CS_N representation.
Volumes string
}
CustomService represents a user-defined custom service (CS_1..CS_10).
type DRConfig ¶ added in v1.0.6
type DRConfig struct {
SecondaryRegion string `env:"DR_SECONDARY_REGION"` // Hetzner region for standby
StandbyHost string `env:"DR_STANDBY_HOST"` // IP/hostname of warm standby
DrillSchedule string `env:"DR_DRILL_SCHEDULE"` // cron for DR drills (default: off)
}
DRConfig holds disaster recovery configuration.
type ElasticsearchConfig ¶
type ElasticsearchConfig struct {
Version string `env:"ELASTICSEARCH_VERSION"` // 8.11.3
Port int `env:"ELASTICSEARCH_PORT"` // 9200
Password string `env:"ELASTICSEARCH_PASSWORD"`
Memory string `env:"ELASTICSEARCH_MEMORY"` // 1Gi
}
ElasticsearchConfig holds Elasticsearch-specific configuration.
type EmailConfig ¶
type EmailConfig struct {
Provider string `env:"EMAIL_PROVIDER"` // mailpit/elasticemail/sendgrid/postmark/mailgun/ses/smtp
From string `env:"EMAIL_FROM"`
ElasticEmailAPIKey string `env:"ELASTIC_EMAIL_API_KEY"`
ElasticEmailAccount string `env:"ELASTIC_EMAIL_ACCOUNT_EMAIL"`
SendGridAPIKey string `env:"SENDGRID_API_KEY"`
PostmarkAPIKey string `env:"POSTMARK_API_KEY"`
MailgunAPIKey string `env:"MAILGUN_API_KEY"`
MailgunDomain string `env:"MAILGUN_DOMAIN"`
AWSAccessKeyID string `env:"AWS_ACCESS_KEY_ID"`
AWSSecretAccessKey string `env:"AWS_SECRET_ACCESS_KEY"`
AWSRegion string `env:"AWS_REGION"`
SMTPHost string `env:"SMTP_HOST"`
SMTPPort int `env:"SMTP_PORT"`
SMTPUser string `env:"SMTP_USER"`
SMTPPass string `env:"SMTP_PASS"`
SMTPSecure bool `env:"SMTP_SECURE"`
}
EmailConfig holds email provider configuration.
type FrontendApp ¶
type FrontendApp struct {
Index int
DisplayName string
SystemName string
Port int
Route string
Framework string
TablePrefix string
Image string // FRONTEND_APP_N_IMAGE (optional docker image reference)
}
FrontendApp represents a frontend application (FRONTEND_APP_1..FRONTEND_APP_20).
type FunctionsConfig ¶
type FunctionsConfig struct {
Enabled bool `env:"FUNCTIONS_ENABLED"`
Version string `env:"FUNCTIONS_VERSION"` // latest
Port int `env:"FUNCTIONS_PORT"` // 3008
Route string `env:"FUNCTIONS_ROUTE"` // functions.{BD}
// Runtime selects the container image: node (default), deno, python.
Runtime string `env:"FUNCTIONS_RUNTIME"` // node|deno|python
// Resource limits for the functions container.
Memory string `env:"FUNCTIONS_MEMORY"` // 256M
CPU string `env:"FUNCTIONS_CPU"` // 0.5
Timeout string `env:"FUNCTIONS_TIMEOUT"` // 30s
}
FunctionsConfig holds serverless functions runtime configuration.
type HasuraConfig ¶
type HasuraConfig struct {
Version string `env:"HASURA_VERSION"`
AdminSecret string `env:"HASURA_GRAPHQL_ADMIN_SECRET"`
JWTKey string `env:"HASURA_JWT_KEY"`
JWTType string `env:"HASURA_JWT_TYPE"` // HS256
Console bool `env:"HASURA_GRAPHQL_ENABLE_CONSOLE"`
DevMode bool `env:"HASURA_GRAPHQL_DEV_MODE"`
CORSDomain string `env:"HASURA_GRAPHQL_CORS_DOMAIN"`
Route string `env:"HASURA_ROUTE"` // api.{BASE_DOMAIN}
Port int `env:"HASURA_PORT"` // 8080
MemLimit string `env:"HASURA_MEM_LIMIT"`
CPULimit string `env:"HASURA_CPU_LIMIT"`
LogLevel string `env:"HASURA_GRAPHQL_LOG_LEVEL"` // warn
}
HasuraConfig holds Hasura GraphQL engine configuration.
type InternalRoute ¶
type InternalRoute struct {
Index int
Name string // INTERNAL_ROUTE_N_NAME
Subdomain string // INTERNAL_ROUTE_N_SUBDOMAIN
Target string // INTERNAL_ROUTE_N_TARGET (e.g., hasura:8080)
RateZone string // INTERNAL_ROUTE_N_RATE_ZONE (default: general)
WebSocket bool // INTERNAL_ROUTE_N_WEBSOCKET
}
InternalRoute represents an internal Nginx route (INTERNAL_ROUTE_1..INTERNAL_ROUTE_20).
type LicenseConfig ¶ added in v1.0.6
type LicenseConfig struct {
PingURL string `env:"LICENSE_PING_URL"` // https://ping.nself.org
CachePath string `env:"LICENSE_CACHE_PATH"` // ~/.cache/nself/license.json
CheckInterval string `env:"LICENSE_CHECK_INTERVAL"` // 6h
OfflineMode bool `env:"LICENSE_OFFLINE_MODE"` // false
PublicKeyOverride string `env:"LICENSE_PUBLIC_KEY_OVERRIDE"` // hex-encoded Ed25519 pubkey for testing
SunsetAt time.Time `env:"LICENSE_SUNSET_AT"` // optional hard cutoff; zero = no sunset
}
LicenseConfig holds license validation and grace period configuration.
Offline grace-period lengths are NOT configurable here: they are fixed constants in internal/license/grace.go (GraceSoftThreshold, GraceHardThreshold), by design — see checker.go's exposure rationale (grace.go's GraceHardThreshold comment). A prior GraceDays field (env:"LICENSE_GRACE_DAYS") was declared here and referenced in a grace.go comment claiming the ladder was configurable, but nothing in the codebase ever read it. Both were removed together, P6-E12-W4-S4-T2, 2026-09.
type MLflowConfig ¶
type MLflowConfig struct {
Enabled bool `env:"MLFLOW_ENABLED"`
Route string `env:"MLFLOW_ROUTE"` // mlflow.{BD} — read by ssl/domains.go, urls.go, doctor.go
Version string `env:"MLFLOW_VERSION"` // plugin-managed: populated by nself plugin install mlflow
Port int `env:"MLFLOW_PORT"` // read by doctor.go for port-conflict checks; plugin-managed: populated by nself plugin install mlflow
DBName string `env:"MLFLOW_DB_NAME"` // plugin-managed: populated by nself plugin install mlflow
ArtifactsBucket string `env:"MLFLOW_ARTIFACTS_BUCKET"` // plugin-managed: populated by nself plugin install mlflow
AuthEnabled bool `env:"MLFLOW_AUTH_ENABLED"` // plugin-managed: populated by nself plugin install mlflow
AuthUsername string `env:"MLFLOW_AUTH_USERNAME"` // plugin-managed: populated by nself plugin install mlflow
AuthPassword string `env:"MLFLOW_AUTH_PASSWORD"` // plugin-managed: populated by nself plugin install mlflow
}
MLflowConfig holds MLflow experiment tracking configuration. Compose generation is plugin-managed: nself plugin install mlflow Enabled, Route, and Port are read by ssl/domains.go, urls.go, and doctor.go. All other fields are consumed exclusively by the nself-mlflow plugin at install time.
type MailpitConfig ¶
type MailpitConfig struct {
Enabled bool `env:"MAILPIT_ENABLED"`
Version string `env:"MAILPIT_VERSION"` // latest
SMTPPort int `env:"MAILPIT_SMTP_PORT"` // 1025
UIPort int `env:"MAILPIT_UI_PORT"` // 8025
MaxMessages int `env:"MAILPIT_MAX_MESSAGES"` // 500
Route string `env:"MAILPIT_ROUTE"` // mail.{BD}
UIUser string `env:"MAILPIT_UI_USER"` // admin (default)
UIPassword string `env:"MAILPIT_UI_PASSWORD"`
}
MailpitConfig holds Mailpit local email testing configuration.
type MeiliSearchConfig ¶
type MeiliSearchConfig struct {
Version string `env:"MEILISEARCH_VERSION"` // v1.6
MasterKey string `env:"MEILISEARCH_MASTER_KEY"`
Env string `env:"MEILISEARCH_ENV"` // development
}
MeiliSearchConfig holds MeiliSearch-specific configuration.
type MinioConfig ¶
type MinioConfig struct {
Enabled bool `env:"MINIO_ENABLED"`
Version string `env:"MINIO_VERSION"` // latest
Port int `env:"MINIO_PORT"` // 9000
ConsolePort int `env:"MINIO_CONSOLE_PORT"` // 9001
RootUser string `env:"MINIO_ROOT_USER"` // minioadmin
RootPassword string `env:"MINIO_ROOT_PASSWORD"` // minioadmin
DefaultBuckets string `env:"MINIO_DEFAULT_BUCKETS"` // uploads,public,private,temp
Region string `env:"MINIO_REGION"` // us-east-1
S3AccessKey string `env:"S3_ACCESS_KEY"`
S3SecretKey string `env:"S3_SECRET_KEY"`
S3Bucket string `env:"S3_BUCKET"` // nself
StorageVersion string `env:"STORAGE_VERSION"` // 0.6.1
StorageRoute string `env:"STORAGE_ROUTE"` // storage.{BD}
ConsoleRoute string `env:"STORAGE_CONSOLE_ROUTE"` // storage-console.{BD}
MemLimit string `env:"MINIO_MEMORY"` // 1G
CPULimit string `env:"MINIO_CPU"` // 0.5
}
MinioConfig holds MinIO S3-compatible object storage configuration.
type MonitoringConfig ¶
type MonitoringConfig struct {
Enabled bool `env:"MONITORING_ENABLED"`
GrafanaEnabled bool `env:"GRAFANA_ENABLED"`
GrafanaRoute string `env:"GRAFANA_ROUTE"` // read by ssl/domains.go, urls.go, doctor.go
GrafanaAdminPassword string `env:"GRAFANA_ADMIN_PASSWORD"` // read by config/validator.go
PrometheusEnabled bool `env:"PROMETHEUS_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
PrometheusPort int `env:"PROMETHEUS_PORT"` // plugin-managed: populated by nself plugin install monitoring
GrafanaPort int `env:"GRAFANA_PORT"` // read by urls.go and doctor.go for port display; plugin-managed: populated by nself plugin install monitoring
GrafanaAdminUser string `env:"GRAFANA_ADMIN_USER"` // plugin-managed: populated by nself plugin install monitoring
LokiEnabled bool `env:"LOKI_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
LokiPort int `env:"LOKI_PORT"` // plugin-managed: populated by nself plugin install monitoring
PromtailEnabled bool `env:"PROMTAIL_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
TempoEnabled bool `env:"TEMPO_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
TempoPort int `env:"TEMPO_PORT"` // plugin-managed: populated by nself plugin install monitoring
AlertmanagerEnabled bool `env:"ALERTMANAGER_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
AlertmanagerPort int `env:"ALERTMANAGER_PORT"` // plugin-managed: populated by nself plugin install monitoring
CadvisorEnabled bool `env:"CADVISOR_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
CadvisorPort int `env:"CADVISOR_PORT"` // plugin-managed: populated by nself plugin install monitoring
NodeExporterEnabled bool `env:"NODE_EXPORTER_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
NodeExporterPort int `env:"NODE_EXPORTER_PORT"` // plugin-managed: populated by nself plugin install monitoring
PGExporterEnabled bool `env:"POSTGRES_EXPORTER_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
PGExporterPort int `env:"POSTGRES_EXPORTER_PORT"` // plugin-managed: populated by nself plugin install monitoring
RedisExporterEnabled bool `env:"REDIS_EXPORTER_ENABLED"` // plugin-managed: populated by nself plugin install monitoring
RedisExporterPort int `env:"REDIS_EXPORTER_PORT"` // plugin-managed: populated by nself plugin install monitoring
// S34 additions
PrometheusRetention string `env:"PROMETHEUS_RETENTION"` // e.g. "30d"
LokiHotDays int `env:"LOKI_HOT_DAYS"` // default 30
LokiColdDays int `env:"LOKI_COLD_DAYS"` // default 365
AlertmanagerPagerdutyKey string `env:"ALERTMANAGER_PAGERDUTY_KEY"` // PagerDuty integration key
// Watchdog
WatchdogEnabled bool `env:"WATCHDOG_ENABLED"`
WatchdogCircuitBreakerAttempts int `env:"WATCHDOG_CIRCUIT_BREAKER_ATTEMPTS"` // default 3
WatchdogCircuitBreakerWindow string `env:"WATCHDOG_CIRCUIT_BREAKER_WINDOW"` // default 10m
WatchdogEscalationWebhook string `env:"WATCHDOG_ESCALATION_WEBHOOK"`
// Queue/Jobs
QueueWorkersPerQueue int `env:"QUEUE_WORKERS_PER_QUEUE"` // default 2
QueueDLQAlertThreshold int `env:"QUEUE_DLQ_ALERT_THRESHOLD"` // default 100
// Promotion
PromoteRequiresTwoApprovers bool `env:"PROMOTE_REQUIRES_TWO_APPROVERS"`
}
MonitoringConfig holds monitoring stack configuration. Compose generation is plugin-managed: nself plugin install monitoring Enabled, GrafanaEnabled, GrafanaRoute, GrafanaAdminPassword, and GrafanaPort are read by ssl/domains.go (SSL SANs), config/validator.go (password check), urls.go, and doctor.go. All other fields are consumed exclusively by the nself-monitoring plugin at install time.
type NginxConfig ¶
type NginxConfig struct {
Version string `env:"NGINX_VERSION"` // alpine
HTTPPort int `env:"NGINX_HTTP_PORT"` // 80
SSLPort int `env:"NGINX_HTTPS_PORT"` // 443
MaxBody string `env:"NGINX_CLIENT_MAX_BODY_SIZE"` // 100M
BindIP string `env:"NGINX_BIND_IP"` // computed: 127.0.0.1 (dev) or 0.0.0.0 (prod) — overridable
AuthRateLimit string `env:"AUTH_RATE_LIMIT"` // 30r/m
RateLimitAPI string `env:"RATE_LIMIT_API_RPS"` // 30
RateLimitAuth string `env:"RATE_LIMIT_AUTH_RPS"` // 5
RateLimitAI string `env:"RATE_LIMIT_AI_RPS"` // 10
// FrontedBy names the stack whose nginx fronts this project's domains
// (e.g. "nself-web"), when this project has no ingress nginx of its own.
// Empty (the default) means this stack runs its own nginx, unchanged
// from every prior release.
//
// When set, `nself build` omits the nginx service from
// docker-compose.yml entirely and excludes it from the service counts
// `nself status`/`nself start` expect. Without this, a stack meant to
// sit behind another stack's nginx still generates and tries to start
// its own nginx container, which fails to bind 80/443 (already held by
// the fronting stack's nginx via docker-proxy) and then sits forever as
// one unhealthy service nself status can never clear ("6/7" on ntask's
// staging deploy, 2026-09-03, fronted by nself-web).
//
// This flag only removes the container that can never run. It does NOT
// wire this project's containers onto the fronting stack's Docker
// network — the fronting nginx's `resolver 127.0.0.11` can only reach
// container names on a network it is attached to, so making
// auth.task.staging.nself.org resolve ntask_auth still requires the
// operator to attach the two projects' networks (or declare one as
// external in both compose files) by hand. That is a bigger, riskier
// change — automatically rewriting a Docker network topology from a
// per-project flag — and belongs in a follow-up once the desired shape
// of that wiring is decided.
FrontedBy string `env:"NGINX_FRONTED_BY"`
}
NginxConfig holds Nginx reverse proxy configuration.
type PgBouncerConfig ¶ added in v1.0.9
type PgBouncerConfig struct {
Enabled bool `env:"PGBOUNCER_ENABLED"`
Port int `env:"PGBOUNCER_PORT"` // 6432
PoolMode string `env:"PGBOUNCER_POOL_MODE"` // session, transaction, statement
MaxClientConn int `env:"PGBOUNCER_MAX_CLIENT_CONN"` // 100
DefaultPoolSize int `env:"PGBOUNCER_DEFAULT_POOL_SIZE"` // 25
MinPoolSize int `env:"PGBOUNCER_MIN_POOL_SIZE"` // 5
ReservePoolSize int `env:"PGBOUNCER_RESERVE_POOL_SIZE"` // 5
ServerIdleTimeout int `env:"PGBOUNCER_SERVER_IDLE_TIMEOUT"` // 600
LogConnections bool `env:"PGBOUNCER_LOG_CONNECTIONS"` // false
LogDisconnections bool `env:"PGBOUNCER_LOG_DISCONNECTIONS"` // false
AdminUsers string `env:"PGBOUNCER_ADMIN_USERS"` // postgres
StatsUsers string `env:"PGBOUNCER_STATS_USERS"` // postgres
}
PgBouncerConfig holds connection pooler configuration.
type PluginProConfig ¶
type PluginProConfig struct {
NotifySecret string `env:"NOTIFY_INTERNAL_SECRET"`
NotifyPort int `env:"NOTIFY_PORT"` // 3712
NotifyVAPIDPub string `env:"NOTIFY_VAPID_PUBLIC_KEY"`
NotifyVAPIDPriv string `env:"NOTIFY_VAPID_PRIVATE_KEY"`
NotifyRoute string `env:"NOTIFY_ROUTE"`
CronSecret string `env:"CRON_INTERNAL_SECRET"`
CronPort int `env:"CRON_PORT"` // 3713
CronRetention int `env:"CRON_RETENTION_DAYS"` // 90
AIMemLimit string `env:"PLUGIN_AI_MEMORY_LIMIT"` // 1g
AICPULimit string `env:"PLUGIN_AI_CPU_LIMIT"` // 1.0
MuxMemLimit string `env:"PLUGIN_MUX_MEMORY_LIMIT"` // 512m
MuxCPULimit string `env:"PLUGIN_MUX_CPU_LIMIT"` // 0.5
ClawMemLimit string `env:"PLUGIN_CLAW_MEMORY_LIMIT"` // 512m
ClawCPULimit string `env:"PLUGIN_CLAW_CPU_LIMIT"` // 0.5
DefaultMemLimit string `env:"PLUGIN_DEFAULT_MEMORY_LIMIT"` // 512m
DefaultCPULimit string `env:"PLUGIN_DEFAULT_CPU_LIMIT"` // 0.5
}
PluginProConfig holds per-plugin configuration for Pro plugins.
type PluginSystemConfig ¶
type PluginSystemConfig struct {
Dir string `env:"NSELF_PLUGIN_DIR"` // ~/.nself/plugins
Cache string `env:"NSELF_PLUGIN_CACHE"` // ~/.nself/cache/plugins
Registry string `env:"NSELF_PLUGIN_REGISTRY"` // https://plugins.nself.org
CacheTTL int `env:"NSELF_REGISTRY_CACHE_TTL"` // 300
LicenseKey string `env:"NSELF_PLUGIN_LICENSE_KEY"`
SkipVerify bool `env:"NSELF_LICENSE_SKIP_VERIFY"`
PingURL string `env:"NSELF_PING_API_URL"` // https://ping.nself.org
PricingURL string `env:"NSELF_PRICING_URL"` // https://nself.org/pricing
InternalSecret string `env:"PLUGIN_INTERNAL_SECRET"`
}
PluginSystemConfig holds plugin system management configuration.
type PostgresConfig ¶
type PostgresConfig struct {
Version string `env:"POSTGRES_VERSION"` // 16-alpine
// Image, when set, is the exact postgres image nself build emits and wins
// over every other resolution (see compose.ResolvePostgresImage). Set this
// to pin a running image (e.g. pgvector/pgvector:pg16) across regens
// without relying on POSTGRES_EXTENSIONS inference (cli#384).
Image string `env:"POSTGRES_IMAGE"`
Host string `env:"POSTGRES_HOST"` // postgres (container name)
Port int `env:"POSTGRES_PORT"` // 5432
DB string `env:"POSTGRES_DB"` // nself
User string `env:"POSTGRES_USER"` // postgres
Password string `env:"POSTGRES_PASSWORD"`
Extensions []string `env:"POSTGRES_EXTENSIONS"` // comma-separated list
ExposePort string `env:"POSTGRES_EXPOSE_PORT"` // auto, true, false
MemLimit string `env:"POSTGRES_MEM_LIMIT"` // 2g
CPULimit string `env:"POSTGRES_CPU_LIMIT"` // 2.0
// MaxConnections overrides Postgres max_connections. The stock default of
// 100 exhausts under a multi-service stack (PERF-POOL-01); nself raises it.
MaxConnections int `env:"POSTGRES_MAX_CONNECTIONS"` // default 200
}
PostgresConfig holds PostgreSQL database configuration.
type RedisConfig ¶
type RedisConfig struct {
Enabled bool `env:"REDIS_ENABLED"`
Version string `env:"REDIS_VERSION"` // 7-alpine
Port int `env:"REDIS_PORT"` // 6379
Password string `env:"REDIS_PASSWORD"` // empty = no auth
Memory string `env:"REDIS_MEMORY"` // 512M
CPU string `env:"REDIS_CPU"` // 0.5
PoolSize int `env:"REDIS_POOL_SIZE"` // 50 (prod default); use 20 for dev
}
RedisConfig holds Redis cache/queue configuration.
type RemoteSchema ¶
RemoteSchema represents a Hasura Remote Schema configuration.
type SearchConfig ¶
type SearchConfig struct {
Enabled bool `env:"SEARCH_ENABLED"`
Engine string `env:"SEARCH_ENGINE"` // meilisearch, typesense, etc.
Port int `env:"SEARCH_PORT"` // auto from provider
APIKey string `env:"SEARCH_API_KEY"` // auto-generated if unset
Route string `env:"SEARCH_ROUTE"` // search.{BD}
IndexPrefix string `env:"SEARCH_INDEX_PREFIX"`
AutoIndex bool `env:"SEARCH_AUTO_INDEX"` // true
Language string `env:"SEARCH_LANGUAGE"` // en
// Provider-specific (only populated for active provider)
MeiliSearch MeiliSearchConfig
Typesense TypesenseConfig
Elasticsearch ElasticsearchConfig
}
SearchConfig holds search engine configuration (provider-agnostic).
type SecretsConfig ¶ added in v1.0.6
type SecretsConfig struct {
AgeKeyPath string `env:"SECRETS_AGE_KEY_PATH"` // ~/.config/nself/age-key.txt
DeployAgeKey string `env:"DEPLOY_AGE_KEY"` // raw age private key for CI/CD
}
SecretsConfig holds secrets management configuration.
type TelemetryPreference ¶ added in v1.0.11
type TelemetryPreference struct {
// Enabled is the stored preference from config.toml.
// This value is overridden to false when NSELF_TELEMETRY_OPT_OUT=1 is set.
Enabled bool
// Source describes where the value came from: "env", "config", or "default".
Source string
}
TelemetryPreference describes the user's telemetry opt-in/out state.
func GetTelemetryPreference ¶ added in v1.0.11
func GetTelemetryPreference() TelemetryPreference
GetTelemetryPreference returns the effective telemetry preference. NSELF_TELEMETRY_OPT_OUT=1 beats the config file, which beats the default.
type TenantConfig ¶ added in v1.0.6
type TenantConfig struct {
DefaultPlan string `env:"TENANT_DEFAULT_PLAN"` // basic
DestroyBackupRetainDays int `env:"TENANT_DESTROY_BACKUP_RETAIN_DAYS"` // 90
StripeSecretKey string `env:"STRIPE_SECRET_KEY"`
StripeWebhookSecret string `env:"STRIPE_WEBHOOK_SECRET"`
StripeAPIVersion string `env:"STRIPE_API_VERSION"` // 2024-04-10
}
TenantConfig holds multi-tenancy and billing configuration.
type TypesenseConfig ¶
type TypesenseConfig struct {
Version string `env:"TYPESENSE_VERSION"` // 27.1
APIKey string `env:"TYPESENSE_API_KEY"`
EnableCORS bool `env:"TYPESENSE_ENABLE_CORS"`
LogLevel string `env:"TYPESENSE_LOG_LEVEL"`
NumMemoryShards int `env:"TYPESENSE_NUM_MEMORY_SHARDS"`
SnapshotIntervalS int `env:"TYPESENSE_SNAPSHOT_INTERVAL_SECONDS"`
}
TypesenseConfig holds Typesense-specific configuration.
type ValidatorFunc ¶
ValidatorFunc pairs a human-readable name with a validation function. The name is used in error messages and test assertions.
type ValidatorResult ¶
ValidatorResult pairs a validator name with its outcome.
func RunAllWithResults ¶
func RunAllWithResults(cfg *Config) []ValidatorResult
RunAllWithResults executes every registered validator and returns one ValidatorResult per validator, preserving the original name and error. Unlike RunAll, no error is returned — the caller inspects results directly.
Source Files
¶
- cascade.go
- custom_services.go
- custom_services_validate.go
- defaults.go
- defaults_auth_nginx.go
- defaults_helpers.go
- defaults_ops.go
- defaults_plugins_backup.go
- defaults_postgres_hasura.go
- defaults_storage_services.go
- exports.go
- frontend_apps.go
- helpers.go
- helpers_unknown_vars.go
- interfaces.go
- loader.go
- loader_helpers.go
- loader_known_vars.go
- loader_known_vars_core.go
- loader_known_vars_ops.go
- loader_known_vars_search.go
- loader_known_vars_storage.go
- loader_parse_env.go
- loader_parse_env_core.go
- loader_parse_env_ops.go
- loader_parse_env_storage.go
- monorepo.go
- registry.go
- remote_schemas.go
- runtime.go
- sanitize.go
- telemetry.go
- types.go
- types_datastores.go
- types_ops_plugins.go
- types_services.go
- validator.go
- validator_placeholder_secrets.go
- validator_ports_services.go