In my dockerfile, I have my WORKDIR and I want to have it as a VOLUME, so that on the host I have a directory in /var/lib/docker/volumes/ where is the same content as in the WORKDIR.
How do I use the VOLUME Dockerfile command for this?
While you can mount a volume over the WORKDIR that you were using when building your image, the volume isn't available at build time. Volumes are only available for a container, not while building an image.
You can COPY files into the image to represent the content that will exist in the volume once a container is running, and use those temporary files to complete the building of the image. However, those exact files would be inaccessible once a volume is mounted in that location.
To have a directory from the host machine mounted inside a container, you would pass a -v parameter (you can do multiple -v params for different directories or for individual files) to the docker run command that starts the container:
docker run -v /var/lib/docker/volumes:/full/path/inside/container your_image_name
Related
How can I use a dockerfile to copy files from my host to the image at create time, and make these file available to the host machine when the container is created? I'm lost between 1) VOLUME=[..] in the Dockerfile 2) --volume in the run command 3) docker volume create
I tried creating a dockerfile to copy the files to the image. though if I run the container with the -v option, the target on the container seems to get cleared?? example:
FROM node:latest
WORKDIR /usr/src/myapp
COPY package*.json ./
RUN npm install
COPY index.js /usr/src/myapp/index.js
EXPOSE 8080
CMD [ "node", "/usr/src/myapp/index.js" ]
Running it without volume works great
docker run -p 8080:8080 --name Test test:latest
With volume however, it seems the target dir on the container is cleared (Error: Cannot find module '/usr/src/myapp/index.js')
docker run -p 8080:8080 -v /mynasvolume1/test:/usr/src/myapp --name Test test:latest
I know my alternative is to create a named volume on the host and include that as VOLUME in the Dockerfile. That is not my preference though as it doesn't allow me to select the volume location on my host machine (Synology NAS doesn't give me solutions to change the default location from /volume1/#docker/volumes to a location I can share or mount)
Yes it seems cleared, because mounting /mynasvolume1/test to /usr/src/myapp will show only files from /mynasvolume1/test and override the files you COPYed in you Dockerfile. It's unclear what you're trying to achieve, but try mounting to a specific directory like: /mynasvolume1/test:/usr/src/myapp/test
I am new to docker i want to mount current directory in container and run command.
USING DOCKER FILE
mount current directory in a folder eg files
EG:
FROM ubuntu As tuttt
VOLUME [ %cd% ]
ENTRYPOINT ["/bin/bash"]
RUN ls
Volumes are mounted when you run a container. Dockerfile is the definition of the steps to build an image. From the image you run a container.
You can build your image (remove the VOLUME declaration since it is not useful in your case) and then you run it with:
docker run -v <host_path>:<container_path> <image_tag>
What is the use of "VOLUME" or "RUN mkdir /m"?
Even if I do not specify any of these instructions in the Dockerfile, then also "docker run -v ${PWD}/m:/m" works.
Inside a Dockerfile, VOLUME marks a directory as a mount point for an external volume. Even if the docker run command doesn't mount an existing folder into that mount point, docker will create a named volume to hold the data.
RUN mkdir /m does what mkdir does on any Unix system. It makes a directory named m at the root of the filesystem.
docker run -v ... binds a host directory to a volume inside a container. It will work whether or not the mount point was declared as a volume in a Dockerfile, and it will also create the directory if it doesn't exist. So neither VOLUME or RUN mkdir are specifically necessary before using that command, though they may be helpful to communicate the intent to the user.
I tried to share data between the docker container and the host, for example by adding the parameter -v /Users/name/Desktop/Tutorials:/cntk/Tutorials to the docker run command, but I noticed that it also deletes all the files on the docker contained in /cntk/Tutorials.
My question is how to make the same link, but having instead all the files in /cntk/Tutorials copied to the host (at /Users/name/Desktop/Tutorials)
Thank you
Unfortunately that it is not possible, take a look here. That is because this is how mounting works in Linux.
It is not correct to say that the files were deleted. They are still present in the underlying image, but the act of mounting another directory at the same path has obscured them. They exist, but are not accessible in this condition.
One way you can accomplish this is by mounting a volume into your container at a different path, and then copying the container's files to that path. Something like this.
Mount a host volume using a different path than the one the container already has for the files you are interested in.
docker run -v /Users/name/Desktop/Tutorials:/cntk/Tutorials2 [...]
Now, execute a command that will copy the files already in the docker image, into the mounted volume from the outside host.
docker exec <container-id> cp -r /cntk/Tutorials /cntk/Tutorials2
The docker cp command allows you to copy files/folders on demand between host and the container:
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
docker cp ContainerName:/home/data.txt . <== copy from container to host
docker cp ./test.txt ContainerName:/test.txt <== copy from host to container
docker cp ContainerName:/test.txt ./test2.txt <== copy from container to host
For details run docker cp --help
when I run nodered with
docker run -v D:/mydir:/data
the content of /data is copied in my volume at first run, thats what I've expected.
If I make
docker run -v D:/mydir:/usr/src/node-red/node_modules nodered
Then the volume is empty
I was expecting to get the content of node_modules being copied in the volume at start time... what am I missing ?
I can illustrate that a little bit more :
docker run --rm -v d:/VM:/data nodered/node-red-docker ls /data
--> list files
docker run --rm ls /usr/src/node-red/node_modules
--> list content of node_modules
docker run --rm -v d:/VM:/usr/src/node-red/node_modules nodered/node-red-docker ls /usr/src/node-red/node_modules
--> is empty !
You're mounting host directories as volumes, so there isn't any copying going on - the mount path inside the container is being mapped to the path on the host, so you're seeing the contents of the host directory.
Volumes sit outside the Union File System when you mount them, so you don't get an overlay which merges the contents of the image and the contents of the host directory. Instead you're effectively bypassing the contents of the image for that volume, and repointing it to your host.
Samples:
touch /docker/nodered-modules/sample.txt
docker run --rm -v /docker/nodered-modules:/usr/src/node-red/node_modules nodered/node-red-docker ls /usr/src/node-red/node_modules
sample.txt
touch /docker/nodered-data/sample.txt
docker run --rm -v /docker/nodered-data:/data nodered/node-red-docker ls /data
sample.txt
The reason you're seeing a difference is because the /data volume is defined in the Dockerfile and empty in the image, so you see the contents of your host directory as expected. The modules directory isn't empty in the image, but you're repointing it to an empty directory on your host.
Docker does not support copying data from the base image into host directories that are mounted as container volumes.