What are the best practices for using ADD and COPY instructions in Docker?
sobes.tech AI
Answer from AI
There are several best practices for ADD and COPY instructions in Docker aimed at improving security, transparency, and build efficiency.
The main difference between ADD and COPY:
COPYsimply copies files and directories from the specified source on the host to the specified destination in the container. The source must be a local file or directory.ADDhas broader capabilities: it can copy local files and directories, as well as extract archives (tar, gzip, bzip2) and fetch files from URLs.
Best practices:
-
Prefer
COPYoverADD: In most cases,COPYis sufficient. It is more transparent as it simply copies local files. UsingADDfor extracting archives or downloading from URLs can be less predictable and increase build complexity. -
Use
COPYfor local files: If you need to copy files from the build context into the image, always useCOPY.# Instead of ADD . /app COPY . /app -
Be cautious with URLs in
ADD: UsingADDwith URLs can lead to build instability if the remote resource is unavailable. It can also be less secure as it depends on external sources. Prefer usingcurlorwgetin a separate layer (RUN) to download resources from URLs, which provides more control and allows checksum verification.# Instead of ADD http://example.com/file.tar.gz /tmp/ RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* \ && curl -fsSL http://example.com/file.tar.gz -o /tmp/file.tar.gz \ && tar -xzf /tmp/file.tar.gz -C /app \ && rm /tmp/file.tar.gz -
Extract archives in a separate layer when using
ADD: If you must useADDto extract an archive (less common scenario), ensure you do it in a separate layer. However, as mentioned earlier, more explicit extraction usingRUNis often preferable. -
Copy only necessary files: Do not copy the entire build context (
COPY . /app) if it contains unnecessary files (source code, test data, hidden directories, etc.). Use.dockerignoreto exclude these files. This reduces image size and speeds up build by decreasing data transferred to the Docker daemon.Example
.dockerignore:.git node_modules *.log tmp/# Copy only necessary files after applying .dockerignore COPY . /app -
Use absolute paths for destinations: Always specify absolute destination paths in the image (/app, /usr/local/bin, etc.). This makes the Dockerfile more understandable and predictable, avoiding ambiguity regarding the current working directory (
WORKDIR).# Always specify absolute destination paths COPY src /app/src -
Vary the order based on change frequency: Place
COPYorADDinstructions for files that change less frequently (e.g., dependency files likepackage.json,requirements.txt) higher in the Dockerfile than instructions for files that change more often (application source code). This allows Docker to efficiently use layer caching.# Dependency files (change less often) COPY requirements.txt /app/ RUN pip install --no-cache-dir -r requirements.txt # Application source code (change more often) COPY . /app/
Summary table:
| Instruction | Description | Recommended use | What to avoid |
|---|---|---|---|
COPY |
Copies local files/directories | Copying local files and directories into the image. | Using it when you need to extract archives or download from URLs. |
ADD |
Copies local files/directories, extracts archives, downloads from URL | Use for automatic archive extraction (rare). | Using it for copying local files (prefer COPY). Using it for URL downloads. |
Following these practices results in more reliable, secure, and efficient Docker images.