I have a docker image that installs ubuntu and RUNs some additional commands like installing NodeJS.
The Dockerfile (in combination with a docker-compose.yml) also mounts a directory to a directory on the host. That looks like this:
services:
test:
build:
context: ../../
dockerfile: docker/Dev/Dockerfile
ports:
- 7000:7000
volumes:
- ./../../src:/src
In the Dockerfile I have the following lines for a volume:
VOLUME ["/src"]
WORKDIR /src
When I run the container with docker-compose up and then do a ls -a inside the mounted src/ folder of the container, then I see all the files that I also see on the host. So far so good.
(Command I run too look inside container: docker exec -it <container hash> ls -a)
Since all files seem to be there, including a package.json I added a new RUN command to my Dockerfile which is: npm install. So I have this:
VOLUME ["/src"]
WORKDIR /src
RUN npm install
Except that gives me an error that it can't find a package.json in the src/ folder.
When I add a RUN ls -a (remember, I switched to the src/ folder with WORKDIR), then it shows that it's an empty directory...
So in Dockerfile I have:
VOLUME ["/src"]
WORKDIR /src
# shows that /src is empty. If I do 'RUN pwd', then it shows I really am in /src
RUN ls -a
RUN npm install
But still, after I do a docker-compose up and then again do a ls -a inside the /src folder of the container it shows all my source files again.
So my question is, why aren't they there during build time (I'm running docker-compose build)?
What is the way to fix this issue?
You're misunderstanding the difference between the VOLUME command in a Dockerfile and the -v flag to the docker daemon (what docker-compose uses for its volumes).
The values under the volumes key in your docker-compose file tell docker what directories to map in after your image has finished building. They aren't used during the build process.
Fortunately, you automatically have access to all of your source files, due to the context line in your compose file - they're just in the local src directory, not your current working directory!
Try updating your Dockerfile to the following:
# NOTE: You don't want a VOLUME directive if you only want to mount a local
# directory. WORKDIR is optional, but doesn't matter for my example,
# so I'm omitting it.
# Copy the npm files into your Docker image. If you do this first, the docker
# daemon can cache the built layers, making your images build faster and be
# substantially smaller, since most of your dependencies will remain unchanged
# between builds.
COPY src/package.json package.json
COPY src/npm-shrinkwrap.json npm-shrinkwrap.json
# Actually install the dependencies.
RUN npm install
# Copy all of your source files from the `src` directory into the Docker image.
COPY src .
Now, one problem here: You probably already have your npm modules installed under src/node_modules. So, you can either ditch everything above except the final COPY line, or you can add src/node_modules to a .dockerignore file in your build root (../..).