Reputation: 150654
Supposed I have a Docker container and a folder on my host /hostFolder
. Now if I want to add this folder to the Docker container as a volume, then I can do this either by using ADD
in the Dockerfile
or mounting it as a volume.
So far, so good.
Now /hostFolder
contains a sub-folder, /hostFolder/subFolder
.
I want to mount /hostFolder
into the Docker container (whether as read-write or read-only does not matter, works both for me), but I do NOT want to have it included /hostFolder/subFolder
. I want to exclude this, and I also want the Docker container be able to make changes to this sub-folder, without the consequence of having it changed on the host as well.
Is this possible? If so, how?
Upvotes: 418
Views: 218566
Reputation: 71
Docker recently added watch. It allows for directories to be ignored or excluded.
Say you wanted to exclude node_modules
directory, you'd do:
services:
web:
build: .
command: npm start
develop:
watch:
- action: sync
path: ./web
target: /src/web
ignore:
- node_modules/
- action: rebuild
path: package.json
Then start the container with:
docker compose watch
You can read more about it in the docs
Upvotes: 7
Reputation: 89
For a file, an env file specifically, that must exist inside the project, I used this solution:
volumes:
- ./empty.env:/app/.env
Where "empty.env" is just an empty file. It helped me to use the same branch in different environments, inside and outside the container.
Upvotes: -1
Reputation: 21
This works for me Manjaro Linux, Docker Compose yml has v2.4 at the top since thats the last non-swarm version. I want to make sure that my snapshots folder on my host is excluded in the docker container. I do not have volumes section in my docker-compose, keeping it simple:
version: "2.4"
services:
filerun:
volumes:
- $DATAPOOL/users:/user-files
- /user-files/snapshots/
On my host, the folder users/snapshots remains untouched. Within the container, the folder user-files/snapshots is just an empty folder.
Upvotes: 2
Reputation: 49
I found this link which saved me: Working with docker bind mounts and node_modules.
This working solution will create a "exclude" named volume in docker volumes manager. The volume name "exclude" is arbitrary, so you can use a custom name for the volume intead exclude.
services:
node:
command: nodemon index.js
volumes:
- ./:/usr/local/app/
# the volume above prevents our host system's node_modules to be mounted
- exclude:/usr/local/app/node_modules/
volumes:
exclude:
You can see more infos about volumes in Official docs - Use a volume with docker compose
Upvotes: 4
Reputation: 561
For those trying to get a nice workflow going where node_modules
isn't overridden by local this might help.
services:
server:
build: .
volumes:
- .:/app
- /app/node_modules
docker-compose -V
. Without this if you added a new package and rebuilt your image it would be using the node_modules
from your initial docker-compose launch. -V, --renew-anon-volumes Recreate anonymous volumes instead of retrieving
data from the previous containers.
Upvotes: 56
Reputation: 19
To exclude a mounted file contained in the volume of your machine, you will have to overwrite it by allocating a volume to this same file. In your config file:
services:
server:
build : ./Dockerfile
volumes:
- .:/app
An example in you dockerfile:
# Image Location
FROM node:13.12.0-buster
VOLUME /app/you_overwrite_file
Upvotes: -1
Reputation: 161
for the people who also had the issue that the node_modules folder would still overwrite from your local system and the other way around
volumes:
node_modules:
services:
server:
volumes:
- .:/app
- node_modules:/app/node_modules/
This is the solution, With the trailing /
after the node_modules being the fix.
Upvotes: 16
Reputation: 24110
With the docker command line:
docker run \
--mount type=bind,src=/hostFolder,dst=/containerFolder \
--mount type=volume,dst=/containerFolder/subFolder \
...other-args...
The -v
option may also be used (credit to Bogdan Mart), but --mount
is clearer and recommended.
Upvotes: 24
Reputation: 81
Looks like the old solution doesn't work anymore(at least for me). Creating an empty folder and mapping target folder to it helped though.
volumes:
- ./angularApp:/opt/app
- .empty:/opt/app/node_modules/
Upvotes: 8
Reputation: 1826
To exclude a file, use the following
volumes:
- /hostFolder:/folder
- /dev/null:/folder/fileToBeExcluded
Upvotes: 30
Reputation: 2908
If you want to have subdirectories ignored by docker-compose but persistent, you can do the following in docker-compose.yml
:
volumes:
node_modules:
services:
server:
volumes:
- .:/app
- node_modules:/app/node_modules
This will mount your current directory as a shared volume, but mount a persistent docker volume in place of your local node_modules
directory. This is similar to the answer by @kernix, but this will allow node_modules
to persist between docker-compose up
runs, which is likely the desired behavior.
Upvotes: 202
Reputation: 8490
Using docker-compose I'm able to use node_modules locally, but ignore it in the docker container using the following syntax in the docker-compose.yml
volumes:
- './angularApp:/opt/app'
- /opt/app/node_modules/
So everything in ./angularApp
is mapped to /opt/app
and then I create another mount volume /opt/app/node_modules/
which is now empty directory - even if in my local machine ./angularApp/node_modules
is not empty.
Upvotes: 658
Reputation: 46500
First, using the ADD
instruction in a Dockerfile is very different from using a volume (either via the -v
argument to docker run
or the VOLUME
instruction in a Dockerfile). The ADD
and COPY
commands just take a copy of the files at the time docker build
is run. These files are not updated until a fresh image is created with the docker build
command. By contrast, using a volume is essentially saying "this directory should not be stored in the container image; instead use a directory on the host"; whenever a file inside a volume is changed, both the host and container will see it immediately.
I don't believe you can achieve what you want using volumes, you'll have to rethink your directory structure if you want to do this.
However, it's quite simple to achieve using COPY
(which should be preferred to ADD
). You can either use a .dockerignore
file to exclude the subdirectory, or you could COPY
all the files then do a RUN rm bla
to remove the subdirectory.
Remember that any files you add to image with COPY
or ADD
must be inside the build context i.e. in or below the directory you run docker build
from.
Upvotes: 14