config

package
v1.0.7 Latest Latest
Warning

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

Go to latest
Published: Apr 16, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildJWTSecret

func BuildJWTSecret(cfg *Config) (string, error)

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. In dev mode, a missing JWTKey is auto-generated. In non-dev modes, an empty JWTKey produces an empty string (the caller must validate).

func BuildServiceURL

func BuildServiceURL(subdomain, baseDomain string) string

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

func DefaultFor(key string) string

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

func DetectMonorepoRoot(dir string) string

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 FindNSelfRoot

func FindNSelfRoot(startDir string) (string, error)

FindNSelfRoot walks up from startDir looking for a nself project root. It checks, at each directory level:

  1. startDir/.backend/.env → returns startDir/.backend (monorepo case)
  2. 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 RouteToFQDN

func RouteToFQDN(route, baseDomain string) (string, error)

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 SanitizeDomain

func SanitizeDomain(input string) (string, error)

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

func SanitizeName(input string) (string, error)

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 Validate

func Validate(cfg *Config) error

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

func ValidateHasuraDevMode(cfg *Config) error

ValidateHasuraDevMode returns an error if HASURA_GRAPHQL_DEV_MODE=true in prod.

func ValidateNginxInputs

func ValidateNginxInputs(cfg *Config) error

ValidateNginxInputs validates raw nginx template inputs that are interpolated without escaping. Prevents nginx directive injection via env vars.

func ValidateRedisPassword

func ValidateRedisPassword(cfg *Config) error

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 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"`
	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"`
}

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 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"`

	// 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

	// 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

	// 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

	// 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

func ApplyDefaults(cfg *Config) (*Config, error)

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

func Load(projectDir string) (*Config, error)

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):

.env.dev → .env.{ENV} → .env.secrets → .env.local → .env → .env.ai

.env.ai is loaded last so the AI tier configuration (generated once by `nself init`, contains NSELF_MASTER_SECRET) always takes effect at plugin startup without requiring a separate loader. Spec: p88 §8.4.

Each file is optional. Missing files are silently skipped.

func (*Config) DatabaseURL

func (cfg *Config) DatabaseURL() string

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) IsProduction

func (c *Config) IsProduction() bool

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)
}

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}
}

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
	GraceDays         int    `env:"LICENSE_GRACE_DAYS"`          // 7
	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
}

LicenseConfig holds license validation and grace period configuration.

type Loader

type Loader interface {
	Load(dir string) (*Config, error)
}

Loader abstracts configuration loading for testability.

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
}

NginxConfig holds Nginx reverse proxy 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
	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
}

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
}

RedisConfig holds Redis cache/queue configuration.

type RemoteSchema

type RemoteSchema struct {
	Index   int
	Name    string
	URL     string
	Headers string // key:val,key:val
}

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 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

type ValidatorFunc struct {
	Name string
	Fn   func(*Config) error
}

ValidatorFunc pairs a human-readable name with a validation function. The name is used in error messages and test assertions.

type ValidatorResult

type ValidatorResult struct {
	Name string
	Err  error
}

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.

Jump to

Keyboard shortcuts

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