Multi-stage Docker: RUN wget vs ADD

2019-06-17 02:59发布

问题:

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?

回答1:

It does look like it: ADD is used for instance in the Katakoda "Creating optimized Docker Images using Multi-Stage Builds" example (for the first image, before the second stage.

With two steps, you can focus on minimizing the (42-max for aufs, hard-limit 127) layers in the second stage only.



标签: docker