I want to run a Postman collection from a Docker image in a Gitlab CI pipeline. The Docker socket file is already mounted for the gitlab-ci-runner so the runner has access to the docker server.
Here's the job definition from .gitlab-ci.yaml
postman:
image: docker:20.10.14
stage: schedule
only:
- schedules
before_script: []
script:
- env
- docker run -t -v $CI_PROJECT_DIR:/etc/newman postman/newman run postman_collection.json
The console output of the gitlab CI runner looks like this:
$ docker run -t -v $CI_PROJECT_DIR:/etc/newman postman/newman run postman_collection.json
error: collection could not be loaded
unable to read data from file "postman_collection.json"
ENOENT: no such file or directory, open 'postman_collection.json'
The file exists. I even tried
docker run --rm -it -v $PWD:/etc/newman --entrypoint sh postman/newman
from my localhost console and ran it manually. It's all there. What am I missing?
The Docker socket file is already mounted for the gitlab-ci-runner
The problem here is that in the scenario where you are talking to the host docker daemon (i.e., when the host docker socket in mounted in the job), when you pass the volume argument to docker run
like -v /source/path:/container/path
the /source/path
part of the argument refers to the host filesystem not the filesystem of the job container.
Think about it like this: the host docker daemon doesn't know that its socket is mounted inside the job container. So when you run docker
commands this way, it's as if you're running the docker
command on the runner host!
Because $PWD
and $CI_PROJECT_DIR
in your job command evaluates to a path in the job container (and this path isn't on the runner host filesystem) the volume mount will not work as expected.
This limitation is noted in the limitations of Docker socket binding documentation:
Sharing files and directories from the source repository into containers may not work as expected. Volume mounting is done in the context of the host machine, not the build container
The easiest workaround here would likely be to use postman/newman
as your image:
instead of docker
.
myjob:
image:
name: postman/newman
entrypoint: [""]
script:
- newman run postman_collection.json