Open In App

Docker ADD vs COPY Command in Dockerfile

Last Updated : 23 Dec, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

When creating Dockerfiles, it's often necessary to transfer files from the host system into the Docker image. These could be property files, native libraries, or other static content that our applications will require at runtime. The Dockerfile specification provides two ways to copy files from the source system into an image: the COPY and ADD directives. Here we will look at the difference between them and when it makes sense to use each one of them.

Sometimes you see COPY or ADD being used in a Dockerfile, but you should be using COPY 99% of the time. Here's why.

COPY and ADD are both Dockerfile instructions that serve a similar purpose. They let you copy files from a specific location into a Docker image.

Docker COPY Command

COPY takes in a source and destination. It only lets you copy a local directory from your host (the machine building the Docker image) into the Docker image itself.

COPY <src> <dest>

Explanation

  • <src> : the source path of the file or directory on your local machine.
  • <dest> : destination path inside the Docker image where you want the copied files or directories to be placed.

Note: If you are copying local files to your Docker image, always use COPY because it's more explicit.

Important Points

  • Basic Functionality: The 'COPY' command is used to copy files and directories from the host’s file system into the Docker image. It doesn’t support URLs or automatic extraction of compressed files.
  • Security: Since 'COPY' only handles local files, it is generally more secure and predictable than 'ADD', reducing the risk of unintentionally including files from external sources.
  • Use Case: 'COPY' is ideal for transferring files from the local build context to the Docker image without any additional processing.

Example

COPY ./config/settings.json /app/config/
COPY ./static /app/static/

In this example, 'settings.json' is copied to the '/app/config/' directory inside the image, and all files within the 'static' directory are copied to '/app/static/' .This setup allows you to arrange local files within specific directories inside the Docker image.

Docker ADD Command

ADD  does that same work like docker copy command but in addition, it also supports 2 other sources. 

  • A URL instead of a local file/directory.
  • Extract tar from the source directory into the destination.
ADD <src> <dest>

Explanation

  • <src>: This can be a local file/directory, a URL, or a tar file.
  • <dest>: This is the destination path in the Docker image where the files will be placed.

In most cases, if you're using a URL, you download a zip file and then use the RUN command to extract it. However, you might as well just use RUN  and curl instead of ADD  here, so you chain everything into 1 RUN command to make a smaller Docker image. A valid use case for ADD is when you want to extract a local tar file into a specific directory in your Docker image. This is exactly what the Alpine image does with ADD rootfs.tar.gz /. 

Important Points

While functionality is similar, the ADD directive is more powerful in two ways as follows:

  1. It can handle remote URLs
  2. It can also auto-extract tar files.

Let's look at these more closely.

First, the ADD directive can accept a remote URL for its source argument. The COPY directive, on the other hand, can only accept local files. 

Note: Using ADD to fetch remote files and copying is not typically ideal. This is because the file will increase the overall Docker Image size. Instead, we should use curl or wget to fetch remote files and remove them when no longer needed.

Second, the ADD directive will automatically expand tar files into the image file system. While this can reduce the number of Dockerfile steps required to build an image, it may not be desired in all cases.

Note: The auto-expansion only occurs when the source file is local to the host system.

Reasons to use COPY instead of ADD in Dockerfile

According to the Dockerfile best practices guide, we should always prefer COPY over ADD unless we specifically need one of the two additional features of ADD. As noted above, using ADD command automatically expands tar files and specific compressed formats, which can lead to unexpected files being written to the file system in our images.

Docker ADD vs COPY Command in Dockerfile

COPY COMMAND ADD COMMAND
COPY is a docker file command that copies files from a local source location to a destination in the Docker container.ADD command is used to copy files/directories into a Docker image.
Syntax: COPY <src> <dest>Syntax: ADD source destination
It only has only one assigned function.It can also copy files from a URL.
Its role is to duplicate files/directories in a specified location in their existing format.ADD command is used to download an external file and copy it to the wanted destination.
If we want to avoid backward compatibility, we should use the COPY command.ADD command is less usable than the COPY command.

Remote Context of Docker COPY and ADD Commands

While working with Docker, the COPY and ADD commands are both used to add files to an image, but they handle remote contexts in distinct ways. Here’s a breakdown of how each command works with remote files.

Remote Context of Docker COPY Command

  • Local Context Only: The COPY command is strictly limited to files and directories that are present in your local build context. This means you can only copy files that are located in the directory where you run the docker build command. It doesn’t allow for fetching files from remote URLs.
  • Use Cases: Because of this limitation, COPY is best used for including files that are part of your project or configuration files stored locally.
  • Best Practice: If you need to include files from a remote source, it's recommended to download them using curl or wget inside the Dockerfile before using COPY. This gives you more control over the process and helps manage security and image size.

Example

FROM alpine:latest

# Install curl to fetch remote files
RUN apk add --no-cache curl

# Download a file from a remote source
RUN curl -o /tmp/remote-file.txt https://example.com/remote-file.txt

# Copy the downloaded file to the final image
COPY /tmp/remote-file.txt /app/remote-file.txt

Remote Context of Docker ADD Command

  • Supports Remote URLs: The ADD command offers more flexibility by allowing you to specify a remote URL as the source. If you provide a URL, ADD will download the file directly into the Docker image.
  • Automatic Extraction: In addition, ADD can automatically unpack compressed files (like .tar or .zip) when they are included in the build context, a feature that COPY does not have.
  • Security Considerations: Although being able to download files directly with ADD is convenient, it also introduces some security risks. Remote files can change or disappear, and there’s a chance of inadvertently including harmful content in your image.

Example

FROM alpine:latest

# Download a file directly using ADD
ADD https://example.com/remote-file.txt /app/remote-file.txt

Key Points to Remember

  • Security Risks: Using ADD to download files from remote locations can lead to unexpected issues and security vulnerabilities. It’s usually safer to explicitly manage remote downloads with tools like curl or wget, and reserve COPY for files you know and trust.
  • Build Context Control: The COPY command gives you better control over which files are included in your image, ensuring everything comes from your local context. This leads to more consistency and predictability in your builds.
  • Use Cases: Use COPY for local files and directories to ensure a secure and predictable build process. Reserve ADD for cases where you need its special features, like fetching remote files or unpacking archives, while being mindful of the potential risks involved.

By understanding how these commands work with remote files, you can make better choices for managing your Docker images effectively.

Conclusion

Here we have seen the two primary ways to copy files into a Docker image: ADD and COPY. While functionally similar, the COPY directive is preferred for most cases. This is because the ADD directive provides additional functionality that should be used with caution and only when needed.


Next Article

Similar Reads