Reputation: 1476
Host OS: Linux
Container OS: Linux
I'm trying to learn how to use docker. I use docker-compose and I'm successfully building images and running containers.
Now if I want to mount some directory inside the container the documentation says that I should use the COPY command inside Dockerfile.
COPY /path/to/my/addons/ /path/to/directory/inside/container
Sadly when I compose this container the COPY command is ignored and my stuff from /path/to/my/addons doesn't make it to the container.
I've also tried with ADD command, but same problem.
Upvotes: 2
Views: 1817
Reputation: 986
Take your addon folder to location where your Dockerfile is and then run
mkdir -p /path/to/directory/inside/container
COPY ./addons/* /path/to/directory/inside/container
Upvotes: 0
Reputation: 17879
First, you can't use absolute paths for COPY
. All paths must be inside the context of the build, which means relative to the Dockerfile
. If the folder structure on your host is like this
my-docker-directory
-- Dockerfile
-- docker-compose.yml
-- addons
then you're able to use COPY addons /path/to/directory/inside/container
. For all subsequent explanations, I assume that you have an addons
folder relative to the Dockerfile
.
COPY
doesn't simply mount a folder to the container at runtime. It doesn't really mount the directory at all. Instead, addons
is copied to /path/to/directory/inside/container
inside the image. It's important to understand, that this process happens unidirectional (host > image) and only happens when the image is build.
COPY
is designed to add dependencies to the image that were required during buildtime like source code that got compiled to binaries. That's the reason why you can't absolute paths. A Dockerfile
usually is placed together with source code/config files at the top level area.
The build process of an image happens only on the first run, except you force it using docker-compose up --build
. But it doesn't seem that this is what you want. To mount a directory from the host at runtime, use a volume
in the docker-compose
file:
version: '3'
services:
test:
build: .
volumes:
- ./addons/:/path/to/directory/inside/container
COPY
and when volumes?It's important to realize that COPY
and ADD
will copy the stuff into the image at buildtime, where volumes
mount them from the host at runtume (without including them in the image). So you usually copy general things to the image, that the users needs like default configuration files.
Volumes are required to include files from the host like customized configuration files. Or persistent things as the data-directory of a database. Without volumes those containers work, but are not persistent. So all content would get lost when the container restarts.
Please note that one doesn't exclude the other. It's fine to COPY
a default configuration for some application in the image, where the user may override this with volumes to modify them. Especially during development this can make things easier because you don't have to rebuild the entire image for a single changed config file*
* Altough it's a good practice to optimize Dockerfiles for the integrated caching mechanism. If a Dockerfile
is well written, rebuilding small config changes often doesn't take too long. But that's another topic out of this scope.
COPY
in Dockerfile
As simple example, we create a Dockerfile
from the nginx webserver image and copy html in it
FROM nginx:alpine
COPY my-html /usr/share/nginx/html
Lets create the folder with demo content
mkdir my-html
echo "Dockerfile content" > my-html/index.html
and add a minimalistic docker-compose.yml
version: '3'
services:
test:
build: .
If we run it for the first time using docker-compose up -d
, the image got build and our test page is served:
root@server2:~/docker-so-example# docker-compose up -d
Creating network "docker-so-example_default" with the default driver
Creating docker-so-example_test_1 ... done
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
Dockerfile content
Let's manipulate our testfile:
echo "NEW Modified content" > my-html/index.html
If we request our server with curl
again, we get the old response:
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
Dockerfile content
To apply our content, a rebuild is required:
docker-compose down && docker-compose up -d --build
Now we can see our changes:
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
NEW Modified content
docker-compose
To show the difference, we use volumes by modifing our docker-compose.yml
file like this:
version: '3'
services:
test:
build: .
volumes:
- ./my-html:/usr/share/nginx/html
Now restart the containers using docker-compose down && docker-compose up -d
and try it again:
root@server2:~/docker-so-example# echo "Again changed content" > my-html/index.html
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
NEW Modified content
root@server2:~/docker-so-example# echo "Some content" > my-html/index.html
root@server2:~/docker-so-example# curl $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-so-example_test_1)
Some content
Notice that we didn't re-build the image and our modifications apply immediately. Using volumes, the files are not included in the image.
Upvotes: 6
Reputation: 2823
COPY command inside a docker file copies the content to the image while building. mounting a volume is a different thing. for mounting you need to use
docker run -v <volume_name>:<volume_name> ...
what exactly you want to achieve ? Do you want to see the folders inside containers in your host ?
Upvotes: 0