1

I'm trying to write a Docker image for a Discord bot that can run both on my Windows PC for testing and Linux server for production use. I want to be able to Git pull my code on any OS, edit a configuration file in this repository, then simply do docker-compose up to build and run my image (which accesses the configuration file; I don't want to copy this into the image as I may need to edit this file without editing the code/image itself). However, this seems to not be possible, because I do not have a way of guaranteeing where the directory in which this configuration file is located. I have seen workarounds in the official Docker docs that say you should use $(pwd)/path/to/file to access your current directory, however, this only works in UNIX-based systems, and only when using this as an argument of the docker build command. Using $(pwd) or %cd% is not accepted in docker-compose.yml, throwing the error:

yaml.scanner.ScannerError: while scanning for the next token
found character '%' that cannot start any token

I have also already tried to specify paths such as path/to/file and ./path/to/file in both docker run -v <volume paths> and docker-compose.yml, to no avail. While no error is thrown when using ./path in docker run, no files or directories can be found in the image when running.

An example of me trying this with docker-compose.yml: Dockerfile

FROM alpine
RUN ls /usr/src/testdir/

docker-compose.yml

version: "3.8"
services:
    test:
        build: ./
        volumes:
         - ./testdir/:/usr/src/testdir

When there's a folder in the same folder as docker-compose.yml named testdir with one file in here, running the command docker-compose up returns:

ls: /usr/src/testdir/: No such file or directory
ERROR: Service 'test' failed to build : The command '/bin/sh -c ls /usr/src/testdir/' returned a non-zero code: 1

Considering the "write-once, run anywhere" mentality of Docker, it dumbfounds me knowing that Docker doesn't provide any easy way to mount volumes by relative path. Is there a way to use a relative path in docker-compose.yml and/or docker run without the use of OS-specific syntax?

Gabriel
  • 11
  • 1
  • 5
  • 1
    In Compose specifically, [relative paths for `volumes:` are relative to the location of the `docker-compose.yml` file](https://docs.docker.com/compose/compose-file/#short-syntax-3) and should work portably. Can you provide a [mcve] showing the setup that doesn't work? – David Maze Nov 12 '20 at 11:22
  • Hi @DavidMaze. As a test, I've set up a directory on my Windows computer with the file docker-compose.yml: `version: "3.8"services: test: build: ./ volumes: - ./testdir/:/usr/src/testdir`(Not able to put these new lines in a comment) Dockerfile: `FROM alpine RUN ls /usr/src/testdir/` And a directory in this same folder named testdir with a single file in this directory. Upon running `docker-compose up`, the following error is outputted: ls: /usr/src/testdir/: No such file or directory ERROR: Service 'test' failed to build : The command '/bin/sh -c ls /usr/src/testdir/' – Gabriel Nov 12 '20 at 14:51

2 Answers2

1

For anyone who hits this and wants to know how to use $(pwd), it may save a little time to know you need to quote wrap the entire parameter, e.g.

docker run --volume "$(pwd)\:C:/solution/workspace" --env TOKEN=$env:TOKEN cdaf/windows-ado-agent
Jules Clements
  • 418
  • 5
  • 8
0

My Solution

My issue wasn't necessarily related to not being able to access relative paths in Docker. Relative paths are usable through docker run (this is pointed out by the above solution by Jules Clements and the comment by user1767316: wrap the volume argument value in double quotes and use ($pwd)), relative paths are supported in docker-compose.yml as pointed out by David. I was attempting to access this volume during build-time, which isn't possible per my configuration during. I instead will copy the configuration file over during one build-time layer, but use the volume for when the image is running.

Other Resources

Gabriel
  • 11
  • 1
  • 5
  • You do not have to use `%cd%, $(pwd), etc. depending on your OS.` You can use `${pwd}` on all OS using cygwin on windows as long as you surround the volume argument value with double quotes. `docker run --volume "$(pwd)\:/dir/inside/container" ...` – user1767316 Nov 13 '22 at 00:53
  • @user1767316 Thanks for the comment. I'll include that in the solution. – Gabriel Nov 13 '22 at 23:59