Compose Generation - nself-org/cli GitHub Wiki
Compose Generation
nself build is the heart of the CLI. It reads your .env files, resolves which services to enable, and generates docker-compose.yml and nginx configs. You should run it whenever your config changes.
The Golden Rule
Never hand-edit
docker-compose.yml. It is regenerated on everynself build. Any manual changes will be lost. If you need to customize a service, use env vars or the.env.localoverride file.
Build Sequence
When you run nself build, the CLI executes the following steps in order:
- Load env cascade, reads
.env.dev→.env.{ENV}→.env.secrets→.env.local→.env, with later files overriding earlier ones - Apply smart defaults, fills in any unset variables with safe, sensible values
- Normalize values, resolves ENV aliases, normalizes boolean flags, sanitizes
PROJECT_NAMEfor Docker compatibility - Run security validation, checks password strength, CORS origins, port bindings, and other security-sensitive settings; aborts with a clear error on any violation
- Detect enabled services, reads all
*_ENABLEDenvironment variables to determine which services should be included - Run change detection, compares file modification times to skip regeneration if nothing has changed (use
--forceto bypass) - Generate SSL certificates, uses mkcert if available, falls back to OpenSSL; skips if valid certs already exist
- Generate nginx configuration, writes all nginx config files based on enabled services and SSL state
- Generate
docker-compose.yml, assembles the full compose file from all enabled service definitions - Apply post-processing, configures log drivers, graceful shutdown timeouts, and security hardening appropriate for the current environment
- Validate the generated compose, runs
docker compose configto verify the output is well-formed - Write
.env.computed, records derived values (resolved ports, computed flags, etc.) for use by downstream tooling
Change Detection and Smart Cache
nself build is smart, it only regenerates files that actually need updating:
- If
.envis newer thandocker-compose.yml→ regenerate compose - If
.envis newer thannginx/nginx.conf→ regenerate nginx - If SSL certs are missing or expired → regenerate SSL
- If the CLI version has changed → rebuild everything from scratch
This makes repeated builds fast. Use --force to bypass the cache and rebuild everything unconditionally.
Multi-File Compose Merge
When plugins are installed, each one provides a docker-compose.plugin.yml overlay file. During nself build, these overlay files are merged into the final docker-compose.yml in a well-defined order:
- Base compose, core required services
- Optional service sections, Redis, MinIO, mailpit, and other optional services if enabled
- Monitoring bundle, Prometheus, Grafana, Loki, and the rest of the monitoring stack (if
MONITORING_ENABLED=true) - Custom services,
CS_1throughCS_10as defined in your env - Plugin overlay files, one per installed plugin, applied in install order
Plugin overlays can add new services, volumes, and networks. They cannot remove or rename services that already exist in the base compose. This ensures the core stack remains stable regardless of which plugins are installed.
Service Generation Order
The compose file is assembled in this order. Services later in the list can depend on services earlier in the list.
- Core,
postgres,hasura,auth,nginx - Optional,
minio(with init container),redis,mailpit,admin,functions,mlflow,search - Monitoring,
prometheus,grafana,loki,promtail,tempo,alertmanager,cadvisor,node-exporter,postgres-exporter,redis-exporter - Custom,
CS_1throughCS_10 - Plugins, loaded from
~/.nself/plugins/, in install order
Security Hardening
In staging and prod environments, nself build automatically applies security hardening to every generated service definition:
cap_drop: ALL, drops all Linux capabilities by defaultsecurity_opt: no-new-privileges: true, prevents privilege escalationcap_add: NET_BIND_SERVICE, re-adds only the capability that services actually need
These are applied automatically based on your ENV setting. You do not need to configure them. In dev, hardening is relaxed to avoid friction during local development.
Common Commands
nself build # Rebuild (only regenerates changed files)
nself build --force # Force full rebuild, bypassing the cache
nself build --check # Validate config without writing any files
nself build --security-report # Show the full security validation report
See also: [Architecture]] ](/nself-org/cli/wiki/[Config-System) | [Nginx-Generation]] | Home