Jonathan
Jonathan

Reputation: 125

Dockerfile COPY from host to container works, but when docker-compose.yml uses volume, the file in container not visible to host

Using the context:

test workspace

The goal is to copy test.txt into the container and have it visible in the host's tst folder. The tst folder contains a pre-existing file, tst.txt.

Using Docker application:

Docker application

Using .dockerignore:

.DS_Store
.vscode
.dockerignore
Dockerfile
docker-compose.yml
**/tst

Using the Dockerfile:

FROM alpine:latest
RUN apk add --no-cache bash
WORKDIR /app
RUN echo "$(echo "pwd:")" "$(pwd)"  <<-- returns pwd: /app 
COPY test.txt .
RUN ls -la . 
CMD ["sh", "-c", "ls -la ."]

Using the docker-compose file:

version: '3.7'
services:
  app:
    build: .
    volumes:
      - ./tst:/app

Running docker-compose up results in:

Creating network "sof_default" with the default driver
Building app
Step 1/7 : FROM alpine:latest
latest: Pulling from library/alpine
6c40cc604d8e: Downloading [>                                                  
----------
Step 3/7 : WORKDIR /app
---> Running in cf58e5a10d23
Removing intermediate container cf58e5a10d23
---> 76fb51298933
Step 4/7 : RUN echo "$(echo "pwd:")" "$(pwd)"
---> Running in 07135f745883
pwd: /app
Removing intermediate container 07135f745883
---> 45acc1c04a12
Step 5/7 : COPY test.txt .
---> de0ce42397b9
Step 6/7 : RUN ls -la . <<- the output shows test.txt was copied into the container's /app directory
---> Running in 60371e9516c1
total 12
drwxr-xr-x    1 root     root          4096 Feb 12 21:25 .
drwxr-xr-x    1 root     root          4096 Feb 12 21:25 ..
-rw-r--r--    1 root     root            15 Feb 12 19:19 test.txt
Removing intermediate container 60371e9516c1
---> 3d514dac4f61
Step 7/7 : CMD ["sh", "-c", "ls -la . && cat test.txt"]
---> Running in db644643a844
Removing intermediate container db644643a844
---> ad9f6988d31d

Successfully built ad9f6988d31d
Successfully tagged sof_app:latest
WARNING: Image for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating sof_app_1 ... done
Attaching to sof_app_1
app_1  | total 8
app_1  | drwxr-xr-x    3 root     root            96 Feb 12 20:50 .
app_1  | drwxr-xr-x    1 root     root          4096 Feb 12 21:25 ..
app_1  | -rw-r--r--    1 root     root            45 Feb 12 20:51 tst.txt
app_1  | cat: can't open 'test.txt': No such file or directory
sof_app_1 exited with code 1

The output shows text.txt was copied into the container, but it is not visible on the host. Why is that?

The https://docs.docker.com/compose/faq/ says

"You can have the image include the code using a COPY, and use a volume in your Compose file to include the code from the host during development. The volume overrides the directory contents of the image."

I interpret the last sentence to mean that any files or folders in the host's volume override those of the same name in the image's mapped directory. I would not expect the host directory to completely overwrite the image's directory, deleting any files already in it. Am I mistaken in that assumption?

Any good guidance is appreciated.

Upvotes: 1

Views: 1622

Answers (1)

codestation
codestation

Reputation: 3518

Bind mounted volumes completely override the directory that you specified on the compose file so you won't see any files copied in the /app directory by the dockerfile.

You must use either anonymous or named volumes so docker copies the files in the declared volume before mounting it. [1]

If you still want to use bind mounted volumes then your only option is to copy the files once the container is already started (not on the dockerfile).

[1] https://docs.docker.com/engine/reference/builder/#volume

Upvotes: 3

Related Questions