When writing a Dockerfile, you often need to bring files from your local machine into the Docker image. Docker provides two instructions for this purpose: COPY and ADD.
At first glance, these commands might seem interchangeable—but there are important differences. Understanding when and how to use each can help you write cleaner, faster, and more secure Dockerfiles.
In this blog post, we’ll break down the differences, use cases, and best practices for using COPY and ADD.
✅ Purpose of Each Command
| Command | Description |
|---|---|
COPY | Copies files/directories from the host to image. |
ADD | Does everything COPY does plus extra features like extracting tar files and fetching from URLs. |
🔍 COPY – Simple and Predictable
The COPY instruction simply copies files or folders from your build context (your local directory) into the Docker image.
📌 Syntax:
COPY <source> <destination>
✅ Example:
COPY ./app /usr/src/app
This will copy everything inside the ./app folder into /usr/src/app in the container.
✅ Best for: Straightforward file transfers where no unpacking or downloading is required.
🔍 ADD – Advanced and Flexible
The ADD instruction can do what COPY does—but it also:
- Automatically extracts local tar archives
- Can fetch remote files from a URL
📌 Syntax:
ADD <source> <destination>
✅ Example 1: Copying and extracting a tar file
ADD archive.tar.gz /app/
If archive.tar.gz is in your local context, Docker will automatically extract it into /app/.
✅ Example 2: Downloading from a URL
ADD https://example.com/file.txt /app/
This will download the file from the internet and place it into the image.
⚠️ Important:
COPYdoes not support URLs or automatic extraction.
🧠 Key Differences at a Glance
| Feature | COPY | ADD |
|---|---|---|
| Copy local files/folders | ✅ Yes | ✅ Yes |
Automatically extract .tar | ❌ No | ✅ Yes |
| Download from a URL | ❌ No | ✅ Yes |
| Simpler and more transparent | ✅ Yes | ❌ No |
🛡 Best Practices
- Prefer
COPY: It’s more explicit, easier to understand, and avoids surprises. - Use
ADDonly when you need:- Tarball auto-extraction
- Remote file downloads (although this is better handled by
curlorwgetin most cases)
✅ Good vs. Bad Example
✅ Recommended (with COPY):
COPY requirements.txt /app/
RUN pip install -r /app/requirements.txt
❌ Avoid (using ADD unnecessarily):
ADD requirements.txt /app/
Why? COPY is simpler and avoids unexpected behaviors like accidental unpacking.
✨ Pro Tip: Downloading Remote Files
Instead of using ADD to download a file, use RUN curl or RUN wget:
RUN curl -o /app/config.json https://example.com/config.json
This gives you better control and clearer Docker layer caching.
✅ Summary
| Use Case | Use COPY | Use ADD |
|---|---|---|
| Copying local files | ✅ | ✅ |
Extracting .tar files | ❌ | ✅ |
| Downloading from a remote URL | ❌ | ✅ (but better with curl) |
| Predictable and secure builds | ✅ | ❌ |
🚀 Final Thoughts
While COPY and ADD can both bring files into your Docker image, best practice is to use COPY unless you truly need ADD’s special features. Being precise in your Dockerfiles leads to better maintainability, performance, and security.