1

Hello I am trying to share data between host and container, in order to do this I have the following Dockerfile, and docker-compose.yml:

Dockerfile

FROM python:3.8.7-buster
RUN mkdir /proxies
COPY proxies /proxies
RUN pwd
RUN ls -la /proxies

docker-compose.yml

version: '3'
services:
  socks_provider:
    build: SocksProvider
    volumes:
      - ${HOST_PATH}/proxies:/proxies

When pwd and ls run to show the correct output, the files in the container are in /proxies, but when try to access to that files using the volume folder in the host there aren't files, but the folder is created.

How can share that files between container and host?

ErikMD
  • 13,377
  • 3
  • 35
  • 71
Tlaloc-ES
  • 4,825
  • 7
  • 38
  • 84
  • what's the value of `HOST_PATH`? – ItayB Jan 30 '21 at 13:52
  • Does this answer your question? [Docker: Strange behaviour of bind mount](https://stackoverflow.com/questions/65955098/docker-strange-behaviour-of-bind-mount) – ErikMD Jan 30 '21 at 13:58
  • HOST_PATH is a variable got from .env, and that is working ok because the folder is creating ok – Tlaloc-ES Jan 30 '21 at 14:05
  • @Tlaloc-ES As mentioned in [this answer by @DavidMaze](https://stackoverflow.com/a/65955679/9164010), "you can't directly use volumes to copy files out of an image; you have to run a container that runs a `cp` command." – ErikMD Jan 30 '21 at 14:11
  • BTW, note that the Dockerfile command `VOLUME` is certainly unneeded in the general case, see e.g. that answer by @DavidMaze in another thread: [Why do some Docker images have no VOLUME defined?](https://stackoverflow.com/a/61761083/9164010) – ErikMD Jan 30 '21 at 14:25
  • Thanks @ErikMD really I do not understand you, so I need another container in order to have data shared between different containers and host? – Tlaloc-ES Jan 30 '21 at 14:28
  • @Tlaloc-ES OK so to give more details, I've posted some "PoC" in an answer below – ErikMD Jan 30 '21 at 14:51

1 Answers1

1

The volumes: ['${HOST_PATH}/proxies:/proxies'] field of your your docker-compose.yml specification creates a so-called bind-mount. And as I mentioned in the comments, this feature cannot automagically "export" existing files from an image to the host. For details, this is well explained in this other SO answer "Docker: Strange behaviour of bind mount".

So to achieve what you want, I guess you need to create a bind-mount with a separate folder, and rely on some entrypoint code. Proof-of-concept (to be refined):

entrypoint.sh

#!/bin/sh

if [ -d "/export" ]; then
  ( set -x; cp -a -T -- /proxies /export )
else
  echo >&2 "Skipping copy to /export: No such directory"
fi

exec "$@"

Dockerfile

FROM python:3.8.7-buster
# RUN mkdir /proxies  # unneeded: the COPY command will create it
COPY proxies /proxies
WORKDIR /app
COPY entrypoint.sh /app/
RUN chmod a+x entrypoint.sh
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["/bin/sh"]

docker-compose.yml

version: '3'
services:
  socks_provider:
    build: SocksProvider
    volumes:
      - ${HOST_PATH}/proxies:/export
ErikMD
  • 13,377
  • 3
  • 35
  • 71
  • ERROR: for services_socks_provider_1 Cannot start service socks_provider: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/app/entrypoint.sh\": permission denied": unknown – Tlaloc-ES Jan 30 '21 at 14:58
  • Good point: a `chmod a+x` was missing indeed – ErikMD Jan 30 '21 at 14:59
  • @Tlaloc-ES I've tested it right now, and it seems to work: `docker-compose up --build` yields `socks_provider_1 | + cp -a -T -- /proxies /export` – ErikMD Jan 30 '21 at 15:07
  • Works because copy the code, but I was expected shared data betwen host and container in order to restore data if run docker in several machines. – Tlaloc-ES Jan 30 '21 at 15:08
  • Two last comments: no need for `RUN mkdir /proxies` nor `RUN mkdir /app` as `COPY` and `WORKDIR` will create the folders for you; finally you may want to add some `CMD ["/bin/sh"]` command or so to specify the default arguments… – ErikMD Jan 30 '21 at 15:09
  • BTW you said "I was expected shared data betwen host and container in order to restore data if run docker in several machines" → maybe a bind-mount would not be the proper solution, but rather a [named volume](https://docs.docker.com/storage/volumes/#populate-a-volume-using-a-container)? (which behaves better than bind-mount, and can be exported/imported as well… but this might deserve a new question, maybe :) – ErikMD Jan 30 '21 at 15:11