docker / compose

Define and run multi-container applications with Docker
https://docs.docker.com/compose/
Apache License 2.0
33.98k stars 5.22k forks source link

Variable substitution not working on Windows 10 with docker machine #3578

Closed cmaessen closed 4 years ago

cmaessen commented 8 years ago

I'm wondering if I've stumbled on a bug or that there's something not properly documented about variable substitution on Windows in combination with Docker Machine.

If I run the "docker-compose up" command for a yml file that looks like this:

  volumes:
    - ${foobar}/build/:/usr/share/nginx/html/

And this variable doesn't exist docker compose will correctly complain about it:

The foobar variable is not set. Defaulting to a blank string.

However, when I change it to an existing environment variable:

  volumes:
    - ${project_dir}/build/:/usr/share/nginx/html/

It will then not properly start the container and displays the following error (trying to access the nginx container will give you a host is unreachable message):

ERROR: for nginx  rpc error: code = 2 desc = "oci runtime error: could not synchronise with container process: not a directory"

If I run the echo command in the Docker Quickstart Terminal it will output the correct path that I've set in the environment variable.

I get the same type of error message if I try to use the environment variable for the official php image instead of the official nginx image. In both cases the docker compose file works if I substitute ${project_dir} text with the content of the environment variable.

So is this a bug or am I missing something?

shin- commented 8 years ago

Does it work if you capitalize the variable's name? (i.e. PROJECT_DIR instead of project_dir)

cmaessen commented 8 years ago

Capitalisation of variable names doesn't have an effect on this behaviour.

BarnumD commented 8 years ago

At first glance, I believe this is due to the fact that docker runs under a different user (the one you specified when you installed.) That user may not have the same variables as you. I'm having a hard time with this as well. I'm trying to set system environment variables as a work around, but haven't gotten anything to work yet.

Anyone else find a way to make this work?

StefanScherer commented 7 years ago

Just tried it on Windows 10 with Docker 1.13.1 installed, but not tested with Docker4Windows.

docker-compose-with-vars
heaths commented 7 years ago

It does not work, however, if you pass it in via docker-compose -e FOOBAR=c:\vagrant\compose. I've tried many different invocations but passing it in never works. Even with verbose output, I can see the environment is passed but not set.

For example,

# Copyright (C) Microsoft Corporation. All rights reserved.
# Licensed under the MIT license. See LICENSE.txt in the project root for license information.

version: '2.1'
services:
  test:
    build: .
    environment:
      CONFIGURATION: Release
    volumes:
      - ../../src/VSSetup.PowerShell/bin/${CONFIGURATION:-Debug}:C:/Users/ContainerAdministrator/Documents/WindowsPowerShell/Modules/VSSetup:ro
      - ../Instances:C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances:ro
      - ../Tests:C:/Tests
      - C:/VS/Community
      - C:/VS/Professional
      - C:/VS/Enterprise
      - C:/BuildTools
    network_mode: transparent

Note that CONFIGURATION is defaulted to "Release", but "Debug" is still used. If I pass -e CONFIGURATION=Release "Debug" is still used. Only if I set CONFIGURATION=Release (or $env:CONFIGURATION="Release" in PowerShell) does it work.

From verbose output, I can see it's still passed:

compose.cli.verbose_proxy.proxy_callable: docker create_container <- (tty=True, labels={u'com.docker.compose.version': u'1.11.2', u'com.docker.compose.container-number': '1', u'com.docker.compose.service': u'test', u'com.docker.compose.project': u'appveyor', u'com.docker.compose.oneoff': u'True'}, name=u'appveyor_test_run_1', image=u'appveyor_test', stdin_open=True, host_config={'NetworkMode': 'transparent', 'Links': [], u'Isolation': None, 'PortBindings': {}, 'Binds': [u'C:\Users\Heath\Source\Repos\VSSetup.PowerShell\docker\Instances:C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances:ro', u'C:\Users\Heath\Source\Repos\VSSetup.PowerShell\src\VSSetup.PowerShell\bin\Debug:C:/Users/ContainerAdministrator/Documents/WindowsPowerShell/Modules/VSSetup:ro', u'C:\Users\Heath\Source\Repos\VSSetup.PowerShell\docker\Tests:C:/Tests:rw'], 'LogConfig': {'Type': u'', 'Config': {}}, 'VolumesFrom': []}, environment=[u'CONFIGURATION=Release'], command=['-c', 'invoke-pester', 'c:\tests', '-enableexit'], volumes={u'C:/Tests': {}, u'C:/BuildTools': {}, u'C:/VS/Enterprise': {}, u'C:/VS/Professional': {}, u'C:/ProgramData/Microsoft/VisualStudio/Packages/_Instances': {}, u'C:/Users/ContainerAdministrator/Documents/WindowsPowerShell/Modules/VSSetup': {}, u'C:/VS/Community': {}}, detach=False, ports=[])

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

cmaessen commented 5 years ago

Can anyone confirm if this was fixed or not?

stale[bot] commented 5 years ago

This issue has been automatically marked as not stale anymore due to the recent activity.

ndeloof commented 5 years ago

I tried to reproduce this issue.

I've used this minimalist compose file:

version: "3"
service:
  test:
    image: alpine
    volumes:
    - ${foo_bar]/Content:/foo
    command: ls /foo

Without declaring environment variable I have container created with a bind mount to /Content, and a warning about unset variable (as expected)

I've declared foo_bar as an environment variable in system settings. docker-compose up then create the container and actually list the content of my bind mount.

So from this experiment it seems this issue has been fixed, or is caused by some misconfiguration.

cmaessen commented 5 years ago

I tried to reproduce this issue.

I've used this minimalist compose file:

version: "3"
service:
  test:
    image: alpine
    volumes:
    - ${foo_bar]/Content:/foo
    command: ls /foo

Without declaring environment variable I have container created with a bind mount to /Content, and a warning about unset variable (as expected)

I've declared foo_bar as an environment variable in system settings. docker-compose up then create the container and actually list the content of my bind mount.

So from this experiment it seems this issue has been fixed, or is caused by some misconfiguration.

Can't tell from your comment but you tested this on a Windows with Docker Machine?

ndeloof commented 5 years ago

I indeed was testing with docker desktop, anyway compose is ony a client for docker API, so as long as the contianer is created with the expected volumes and bind mount configuration, the actual DOCKER_HOST target has no impact.

You can use docker inspect <id> to check that container is created by compose with the expected path set on bind mount, variable being expanded.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 4 years ago

This issue has been automatically closed because it had not recent activity during the stale period.

Tatsujinichi commented 1 year ago

This still doesn't work