Skip to content

Add --env-from-file option to run command - #1584

Open
Thanatos9404 wants to merge 1 commit into
containers:mainfrom
Thanatos9404:run-env-from-file
Open

Thanatos9404 wants to merge 1 commit into
containers:mainfrom
Thanatos9404:run-env-from-file

Conversation

@Thanatos9404

Copy link
Copy Markdown

docker compose run has a repeatable --env-from-file option that sets environment variables of the one-off container from a file (CLI reference). podman-compose rejected it as an unrecognized argument.

Fixes: #1239

Behaviour

This follows docker compose's implementation, getEnvironment() in cmd/compose/run.go:

  • The option can be given several times. The files are read in order, and a variable set by an earlier file is not overridden by a later one. This is the opposite of the global --env-file, where later files win, but it is what docker compose does.
  • A bare KEY line without a value is ignored, as in docker compose.
  • Values given with -e take precedence over all files.
  • The values are added to the service's environment, where -e puts its values, so they override the service's environment and env_file the same way -e does.
  • Relative paths are resolved against the working directory, not the project directory: docker compose opens the path as given. The path is made absolute when the arguments are parsed, because podman-compose changes into the directory of the compose file when it finds that file in a parent directory. Without this, run --env-from-file=testing.env from a subdirectory would read the testing.env next to the compose file instead.
  • A missing file is reported in _parse_args(), next to the up --wait checks, so run stops with Error: Couldn't find env file: <absolute path> and exit code 1 before any pod or container is created. The wording is the one the global --env-file uses.

The files are read with dotenv_to_dict(), the python-dotenv helper already used for env_file. One difference: ${VAR} in the file is expanded from the file itself and the host environment, as for env_file, while docker compose looks up the -e values and the earlier files.

--remove-orphans, which the command in the issue also uses, is a separate option and is not part of this PR.

Tests

New tests in tests/unit/test_compose_run_update_container_from_args.py, using the env files in tests/integration/env_file_tests/env-files/:

  • one file;
  • two files that share variables: the first file wins, and a variable only the second file sets is added;
  • -e overriding a value from a file;
  • a file overriding the service's environment;
  • bare KEY lines, which neither replace the service's value nor stop a later file from setting the variable.

New tests/unit/test_compose_run_args.py, through _parse_args() like test_compose_up_args.py:

  • the option is repeatable and relative paths become absolute against the working directory;
  • a missing file raises PodmanComposeError with its absolute path.

On main the 7 new tests fail or error: 5 failures, and 2 errors from unrecognized arguments: --env-from-file.

Results on Ubuntu 24.04 (WSL), Python 3.12.3, with requirements.txt and test-requirements.txt installed:

  • python -m unittest discover tests/unit: 504 tests OK (497 on main, also OK).
  • ruff format --check, ruff check, mypy . and pylint podman_compose.py (10.00/10): pass.
  • There is no Podman on this machine, so the integration tests were not run. I checked the generated podman run command with --dry-run --verbose, with a dummy podman on PATH that exits 0 (dry run still calls podman network exists). With the compose file and testing.env from the issue, podman-compose run --env-from-file=testing.env app passes -e ZZVAR1=foo -e ZZVAR2=bar -e ZZVAR3=baz, the values docker compose prints in the issue.

Checklist

  • Read CONTRIBUTING.md (one commit, signed off, no feat: prefix)
  • Release note: newsfragments/run_env_from_file.feature
  • Unit tests
  • run options are not part of the compose spec; the docker compose reference is linked above.

`docker compose run` accepts `--env-from-file` to set environment
variables of the one-off container from a file. podman-compose rejected
the option as an unrecognized argument.

The option can be repeated and follows docker compose: the files are
read in order, a variable set by an earlier file is not overridden by a
later one, a bare `KEY` line without a value is ignored, values given
with `-e` take precedence over all files, and the result overrides the
service's environment. The files are parsed with dotenv_to_dict(), the
helper already used for `env_file`.

Relative paths are resolved against the working directory when the
arguments are parsed, because podman-compose may later change into the
directory where the compose file was found. A missing file is reported
in _parse_args(), before any pod or container is created.

Fixes: containers#1239
Signed-off-by: Yashvardhan Thanvi <[email protected]>
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.

Support --env-from-file option in run command

1 participant