mirror of
https://github.com/docker/compose.git
synced 2025-04-08 17:05:13 +02:00
Added additional argument (--env-file) for docker-compose to import environment variables from a given PATH.
Signed-off-by: Dimitrios Mavrommatis <jim.mavrommatis@gmail.com>
This commit is contained in:
parent
572032fc0b
commit
b09d8802ed
compose
tests
@ -39,7 +39,8 @@ SILENT_COMMANDS = set((
|
||||
|
||||
def project_from_options(project_dir, options):
|
||||
override_dir = options.get('--project-directory')
|
||||
environment = Environment.from_env_file(override_dir or project_dir)
|
||||
environment_file = options.get('--env-file')
|
||||
environment = Environment.from_env_file(override_dir or project_dir, environment_file)
|
||||
environment.silent = options.get('COMMAND', None) in SILENT_COMMANDS
|
||||
set_parallel_limit(environment)
|
||||
|
||||
@ -77,7 +78,8 @@ def set_parallel_limit(environment):
|
||||
|
||||
def get_config_from_options(base_dir, options):
|
||||
override_dir = options.get('--project-directory')
|
||||
environment = Environment.from_env_file(override_dir or base_dir)
|
||||
environment_file = options.get('--env-file')
|
||||
environment = Environment.from_env_file(override_dir or base_dir, environment_file)
|
||||
config_path = get_config_path_from_options(
|
||||
base_dir, options, environment
|
||||
)
|
||||
|
@ -208,6 +208,7 @@ class TopLevelCommand(object):
|
||||
(default: the path of the Compose file)
|
||||
--compatibility If set, Compose will attempt to convert keys
|
||||
in v3 files to their non-Swarm equivalent
|
||||
--env-file PATH Specify an alternate environment file
|
||||
|
||||
Commands:
|
||||
build Build or rebuild services
|
||||
@ -274,7 +275,8 @@ class TopLevelCommand(object):
|
||||
'--build-arg is only supported when services are specified for API version < 1.25.'
|
||||
' Please use a Compose file version > 2.2 or specify which services to build.'
|
||||
)
|
||||
environment = Environment.from_env_file(self.project_dir)
|
||||
environment_file = options.get('--env-file')
|
||||
environment = Environment.from_env_file(self.project_dir, environment_file)
|
||||
build_args = resolve_build_args(build_args, environment)
|
||||
|
||||
self.project.build(
|
||||
@ -423,8 +425,10 @@ class TopLevelCommand(object):
|
||||
Compose file
|
||||
-t, --timeout TIMEOUT Specify a shutdown timeout in seconds.
|
||||
(default: 10)
|
||||
--env-file PATH Specify an alternate environment file
|
||||
"""
|
||||
environment = Environment.from_env_file(self.project_dir)
|
||||
environment_file = options.get('--env-file')
|
||||
environment = Environment.from_env_file(self.project_dir, environment_file)
|
||||
ignore_orphans = environment.get_boolean('COMPOSE_IGNORE_ORPHANS')
|
||||
|
||||
if ignore_orphans and options['--remove-orphans']:
|
||||
@ -481,8 +485,10 @@ class TopLevelCommand(object):
|
||||
-e, --env KEY=VAL Set environment variables (can be used multiple times,
|
||||
not supported in API < 1.25)
|
||||
-w, --workdir DIR Path to workdir directory for this command.
|
||||
--env-file PATH Specify an alternate environment file
|
||||
"""
|
||||
environment = Environment.from_env_file(self.project_dir)
|
||||
environment_file = options.get('--env-file')
|
||||
environment = Environment.from_env_file(self.project_dir, environment_file)
|
||||
use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI')
|
||||
index = int(options.get('--index'))
|
||||
service = self.project.get_service(options['SERVICE'])
|
||||
@ -1038,6 +1044,7 @@ class TopLevelCommand(object):
|
||||
container. Implies --abort-on-container-exit.
|
||||
--scale SERVICE=NUM Scale SERVICE to NUM instances. Overrides the
|
||||
`scale` setting in the Compose file if present.
|
||||
--env-file PATH Specify an alternate environment file
|
||||
"""
|
||||
start_deps = not options['--no-deps']
|
||||
always_recreate_deps = options['--always-recreate-deps']
|
||||
@ -1052,7 +1059,8 @@ class TopLevelCommand(object):
|
||||
if detached and (cascade_stop or exit_value_from):
|
||||
raise UserError("--abort-on-container-exit and -d cannot be combined.")
|
||||
|
||||
environment = Environment.from_env_file(self.project_dir)
|
||||
environment_file = options.get('--env-file')
|
||||
environment = Environment.from_env_file(self.project_dir, environment_file)
|
||||
ignore_orphans = environment.get_boolean('COMPOSE_IGNORE_ORPHANS')
|
||||
|
||||
if ignore_orphans and remove_orphans:
|
||||
@ -1345,7 +1353,8 @@ def run_one_off_container(container_options, project, service, options, toplevel
|
||||
if options['--rm']:
|
||||
project.client.remove_container(container.id, force=True, v=True)
|
||||
|
||||
environment = Environment.from_env_file(project_dir)
|
||||
environment_file = options.get('--env-file')
|
||||
environment = Environment.from_env_file(project_dir, environment_file)
|
||||
use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI')
|
||||
|
||||
signals.set_signal_handler_to_shutdown()
|
||||
|
@ -59,12 +59,15 @@ class Environment(dict):
|
||||
self.silent = False
|
||||
|
||||
@classmethod
|
||||
def from_env_file(cls, base_dir):
|
||||
def from_env_file(cls, base_dir, env_file=None):
|
||||
def _initialize():
|
||||
result = cls()
|
||||
if base_dir is None:
|
||||
return result
|
||||
env_file_path = os.path.join(base_dir, '.env')
|
||||
if env_file:
|
||||
env_file_path = os.path.join(base_dir, env_file)
|
||||
else:
|
||||
env_file_path = os.path.join(base_dir, '.env')
|
||||
try:
|
||||
return cls(env_vars_from_file(env_file_path))
|
||||
except EnvFileNotFound:
|
||||
|
@ -324,6 +324,21 @@ class CLITestCase(DockerClientTestCase):
|
||||
'version': '2.4'
|
||||
}
|
||||
|
||||
def test_config_with_env_file(self):
|
||||
self.base_dir = 'tests/fixtures/default-env-file'
|
||||
result = self.dispatch(['--env-file', '.env2', 'config'])
|
||||
json_result = yaml.load(result.stdout)
|
||||
assert json_result == {
|
||||
'services': {
|
||||
'web': {
|
||||
'command': 'false',
|
||||
'image': 'alpine:latest',
|
||||
'ports': ['5644/tcp', '9998/tcp']
|
||||
}
|
||||
},
|
||||
'version': '2.4'
|
||||
}
|
||||
|
||||
def test_config_with_dot_env_and_override_dir(self):
|
||||
self.base_dir = 'tests/fixtures/default-env-file'
|
||||
result = self.dispatch(['--project-directory', 'alt/', 'config'])
|
||||
|
4
tests/fixtures/default-env-file/.env2
vendored
Normal file
4
tests/fixtures/default-env-file/.env2
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
IMAGE=alpine:latest
|
||||
COMMAND=false
|
||||
PORT1=5644
|
||||
PORT2=9998
|
@ -3465,6 +3465,25 @@ class InterpolationTest(unittest.TestCase):
|
||||
'command': 'true'
|
||||
}
|
||||
|
||||
@mock.patch.dict(os.environ)
|
||||
def test_config_file_with_options_environment_file(self):
|
||||
project_dir = 'tests/fixtures/default-env-file'
|
||||
service_dicts = config.load(
|
||||
config.find(
|
||||
project_dir, None, Environment.from_env_file(project_dir, '.env2')
|
||||
)
|
||||
).services
|
||||
|
||||
assert service_dicts[0] == {
|
||||
'name': 'web',
|
||||
'image': 'alpine:latest',
|
||||
'ports': [
|
||||
types.ServicePort.parse('5644')[0],
|
||||
types.ServicePort.parse('9998')[0]
|
||||
],
|
||||
'command': 'false'
|
||||
}
|
||||
|
||||
@mock.patch.dict(os.environ)
|
||||
def test_config_file_with_environment_variable(self):
|
||||
project_dir = 'tests/fixtures/environment-interpolation'
|
||||
|
Loading…
x
Reference in New Issue
Block a user