benjamin.cohen-solal
benjamin.cohen-solal

Reputation: 481

How does the "volume" argument work in docker?

I have these following lines on my .gitlabci file :

- echo "$PWD"
- ls -l "$PWD"
- docker run --volume "$PWD":/code debian:stable ls -l /code

And following is the output:

$ echo "$PWD" 
/builds/ben/project 

$ ls -l "$PWD" total 52
-rw-rw-rw-    1 root     root           946 Feb 19 14:53 ChangeLog
-rw-rw-rw-    1 root     root           294 Feb 19 14:53 INSTALL
-rw-rw-rw-    1 root     root          4341 Feb 19 14:53 Jenkinsfile
-rw-rw-rw-    1 root     root           353 Feb 19 14:53 README.md
-rw-rw-rw-    1 root     root           535 Feb 19 14:53 TODO 
drwxrwxrwx    4 root     root          4096 Feb 19 14:53 application
drwxrwxrwx    2 root     root          4096 Feb 19 14:53 library 
drwxrwxrwx    3 root     root          4096 Feb 19 14:53 public 
drwxrwxrwx    3 root     root          4096 Feb 19 14:53 tests 

$ docker run --volume "$PWD":/code debian:stable ls -l /code 
total 0

Following is my .gitlabci file:

code_quality:
  image: docker:stable

  variables:
    DOCKER_DRIVER: overlay

  allow_failure: true

  services:
    - docker:dind

  script:
    - echo "$PWD"
    - ls -l "$PWD"
    - docker run --volume "$PWD":/code debian:stable ls -l /code

And finally the config.toml of my runner:

concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "test"
  url = "http://docker.int.com:1040/"
  token = "*************"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock","/cache"]
    extra_hosts = ["mygitlab.com:XXX.XXX.XXX.XXX"]
    shm_size = 0
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

I don't understand why the last command doesn't display the content of my $PWD directory (/builds/ben/project). My volume doesn't seem to be mounted successfully but I get no error.

Upvotes: 2

Views: 1364

Answers (1)

grapes
grapes

Reputation: 8646

I am sure you are using docker-in-docker mode.

In this mode docker command in pipeline effectively connects to HOST machine's docker daemon and sends all commands there. As a result, host tries to bind /builds/ben/project path into container, but there is no such path. Again, following bind mounts behavior, this folder will be created empty and mapped into containers.

If you are using non-privileged mode (mapping /var/run/docker.sock), try switching to using docker:dind as a service. In this case daemon will get context from your build job. Otherwise you have to manually copy data into volume.

UPD

When using /var/run/docker.sock you actually pass docker commands unmodified to the daemon, who executes them in his own context. That means he uses his file system, not yours (job's). I've managed to bypass this by manual cloning sources into new container with command like

git clone ${CI_REPOSITORY_URL} --branch ${CI_COMMIT_REF_NAME} --single-branch /tmp/project

Drawback is that you need to install git into your images.

This is what gitlab writes:

Sharing files and directories from the source repo into containers may not work as expected since volume mounting is done in the context of the host machine, not the build container

Upvotes: 1

Related Questions