Transferring files from host to container image is typical while creating container images, thus we have two options for moving files or directories to the container. However, while both options may provide the same outcome, the ADD command has a different use.
If you haven't already, I strongly suggest you read the previous post about Docker build and push:
I'll use examples to demonstrate how the COPY command works. We often utilize copy for source code, assets, settings, and so forth...
The following example uses COPY in three ways:
FROM alpine:3.17 as base WORKDIR /app FROM ubuntu:22.10 as super_secret RUN echo "you_should_not_use_secrets_here" > /secret.txt FROM base as app COPY --from=super_secret /secret.txt /app/secret.txt COPY ./assets/hello.txt /app/hello.txt COPY ./tools /app RUN chmod +x /app/info.sh ENTRYPOINT ["/app/info.sh"]
- COPY --from=super_secret /secret.txt /app/secret.txt, copy file from a stage called super_secret;
- COPY ./assets/hello.txt /app/hello.txt, copy the file from the host to the container;
- COPY ./tools /app, copy the directory from the host to the container;
That covers our discussion of the most common COPY applications.
Although the ADD command behaves similarly to the COPY command in that it copies files, ADD has been developed to copy from local (host) or remote files (http) to the container image; if this file has been compressed (tar.gz), the content will be extracted and copied to the destination directory.
The following is an example of a Dockerfile that copies a compressed file and extracts it to the destination directory:
FROM alpine:3.17 WORKDIR /app ADD ./assets/tools.tar.gz /app RUN chmod +x /app/assets.sh ENTRYPOINT ["/app/assets.sh"]
Following that, we have a Dockerfile containing a remote file that will be extracted to the target directory:
FROM alpine:3.17 WORKDIR /app ADD https://github.com/williampsena/docker-recipes/raw/main/build/samples/assets/tools.tar.gz /app RUN tar -xf tools.tar.gz RUN chmod +x /app/assets.sh ENTRYPOINT ["/app/assets.sh"]
Two builds will generate the identical files, but the first will use the host path and the second will use the remote path. The file tools.tar.gz will be present in the container using ADD remote example, which you should delete using the RUN command to save up space.
COPY --chown foo:foo --chmod 644 ./assets /assets ADD --chown foo:foo --chmod 644 ./assets/foo.tar.gz /assets
- As previously stated, ADD and COPY achieve the same result when transferring files, although Docker advises using COPY rather than ADD.
- Because image size matters, Docker recommends avoiding using ADD to download packages from remote URLs; instead, use curl or wget. That way, when the files have been extracted, you may remove them and avoid having to add another layer to your image. You should, for example, avoid doing the following:
# curl RUN mkdir -p /tmp/assets && \ curl -SL https://github.com/williampsena/docker-recipes/raw/main/build/samples/assets/tools.tar.gz | tar xvfz - -C /tmp/assets # wget RUN mkdir -p /tmp/assets && \ wget -qO- https://github.com/williampsena/docker-recipes/raw/main/build/samples/assets/tools.tar.gz | tar xvfz - -C /tmp/assets
⚠️ The Dockerfiles recipes and assets might be found on my Github repository.
With practical build samples, we learned the difference between COPY and AND today. I'll go through additional Docker instructions in future blogs.
Keep your 🧠 kernel up to date. God bless 🙏🏿 you.