@@ -78,31 +78,58 @@ Create a `.stackctl` file (generated via `stackctl init`):
7878project : myproject
7979
8080stack :
81- # Root directory for service compose files (each must declare x-stack metadata)
81+ # Directory used by doctor and sync to locate generated stack files
82+ # (generate defaults to <repoRoot>/stacks instead)
8283 directory : ./stack
83- # Stack names to manage (empty = all discovered)
84- names : []
84+ # Stack names to manage (must contain at least one name)
85+ names :
86+ - app
8587 # Default Docker network
8688 network : myproject_default
87- # Override files (profile or explicit)
88- overrides : []
89+ # Reserved for future use; currently does not affect generated output
90+ networkDriver : overlay
8991
9092render :
9193 # Output directory for rendered YAML
9294 outputDirectory : ./.rendered
93- # Fail on unresolved variables
94- strict : false
95+
96+ secrets :
97+ # One encrypted dotenv filename, or multiple filenames to discover
98+ encryptedFileName : [".env.enc", ".env.production.enc"]
9599` ` `
96100
97101### Converting Environment Variables
98102
99- | Old Environment Variable | New Config Field | Example |
100- | ------------------------ | ------------------------------------------ | ------------------ |
101- | ` COMPOSE_DIR` | `stack.directory` | `./docker-compose` |
102- | `RENDER_DIR` | `render.outputDirectory` | `./.rendered` |
103- | `STACKS_DIR` | No equivalent (generated to `stacks/`) | — |
104- | `STACK_PREFIX` | `project` | `mystack` |
105- | `STACKCTL_PROFILE` | `--profile` flag or `STACKCTL_PROFILE` env | `dev` |
103+ | Old Environment Variable | New Config Field | Example |
104+ | ------------------------ | ------------------------------------------ | --------------------- |
105+ | ` COMPOSE_DIR` | No direct equivalent | Repository-root scan |
106+ | `RENDER_DIR` | `render.outputDirectory` | `./.rendered` |
107+ | `STACKS_DIR` | No equivalent (generated to `stacks/`) | N/A |
108+ | `STACK_PREFIX` | `project` | `mystack` |
109+ | `STACKCTL_PROFILE` | `--profile` flag or `STACKCTL_PROFILE` env | `dev` |
110+
111+ ` stack.directory` is not the source directory for generation. The `generate` command recursively
112+ discovers exact `docker-compose.yml` and `docker-compose.yaml` files from the repository root and
113+ writes generated files to `<repoRoot>/stacks` by default, unless `--output-dir` is provided. The
114+ configured `stack.directory` is used by `doctor` and `sync` when locating generated stack files.
115+
116+ The `secrets.encryptedFileName` field accepts either one encrypted dotenv filename or a list of
117+ filenames. When a list is configured, secrets commands discover all matching files recursively,
118+ subject to the usual skipped directories. When no `.stackctl` config file exists, encrypt, decrypt,
119+ clean, and check fall back to the default `[".env.enc"]` list. `secrets deploy` requires a valid
120+ ` .stackctl` config. When `secrets encrypt` is run without explicit file arguments, it derives
121+ plaintext filenames by stripping `.enc` from each configured encrypted name, walks for those
122+ plaintext files, and encrypts only the ones without an existing encrypted counterpart.
123+
124+ Env status, env audit, and `doctor` encrypted-file checks currently support only `.env.enc` and do
125+ not discover multiple configured encrypted filenames. This is a known limitation planned for a
126+ future release.
127+
128+ Generation validates service network references against the final top-level declarations. A service
129+ referencing an undeclared network produces an error and the stack is not generated or deployed. A
130+ service declaring both `network_mode` and explicit `networks` produces an error because Docker
131+ Compose considers these mutually exclusive. Services using `network_mode` without explicit
132+ ` networks` are allowed and skip network validation.
106133
107134# # Command Parity
108135
@@ -148,11 +175,11 @@ echo "STACKCTL_PROFILE=${STACKCTL_PROFILE:-dev}"
148175# ## Step 2: Run `stackctl init`
149176
150177` ` ` bash
151- # Interactive detection (scans for docker- compose files)
152- stackctl init
178+ # Detect repository layout (scans for compose files)
179+ stackctl init --detect
153180
154181# Or with explicit values
155- stackctl init --project myproject -- preset standard
182+ stackctl init --preset standard
156183` ` `
157184
158185This creates `.stackctl` in your project root. Edit it to match your recorded configuration from
@@ -171,6 +198,9 @@ Fixes any issues reported:
171198- Missing override files
172199- Missing stack directories
173200
201+ The `doctor --fix-volumes` option is exposed but not yet implemented. It reports this status and
202+ does not create missing external volumes.
203+
174204# ## Step 4: Dry-Run a Deployment
175205
176206` ` ` bash
@@ -251,6 +281,11 @@ Override files are applied _after_ profile merging but _before_ render.
251281named stacks during discovery and generation. Every compose file must declare which
252282stack it belongs to.
253283
284+ Discovery recursively scans the repository root only for files named exactly
285+ ` docker-compose.yml` or `docker-compose.yaml`. Files named `compose.yml`, `compose.yaml`, or
286+ other variants such as `docker-compose.dev.yml` are not discovered by generation. Matching files
287+ must also declare `x-stack` metadata.
288+
254289# ## Supported Forms
255290
256291Two forms are supported :
@@ -364,9 +399,10 @@ docker swarm init
364399✗ Stack "myapp" not found in /path/to/project
365400```
366401
367- Check that your compose files declare ` x-stack ` metadata and are located within the
368- configured ` stack.directory ` . See [ Compose Metadata (` x-stack ` )] ( #compose-metadata-x-stack )
369- for supported forms.
402+ Check that your compose files use the exact names ` docker-compose.yml ` or ` docker-compose.yaml ` ,
403+ declare ` x-stack ` metadata, and are located under the repository root. ` stack.directory ` is used by
404+ ` doctor ` and ` sync ` for generated stack files, not as the generation source directory. See
405+ [ Compose Metadata (` x-stack ` )] ( #compose-metadata-x-stack ) for supported forms.
370406
371407``` yaml
372408# docker-compose.yml -- either form works:
@@ -386,18 +422,16 @@ Common issues:
386422
387423- ** Missing ` project ` ** : Set the project name in ` .stackctl `
388424- ** Missing ` stack.network ` ** : Set the Docker network name
389- - ** Empty ` stack.names ` ** : Leave as ` [] ` to discover all stacks, or list specific stack names
425+ - ** Empty ` stack.names ` ** : Provide at least one stack name; an empty list is rejected
390426- ** Invalid ` render.outputDirectory ` ** : Must be a valid path
391427
392428### Unresolved Environment Variables
393429
394- In strict mode (` render.strict: true ` ), unused variables cause failure. Switch to non-strict mode or
395- provide the variables:
430+ In strict mode (` stackctl render --strict ` ), unresolved variables cause failure. Strictness is a
431+ CLI option, not a config field. Run without ` --strict ` for non-strict mode or provide the
432+ variables:
396433
397434``` bash
398- # Non-strict mode
399- echo ' render:\n strict: false' >> .stackctl
400-
401435# Provide variable
402436export MY_VAR=value
403437stackctl up
@@ -452,7 +486,10 @@ This enables drift detection in CI.
452486### Signal Handling
453487
454488- ** Old** : Ctrl-C may leave processes running
455- - ** New** : SIGINT is forwarded to child processes; ` secrets deploy ` runs cleanup on interruption
489+ - ** New** : Commands that stream child process output (e.g. ` up --logs ` , ` logs ` ) forward SIGINT
490+ to the child. Most commands use non-streaming execution and do not forward signals. Secrets
491+ cleanup is not automatic after an interrupted deployment; run ` stackctl secrets clean ` when
492+ needed.
456493
457494## Using stackctl in GitHub Actions
458495
0 commit comments