Skip to content

Add an env_file_path input, and document how values reach the stack file - #26

Merged
ericof merged 2 commits into
mainfrom
issues-2-3-env-file
Sep 4, 2026
Merged

Add an env_file_path input, and document how values reach the stack file#26
ericof merged 2 commits into
mainfrom
issues-2-3-env-file

Conversation

@ericof

@ericof ericof commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Resolves the env_file path-vs-content confusion by adding an input rather than changing what the existing one means, and documents the mechanism both issues were really missing.

Closes #2
Closes #3

#3env_file doesn't work

The input takes the variables as content. But env_file in docker-compose is a path, so people reasonably supply a path — and it fails. Two people hit this independently (#3, and @Jamesking56 in #7), which makes it a design signal rather than user error.

#22 already made the failure legible ('.env' is not in NAME=VALUE format instead of an opaque export: not a valid identifier), but the mistake was still just as easy to make.

Why a new input instead of changing env_file

PR #7 fixed #3 by swapping printf '%s' "$ENV_FILE" for cat "$ENV_FILE". That is the right capability, but as a silent breaking change: every caller currently passing content would start failing, because cat would try to open that content as a filename.

So env_file_path is additive:

env_file:      # unchanged — the variables themselves
env_file_path: # new — a path, read from the workspace
  • env_file keeps its meaning and its verbatim docker --env-file semantics.
  • Supplying both is an error — the precedence between them would otherwise be arbitrary.
  • Relative paths resolve against the workspace, the same way stack_file already does.
  • Nothing is renamed. env_vars would be a better name for the content input, and not worth breaking every existing workflow over.

Parsing is now a shared load_env_file helper, so the two inputs cannot drift apart in how they handle quotes, spaces, or a trailing newline. The internal destination for env_file content is renamed to ENV_FILE_DEST, which frees ENV_FILE_PATH for the input.

Rejected alternative

Auto-detecting — "if the value is one line and names an existing file, read it as a file" — was rejected because it makes the semantics depend on the filesystem, so a typo'd path silently changes behaviour instead of failing.

#2 — document stack_param and env_file

@luchidalgo asked for examples of both. Neither was properly documented, and the answer for one of them is more interesting than the question.

stack_param does nothing on its own. STACK_PARAM is never read by the entrypoint — grep it. It is exported into the container environment, and docker stack deploy substitutes ${STACK_PARAM} when it parses the stack file. The old README example set stack_param: "foo" and never showed anything consuming it, so it demonstrated nothing at all.

And env_file supersedes it entirely. Those variables are exported before deploy runs, so they reach the stack file by exactly the same route — except you get as many as you like, with names you choose. stack_param is a one-variable special case with a name the caller cannot pick.

The new "Passing values into the stack file" section explains the substitution mechanism once, then gives each input a worked example with its matching stack file. stack_param is documented as supported but discouraged rather than deprecated — it costs nothing to keep, and breaking existing callers for tidiness isn't worth it.

Also fixed while in there: the examples pinned kitconcept/docker-stack-deploy@v1.0.1 (which predates the docker 29 base image) and actions/checkout@v2. Both now match what this repository actually uses.

Verification

make lint clean, make test 55 passing / 0 skipped (43 before, 12 new for env_file_path).

Mutation-tested: disabling the env_file_path dispatch fails exactly the two tests that assert the wiring, and nothing else.

Two things the new tests deliberately pin down:

  1. The semantics must not diverge. env_file_path has its own verbatim-quotes and value-with-spaces tests, so a future change to one path cannot quietly change only one of them.
  2. A real file ends in a newline, unlike the env_file input — hence a test that the last entry of a file is not dropped, which is the failure mode the || [ -n "$line" ] guard exists for.

Value assertions print inside brackets ([%s]) because bats strips trailing newlines from $output, which would otherwise mask a value that wrongly kept one.

Note on merge order

This branches off main, and #1's PR touches the README immediately after the same inputs table, so whichever merges second will need a small conflict resolution. Happy to rebase this one once that lands.

The env_file input takes the variables as content, but "env_file" in
docker-compose is a path -- so people reasonably supply a path, and it fails.
That is what #3 reported, and #7 was an attempt to fix it by swapping printf
for cat, which would have broken every caller passing content.

Rather than change what env_file means, add a second input. env_file_path
names a file to read; env_file keeps its current meaning and its verbatim
`docker --env-file` semantics, so nothing existing breaks. Supplying both is
an error, since the precedence between them would otherwise be arbitrary.

The parsing is now a load_env_file helper shared by both paths, so the two
inputs cannot drift apart in how they treat quotes, spaces or a trailing
newline. The internal destination for the env_file content is renamed to
ENV_FILE_DEST, freeing ENV_FILE_PATH for the input.

Relative paths resolve against the workspace, the same way stack_file already
does.

Closes #3
#2 asked for usage examples of stack_param and env_file. Neither was really
documented: the inputs table described env_file as "additional environment
variables" without saying whether that meant content or a path -- the same
ambiguity behind #3 -- and the stack_param example set the input without ever
showing anything consuming the value, so it demonstrated nothing.

Adds a "Passing values into the stack file" section that explains the actual
mechanism: docker stack deploy substitutes environment variables as it reads
the file, and all three inputs are just ways of setting them. Each one gets a
worked example with the matching stack file.

It also says the thing worth saying about stack_param: env_file variables are
exported before deploy runs, so they reach the stack file by exactly the same
route. stack_param is a one-variable special case with a name the caller
cannot choose. Documented as supported but discouraged rather than deprecated
-- it costs nothing to keep.

While in there, the examples pinned kitconcept/docker-stack-deploy@v1.0.1,
which predates the docker 29 base image, and actions/checkout@v2. Both now
match what this repository actually uses.

Closes #2
@ericof
ericof merged commit 790bd44 into main Sep 4, 2026
4 of 5 checks passed
@ericof
ericof deleted the issues-2-3-env-file branch September 4, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

env_file option doesn't work Documentation - Provide stack_param usage exemple

1 participant