Add docs for job scripts running in build_dir instead of docker container when the executor is docker
Problem to solve
When a job script is run with a relative path, the script is executed inside Gitlab runner /builds
directory, even though the executor is docker executor.
Further details
Given the dockerfile of a Node.js app:
FROM node:14.15.0-stretch
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "test"]
and given the .gitlab-ci.yml test job:
test-job:
image: docker_image_name
stage: test
script:
- npm run test
the job will fail with an error message along the lines:
sh: 1: ts-node: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the mypackage@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
This is because the script is not run inside the docker container (which does contain node_modules
- the result of build) but rather it is run in Gitlab runner host path /build/project_name/
which doesn't contain node_modules
.
The job from the following .gitlab-ci.yml will work successfully:
test-job:
image: docker_image_name
stage: test
script:
- cd /usr/src/app && npm run test
because the node_modules
are located in /usr/src/app
inside docker container. I still don't know what Gitlab runner logic is, but I suspect that script
is executed in Gitlab runner host by default and only when specifying absolute path which refers to docker container the script
is run in docker container. This is confusing because in the docs it says:
The runner sends the script to the container’s shell stdin and receives the output.
but it clearly doesn't in this case even though it is docker executor.
Proposal
Explain and document the logic which decides when script
is executed in Gitlab runner host and when it is executed in docker container.