75

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/

  • What happens if you run `env | grep PWD` from the same shell? – BMitch Jan 31 '17 at 01:19
  • 2
    @BMitch I get my normal PWD: /home/user/... and OLDPWD=... –  Jan 31 '17 at 01:22
  • 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. – BMitch Jan 31 '17 at 01:27
  • @BMitch 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 warning –  Jan 31 '17 at 01:28
  • `echo $PWD` is not the same as `env`, the first will pickup variables that have not been exported. – BMitch Jan 31 '17 at 01:30
  • 4
    In my case, I happened to be [running docker-compose using sudo](https://github.com/docker/compose/issues/5003#issuecomment-318469535). [Using the -E flag](https://stackoverflow.com/a/8633575/2104168) for sudo to preserve the existing environment variables solved this for me. `sudo -E bash -c 'docker-compose up'` – cjsimon Jan 21 '20 at 00:25
  • 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. – ajaykools Mar 23 '22 at 12:13

4 Answers4

90

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.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • 13
    For whatever reason, Docker for Windows gets confused with relative directories. The ${PWD} approach works better. – Berin Loritsch Jun 26 '17 at 17:42
  • 6
    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 problem – Ionel Lupu Mar 07 '18 at 12:47
  • 5
    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. – dnk8n Aug 13 '19 at 21:55
  • @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. – A Merii Apr 03 '20 at 15:33
  • 5
    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. – pwes Oct 17 '20 at 10:29
  • @pwes in that scenario, I'd say the `.` is the better option since PWD can be unpredictable to the author of the compose file. – BMitch Oct 17 '20 at 11:14
  • 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}`. – Saeed Neamati Jun 18 '21 at 12:32
  • @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. – BMitch Jun 18 '21 at 12:35
23

My advice: change all $PWD to .

koualsky
  • 255
  • 2
  • 2
  • 10
    This is exactly the same as BMitch's answer – MBorg Feb 17 '20 at 12:04
  • 2
    In docker-compose.yml $PWD has different meaning than "." – pwes Oct 17 '20 at 10:30
  • 2
    @MBorg no it isn't- this answer is a lot shorter. – markemus Jan 04 '21 at 20:09
  • 7
    `.` 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. – Bouke Versteegh Nov 22 '21 at 18:13
  • 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. – patricknelson May 12 '22 at 20:50
20

$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=/
3

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

set PWD=%CD%
Jthorpe
  • 9,756
  • 2
  • 49
  • 64