The best practices section of the Docker docs says this:
Because image size matters, using ADD to fetch packages from remote URLs is strongly discouraged; you should use curl or wget instead. That way you can delete the files you no longer need after they’ve been extracted and you won’t have to add another layer in your image. For example, you should avoid doing things like:
ADD http://example.com/big.tar.xz /usr/src/things/ RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things RUN make -C /usr/src/things all
And instead, do something like:
RUN mkdir -p /usr/src/things \ && curl -SL http://example.com/big.tar.xz \ | tar -xJC /usr/src/things \ && make -C /usr/src/things all
On the other hand, later on it notes:
Prior to Docker 17.05, and even more, prior to Docker 1.10, it was important to minimize the number of layers in your image. [...] Docker 17.05 and higher add support for multi-stage builds, which allow you to copy only the artifacts you need into the final image.
and even
compress[ing] two RUN commands together using the Bash && operator [is] failure-prone and hard to maintain.
It seems to me that if you are using multi-stage builds, the advice about ADD
is inaccurate. The extra layers are unlikely to be a problem unless you are downloading something truly huge, as local disk space is cheap and it's easy to clean out old images. Indeed, when coding one doesn't usually have build commands clean their intermediate artefacts to save space!
In addition, ADD
has a major advantage over RUN wget
: it detects when its target has changed.
Am I missing something, or do multi-stage builds rehabilitate ADD
?