Docker compose won't find $PWD environment variable
Asked Answered
M

4

80

Here's my docker-compose:

version: '2'
services:
  couchpotato:
    build:
        context: ./couchpotato
        dockerfile: Dockerfile
    ports:
     - 5050:5050
    volumes:
     - "${PWD}/couchpotato/data:/home/CouchPotato/data/"
     - "${PWD}/couchpotato/config:/home/CouchPotato/config/"

When I run it inside the shell, in the directory of the docker-compose.yml, I get:

WARNING: The PWD variable is not set. Defaulting to a blank string.

and the compose starts with PWD being empty.

I don't see any error in the file, as seen here: https://docs.docker.com/compose/environment-variables/

Mover answered 31/1, 2017 at 1:15 Comment(7)
What happens if you run env | grep PWD from the same shell?Crazy
@Crazy I get my normal PWD: /home/user/... and OLDPWD=...Mover
And that's the exact same shell you used to run the docker-compose command? You didn't launch it with some kind of exec, through any kind of scheduler, etc? Because when I run something similar locally I can't reproduce this error under bash.Crazy
@Crazy nope, I've just run docker-compose up. That's what I did: echo $PWD and enter, got the PWD printed. Then docker-compose up in the next line, got the warningMover
echo $PWD is not the same as env, the first will pickup variables that have not been exported.Crazy
In my case, I happened to be running docker-compose using sudo. Using the -E flag for sudo to preserve the existing environment variables solved this for me. sudo -E bash -c 'docker-compose up'Beauvoir
Had same problem. What I did is, first i login as root sudo su and then I run docker-compose up command to make it work. But still dont know why ${PWD} didnt pick in non-root session.Gilson
C
98

You don't need ${PWD} for this, you can just make the path relative and compose will expand it (one major difference between compose paths and those processed by docker run).

version: '2'
services:
  couchpotato:
    build:
        context: ./couchpotato
        dockerfile: Dockerfile
    ports:
     - 5050:5050
    volumes:
     - "./couchpotato/data:/home/CouchPotato/data/"
     - "./couchpotato/config:/home/CouchPotato/config/"

As for why compose doesn't see this variable, that depends on your shell. Compose looks for an exported environment variable, contents of the .env file, and command line flags to the docker-compose command. If each of those comes up empty for the variable, you'll get that warning.

Crazy answered 31/1, 2017 at 1:30 Comment(8)
For whatever reason, Docker for Windows gets confused with relative directories. The ${PWD} approach works better.Lingwood
I;m using Docker compose with Windows Linux Subsystem. I can relate to the fact that relative paths (like ./config/nginx) are not working and gives the error not a directory. For me at least. Using ${PWD} instead of .solves the problemAmmoniac
Something to bare in mind, if you are using -f /path/to/compose.yml, then the relative volumes will be relative to the template. Sometimes it might be useful to have it relative to PWD, hence why you might want to include it. It's to do with the shell. Might have to manually set PWD if you are running automation without a shell.Unholy
@boyd I am currently using ubuntu wsl2, and have docker and docker-compose installed on it there and not on windows. When trying to use ${PWD} , I get the following warning: The PWD variable is not set. Defaulting to a blank string.Swamper
The dot (.) and PWD variable can expand to different values, when the docker-compose.yml is not in the current dir: "." expand to the dir, where the YAML file is and PWD is your current dir. So they can serve different purposes.Gluteus
@Gluteus in that scenario, I'd say the . is the better option since PWD can be unpredictable to the author of the compose file.Crazy
This answer is wrong. What if you want to use the current directory's name dynamically on both sides of the volume? for example ${PWD}/db:/databases/${PWD}.Consciencestricken
@SaeedNeamati you would need to define ${PWD} for that to work. From the above answer "Compose looks for an exported environment variable, contents of the .env file, and command line flags to the docker-compose command." Putting ${PWD} in the other side of the mount is also a different question, the above is an answer to the OP.Crazy
C
25

My advice: change all $PWD to .

Cavan answered 17/2, 2020 at 11:44 Comment(5)
This is exactly the same as BMitch's answerCassette
In docker-compose.yml $PWD has different meaning than "."Gluteus
@Cassette no it isn't- this answer is a lot shorter.Chartier
. is a path relative to the docker-compose file, while $PWD is an environment variable that usually contains the current working directory, from which the docker-compose command is ran. They are not the same, unless you ran dc from the same dir as the yml.Yvetteyvon
I used to use this, the extremely frustrating problem with this is that now Docker errors with "volume name is too short, names should be at least two alphanumeric characters" and ${PWD} doesn't seem to work for me on Windows, even when executing it in Cygwin. Annoying because the whole point to using docker was for simplicity and cross compatibility.Ape
E
22

$PWD will not work if you are running using sudo. Try the recommended settings from Docker for Linux https://docs.docker.com/engine/install/linux-postinstall/.

Sudo will run as a different user, with a different env.

$ sudo env | grep -i pwd
$ env | grep -i pwd
PWD=/home/user
OLDPWD=/
Emphysema answered 20/5, 2020 at 4:41 Comment(1)
This worked for me sudo PWD=${PWD} docker-compose buildFlyn
T
4

If you really need absolute paths, then call this before calling docker-compose up:

set PWD=%CD%
Twum answered 18/2, 2021 at 21:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.