Skip to content

Commit

Permalink
feat(core): Support working with env files (#737)
Browse files Browse the repository at this point in the history
Fix: #687

Users should not be required to load each env var manually if they have
an env file.
Added support for loading a dot-env file.

Usage:
```python
with DockerContainer("nginx:latest").with_env_file("my_env_file"):
    # We now have a container with the relevant env vars from the file
```

This is an implementation of ```docker run --env-file <file> ...```
  • Loading branch information
Tranquility2 authored Nov 18, 2024
1 parent f1d8d35 commit 932ee30
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
8 changes: 8 additions & 0 deletions core/testcontainers/core/container.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import contextlib
from os import PathLike
from socket import socket
from typing import TYPE_CHECKING, Optional, Union

import docker.errors
from docker import version
from docker.types import EndpointConfig
from dotenv import dotenv_values
from typing_extensions import Self, assert_never

from testcontainers.core.config import ConnectionMode
Expand Down Expand Up @@ -57,6 +59,12 @@ def with_env(self, key: str, value: str) -> Self:
self.env[key] = value
return self

def with_env_file(self, env_file: Union[str, PathLike]) -> Self:
env_values = dotenv_values(env_file)
for key, value in env_values.items():
self.with_env(key, value)
return self

def with_bind_ports(self, container: int, host: Optional[int] = None) -> Self:
self.ports[container] = host
return self
Expand Down
29 changes: 29 additions & 0 deletions core/tests/test_core.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import tempfile
from pathlib import Path

from testcontainers.core.container import DockerContainer


Expand All @@ -17,3 +20,29 @@ def test_get_logs():
assert isinstance(stdout, bytes)
assert isinstance(stderr, bytes)
assert "Hello from Docker".encode() in stdout, "There should be something on stdout"


def test_docker_container_with_env_file():
"""Test that environment variables can be loaded from a file"""
with tempfile.TemporaryDirectory() as temp_directory:
env_file_path = Path(temp_directory) / "env_file"
with open(env_file_path, "w") as f:
f.write(
"""
TEST_ENV_VAR=hello
NUMBER=123
DOMAIN=example.org
ADMIN_EMAIL=admin@${DOMAIN}
ROOT_URL=${DOMAIN}/app
"""
)
container = DockerContainer("alpine").with_command("tail -f /dev/null") # Keep the container running
container.with_env_file(env_file_path) # Load the environment variables from the file
with container:
output = container.exec("env").output.decode("utf-8").strip()
assert "TEST_ENV_VAR=hello" in output
assert "NUMBER=123" in output
assert "DOMAIN=example.org" in output
assert "[email protected]" in output
assert "ROOT_URL=example.org/app" in output
print(output)
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ docker = "*" # ">=4.0"
urllib3 = "*" # "<2.0"
wrapt = "*" # "^1.16.0"
typing-extensions = "*"
python-dotenv = "*"

# community modules
python-arango = { version = "^7.8", optional = true }
Expand Down

0 comments on commit 932ee30

Please sign in to comment.