Docker Community Forums

Share and learn in the Docker community.

.dockerignore in multi-stage builds


(Steffenburger) #1

Hi,

my task is to build the Single-Page-Application (Stage 1) and then serve it with NGNIX (Stage 2)

FROM node:8.11.4-alpine AS build
WORKDIR /usr/local/app
COPY . .
RUN npm install
RUN npm run build

FROM nginx:1.15.2-alpine
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY nginx/conf.d/default.conf /etc/nginx/conf.d/
COPY --from=build /usr/local/app/dist/MY-APP /usr/share/nginx/html

In Stage 1 I copy all the src files into the build container. To improve this process I created a .dockerignore (as it is suggested in the docs). For the build I obviously do not need the nginx files. Therefore they are part of the .dockerignore.

dist
e2e
nginx
node_modules
.editorconfig
.gitignore
npm-debug.log
README.md
tslint.json

The problem - as soon as the Stage 2 begins, the ngnix entry in the .dockerignore file prevents that the ngnix files can be copied! So the only working solution so far is to remove ngnix from the .dockerignore and therefore copy it into without any need the build container (Stage 1). This is not how it should be!

Feature request - provide a better multi-stage .dockerignore support.
There are probably several solution designs possible.
My personal solution idea would be a “block definition” in .dockerignore similar to the one used in the Dockerfile (here it is separated by the ‘FROM’ keyword)

So, what is your opinion to this guys?
Any other solutions or thoughts?


(Staffan Eketorp) #2

I totally agree. For me this currently makes multi stage builds useless. Surprised this hasn’t caught more attention. I mean in the typical setup you have one or more builder stages and one runner stage and they typically need quite different .dockerignore contexts to make them snappy and and cacheable. Or am I missing something?


(Robmcdan) #3

+1, I have some larger test files that I don’t want in the build context unless I’m targeting the test stage

It would be OK if I had to have sections of the .dockerignore match the names or orders of stages in the dockerfile.


#4

A similar issue here, have 2 jobs, one uses Dockerfile.One and the other uses Dockerfile.Two. Now for e.g out of A & B & C files I need the A & B added through the 1st job & B & C through the 2nd job. The issue is that C is a huge doc and is included in the .dockerignore and won’t be used when building the B & C case.

How can I tell it to ignore the .dockerignore rule for only this specific time?


(Raj Chaudhuri) #5

A multi-stage build is still a single build. As such, it begins by copying your entire build context directory (minus what is excluded via .dockerignore) from the client where you invoke the build command, to the server where the build actually happens.

This does not mean that every file in the build context directory gets copied to every build stage. In your example, your nginx files will not affect the first stage at all.

The purpose of the .dockerignore file is not to make the build containers or the resulting image “snappier”. It is just to prevent files from being copied to the server in the first step.