Reputation: 10226
I have a directory structure like this:
app/
inc/
www/
where inc/
contains code that is common to app and www. to create an image for app I do:
cd app
docker build .
so the context for the build are the contents of app/
. of course, the code in inc/
will be missing from the app and it breaks
googling I've read suggestions that I should:
docker build -f app/Dockerfile .
which includes inc/
(good) but also includes everything else (bad) e.g. www
to solve the problem I would have to build a script that copies the contents of inc/
into app/
, performs the build and the deletes app/inc/
. but that's messy and, actually, I can't do it because I want docker-compose to do my builds.
what is the recommended way to manage this?
Upvotes: 2
Views: 2912
Reputation: 1323203
but also includes everything else (bad) e.g. www
That is where a .dockerignore
file can come in handy: declare www/
in it.
Before the docker CLI sends the context to the docker daemon, it looks for a file named
.dockerignore
in the root directory of the context.
If this file exists, the CLI modifies the context to exclude files and directories that match patterns in it.This helps to avoid unnecessarily sending large or sensitive files and directories to the daemon and potentially adding them to images using
ADD
orCOPY
.
Wrapping docker build or docker compose to generate the right .dockerignore
would be ideal for now.
Ultimately, each build should be able to specify its own dockerignore
file.
See issue 12886.
However:
This feature was put on hold, pending other changes that are being researched/worked on; one of those is making the builder "smarter" when sending the build context; see #31829.
Update august 2019, two years later: issue 12886 (Add support for specifying .dockerignore
file with -i/--ignore
), opened in 2015, is about to be closed with Docker 19.03:
Tõnis Tiigi mentions:
I think we can close this as the use-cases have been addressed in 19.03 and there is a lot of outdated/incorrect advice in here that may confuse new readers.
This has been addressed by three features:
- #12886 (comment) allows setting a dockerignore file per Dockerfile if the repository contains many. (Note that this was the exact description for the initial issue)
- BuildKit automatically ignores files that are not used, automatically removing the problem where different sets of files needed to ignore each other.
- The cases where same Dockerfile uses different sets of files for different "modes" of build (eg. dev vs prod) can be achieved with multi-stage builds and defining the mode changes with build arguments.
This is not the same syntax originally requested in here because that version is incompatible with stability guarantees users expect from Dockerfiles. The provided solutions solve the problems for the users who need better control for ignored files, without adding new ones to the others.
So:
" load
<dockerfile-name>.dockerignore
first and then fall back to.dockerignore
if it can't be found" has landed in the test distribution of Docker (19.03.0-beta1)You need to enable BuildKit mode to use it, example:
$ export DOCKER_BUILDKIT=1
$ echo "FROM ubuntu \n COPY . tmp/" > Dockerfile
$ cp Dockerfile Dockerfile2
$ touch foo bar
$ echo "foo" > .dockerignore
$ echo "bar" > Dockerfile2.dockerignore
$ docker build -t container1 -f Dockerfile .
$ docker build -t container2 -f Dockerfile2 .
$ docker run container1 ls tmp
Dockerfile
Dockerfile2
Dockerfile2.dockerignore
bar
$ docker run container2 ls tmp
Dockerfile
Dockerfile2
Dockerfile2.dockerignore
foo
Upvotes: 1