ADD Instruction Reference
Copy files, directories, or remote files to the container's filesystem
Syntax
The ADD instruction copies new files, directories, or remote file URLs from <src> and adds them to the filesystem of the image at the path <dest>.
The ADD instruction is similar to COPY but with additional features. It can copy files and directories from the build context to the image, like COPY, but it also has special handling for URLs and tar files.
ADD has these key capabilities that differentiate it from COPY:
- It can download files from remote URLs
- It automatically extracts local tar files into the destination directory
- It handles compressed archive formats (gzip, bzip2, xz) automatically
Description
The ADD instruction copies new files, directories, or remote file URLs from <src> and adds them to the filesystem of the image at the path <dest>.
Multiple <src> resources can be specified, and each will be interpreted relative to the source of the context of the build. For example:
ADD hom* /mydir/ # adds all files starting with "hom"
ADD hom?.txt /mydir/ # ? is replaced with any single character
ADD test.txt /absoluteDir/
ADD test.txt relativeDir/
All new files and directories are created with a UID and GID of 0, unless the optional --chown flag specifies a given username, groupname, or UID/GID combination.
The <src> path must be inside the context of the build. For example, you cannot ADD ../something /something, because the first step of a docker build is to send the context directory (and subdirectories) to the docker daemon.
If <src> is a URL and <dest> does not end with a trailing slash, then a file is downloaded from the URL and copied to <dest>. If <dest> ends with a trailing slash, then the filename is inferred from the URL and the file is downloaded to <dest>/<filename>.
If <src> is a local tar archive in a recognized compression format (identity, gzip, bzip2 or xz), it will be unpacked as a directory. When a directory is copied or unpacked, it has the same behavior as tar -x
, the result is the union of:
- Whatever existed at the destination path
- The contents of the source tree, with conflicts resolved in favor of "2." on a file-by-file basis
If <src> is any other kind of file, it is copied individually along with its metadata. In this case, if <dest> ends with a trailing slash /, it will be considered a directory and the contents of <src> will be written at <dest>/base(<src>).
If multiple <src> resources are specified, either directly or due to the use of a wildcard, then <dest> must be a directory, and it must end with a slash /.
Examples
Basic Usage
Copy a single file from your build context to a directory in the image:
FROM alpine:3.14
WORKDIR /app
ADD config.json .
This copies config.json from the build context to /app/config.json in the image.
Copying Directories
Copy an entire directory and its contents:
FROM node:18-alpine
WORKDIR /app
ADD src/ ./src/
This copies the src directory and all its contents to /app/src/ in the image.
Using Wildcards
Copy multiple files using wildcards:
FROM python:3.9-slim
WORKDIR /app
ADD config*.json ./config/
This copies all files starting with "config" and ending with ".json" to the /app/config/ directory.
Downloading Remote Files
Download a file from a URL:
FROM ubuntu:20.04
WORKDIR /app
ADD https://example.com/file.tar.gz .
This downloads file.tar.gz from example.com and saves it to /app/file.tar.gz (it won't be automatically extracted).
Downloading with Checksum Verification
Download a file and verify its integrity:
FROM ubuntu:20.04
WORKDIR /app
ADD --checksum=sha256:24454f830cdb571e2c4ad15481119c43b3cafd48dd869a9b2945d1036d1361ff https://example.com/file.txt .
This downloads file.txt and verifies its SHA256 checksum matches the provided value.
Extracting Archives
Automatically extract a local tar file:
FROM ubuntu:20.04
WORKDIR /app
ADD app.tar.gz .
This extracts the contents of app.tar.gz into the /app directory.
Setting Ownership
Copy files and set their ownership:
FROM ubuntu:20.04
RUN groupadd -r app && useradd -r -g app app
WORKDIR /app
ADD --chown=app:app files/ .
This copies all files from the files/ directory and sets their ownership to the app user and group.
Setting Permissions
Copy a file and set specific permissions:
FROM alpine:3.14
WORKDIR /app
ADD --chmod=755 entrypoint.sh .
This copies entrypoint.sh to /app and sets its permissions to 755 (executable).
ADD vs COPY
Docker provides two instructions for copying files into an image: ADD and COPY. While they might seem similar, they have important differences:
ADD | COPY |
---|---|
Can copy local files and directories | Can copy local files and directories |
Can download files from remote URLs | Cannot download from URLs |
Automatically extracts local tar archives | Does not extract archives |
More complex behavior with special cases | Simpler, more predictable behavior |
Less preferred for simple file copying | Recommended for simple file copying |
The Docker documentation recommends using COPY for simple file copying and reserving ADD for the special cases where its additional features are needed, such as:
- When you need to download a file from a URL
- When you need to automatically extract a local tar file
This recommendation is based on the principle that an instruction should have clear, predictable behavior. Since ADD does different things depending on the input, it can sometimes lead to unexpected results.
Best Practices
- Use COPY instead of ADD for simple file copying. Use ADD only when you need its tar extraction or remote URL features.
- Be specific with what you add. Avoid using ADD . . as it copies everything in your build context, which can make your image unnecessarily large.
- Place ADD instructions after installing dependencies to take advantage of Docker's build cache. Files that change frequently should be added later in the Dockerfile.
- Use .dockerignore to exclude files and directories that shouldn't be added into your image.
- For remote URLs with ADD, use --checksum to verify the integrity of downloaded files.
- Consider using COPY + RUN instead of ADD for more control over archive extraction.
- Consider using multi-stage builds to minimize the final image size.
- Consider security implications when adding remote files. Verify checksums to ensure file integrity.
- Set appropriate permissions on added files, especially executable scripts, using --chmod.
- Consider using non-root users with --chown for better security.
Notes and Limitations
- The ADD instruction creates a new layer in your Docker image.
- ADD honors .dockerignore, which can be used to exclude files and directories from being copied.
- Remote URLs can only be downloaded to individual files, not directories.
- If a remote file has an HTTP Last-Modified header, it will be used to set the mtime of the file. Otherwise, the mtime will be the layer creation time.
- Files downloaded from remote URLs have a permission of 600 by default (user read and write only).
- ADD does not support authentication for remote URLs. If you need to download files from authenticated sources, consider using RUN with curl or wget instead.
- The --chown feature only works on Linux containers, not Windows.
- You cannot ADD files from outside the build context.
- The checksum verification (--checksum) only works with remote URLs, not local files.
- If you're using a Windows container, the destination paths should use Windows-style backslashes, but they'll be converted to forward slashes in the Dockerfile.
- Automatic extraction only works with local tar files, not remote ones.
- ADD triggers a file modification check from source, so if the file has changed since the last build, it will invalidate the cache and force a rebuild of that layer and all subsequent layers.