Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Copy Files to and from Containers

Master transferring files between your host machine and Docker containers using `docker cp`. This lesson covers the core concept, step-by-step walkthrough, and common edge cases, including handling running vs. stopped containers and directory targets.

Focus: copy files to and from containers

Sponsored

You’ve mastered building images, running containers, and even mounting volumes — but what happens when you need to sneak a config file into a running container without rebuilding the whole image? Or grab a log file from a container that’s about to crash. The docker cp command is your direct file-transfer bridge between the host machine and any container, running or stopped. This lesson shows you how to copy files to and from containers with confidence, avoiding the common pitfalls that trip up even seasoned Docker users.

The problem this lesson solves

Docker containers are isolated by design — their filesystem is separate from the host. This isolation is great for security and reproducibility, but it creates a practical headache: how do you get a file into a container without rebuilding its image? And how do you pull a file out of a container (like a log or export) without exec’ing into a shell and piping over the network?

Mounting a volume at container start is the cleanest long-term solution, but it’s not always an option. Maybe the container is already running, or you only need a one-time transfer. docker cp fills this gap: it treats the container’s filesystem like a remote drive, letting you copy files and directories in either direction using a single, simple command.

Core concept / mental model

Think of docker cp as a cross-filesystem cp command — but instead of copying between two host paths, one side is a container path. The container is identified by its name or ID, followed by a colon (:) and the absolute path inside the container.

docker cp <source> <target>
  • Host to container: docker cp /host/file.txt container_name:/path/in/container/
  • Container to host: docker cp container_name:/path/in/container/file.txt /host/destination/

Important: The container does not need to be running. docker cp works with stopped containers too, because it reads the container’s filesystem metadata from the Docker overlay layers.

How it works step by step

Let’s walk through the exact sequence Docker follows when you run docker cp:

  1. Resolve the container: Docker looks up the container name or ID in its metadata (running or stopped).
  2. Access the container’s root filesystem: For running containers, Docker accesses the union filesystem (overlay2). For stopped containers, it reads the committed layers.
  3. Perform the copy: Docker uses its internal file copier — optimized for container paths — to transfer the file or directory. It does not use the container’s own cp command or shell.
  4. Preserve metadata by default: docker cp tries to preserve ownership, permissions, and (for files) timestamps. This behavior can be overridden with the --archive (-a) flag (which is on by default).

Pro tip: Because docker cp works at the Docker daemon level, it can copy files even if the container has no shell or basic utilities like bash or tar installed.

Hands-on walkthrough

Let’s get practical. You’ll create a simple container, copy files in both directions, and verify the result.

1. Create a sample container

# Start an Alpine container in the background
docker run -d --name cp-demo alpine:latest sleep 3600

2. Copy a file from host to container

# Create a text file on the host
echo "Hello from host" > host-greeting.txt

# Copy it into the container's /tmp directory
docker cp host-greeting.txt cp-demo:/tmp/

# Verify the file is inside the container
docker exec cp-demo cat /tmp/host-greeting.txt
# Output: Hello from host

3. Copy a file from container to host

# Create a file inside the container
docker exec cp-demo sh -c "echo 'Greetings from container' > /tmp/container-file.txt"

# Copy it to the host
docker cp cp-demo:/tmp/container-file.txt ./

# Check the local copy
cat container-file.txt
# Output: Greetings from container

4. Copy a directory recursively

# Create a directory with nested files inside the container
docker exec cp-demo mkdir -p /app/data
docker exec cp-demo sh -c "echo 'nested' > /app/data/info.txt"

# Copy the whole directory to the host
docker cp cp-demo:/app/data ./container-data

# List the copied directory
ls -R container-data/
# Output: container-data/:
# info.txt

5. Copy to a stopped container

# Stop the container
docker stop cp-demo

# Copy a config file into the stopped container
echo "config=production" > app.conf
docker cp app.conf cp-demo:/app/config/

# Start and verify
docker start cp-demo
docker exec cp-demo cat /app/config/app.conf
# Output: config=production

Compare options / when to choose what

Method Use case Pros Cons
docker cp One-time file transfer Simple, works on stopped containers, no shell needed No auto-sync, manual per transfer
Volume mount (-v) Persistent shared data Auto-sync, survives container restart Must be set up at container start
docker exec + pipe Ad-hoc files when cp fails Works even without cp inside container Requires shell, more complex
scp/rsync over SSH Remote hosts Encryption, resumable transfers Requires SSH inside container

When to use docker cp: Quick debugging (copy out logs), injecting configs into running containers, extracting artifacts from a stopped build container. When not to: For production data that needs persistence — use volumes instead.

Troubleshooting & edge cases

"No such container" error

docker cp missing-container:/tmp/file .
# Error: Error response from daemon: No such container: missing-container

Fix: Check the container is running or stopped with docker ps -a. The container name must match exactly.

Path not found inside container

docker cp demo:/nonexistent/path .
# Error: Error response from daemon: Could not find the file /nonexistent/path in container

Fix: Use docker exec with ls or test -e to verify the path exists before copying.

Copying symbolilc links

By default, docker cp follows symlinks and copies the target file. To preserve the symlink as a symlink, you need to use --follow-link=false (available in Docker 24+). Older versions always follow symlinks.

docker cp --follow-link=false container:/path/to/symlink ./

Overwrite vs. rename confusion

If the target is a directory, the source is placed inside it:

# Copies file.txt INTO /tmp/ (becomes /tmp/file.txt)
docker cp file.txt container:/tmp/

If the target ends with /, Docker treats it as a directory. If it’s a filename and exists as a directory, it fails:

docker cp file.txt container:/tmp/existing_dir  # okay, creates /tmp/existing_dir/file.txt
docker cp file.txt container:/tmp/existing_file # ERROR if existing_file is a file

What you learned & what's next

You now know how to: - Copy files from host to container using docker cp - Extract files from container to host - Transfer entire directories recursively - Work with both running and stopped containers - Correctly handle common edge cases like missing paths, symlinks, and overwrite behavior

Next up: You'll learn how to manage environment variables — injecting sensitive configs like API keys and database URLs without hardcoding them into your Dockerfile.

Practice recap

Try this mini-exercise: 1) Run an Nginx container (docker run -d --name nginx-practice -p 8080:80 nginx:alpine). 2) Copy a custom index.html from your host into the container at /usr/share/nginx/html/. 3) Verify the custom page loads by visiting http://localhost:8080. 4) Copy the default Nginx config file from the container to your host (/etc/nginx/nginx.conf) and inspect it. This will solidify your understanding of bidirectional file transfer with docker cp.

Common mistakes

  • Forgetting to include the colon (:) in the container path: docker cp file.txt containername/tmp/ — without the colon, Docker thinks the entire string is a file name.
  • Trying to copy into a container that has been removed (not just stopped): docker cp only works on containers visible in docker ps -a.
  • Confusing overwrite vs. rename behavior — if the target path ends with a slash, the source goes inside that directory; without a slash, it replaces the file/directory if it exists.
  • Assuming docker cp preserves extended attributes or ACLs — it preserves basic Unix permissions and ownership but does not handle all filesystem metadata (e.g., xattrs from some storage drivers).

Variations

  1. Use docker cp with an archive flag (-a) to preserve permissions and symlinks exactly as they are in the container (this is the default).
  2. For large transfers, consider using docker exec with tar piped over stdin/stdout for better performance and compression: docker exec container tar -cf - /path | tar -xvf -.
  3. When copying between two containers, use a two-step process: copy from container A to host, then from host to container B — there’s no direct container-to-container docker cp.

Real-world use cases

  • Extracting application logs from a crashed container for debugging without stopping the container (if still running).
  • Injecting a one-time SSL certificate or license file into a running web server container without rebuilding the image.
  • Grabbing a database dump file generated inside a container (e.g., pg_dump) to your local machine for backup or analysis.

Key takeaways

  • docker cp lets you transfer files between host and container filesystems, even when the container is stopped.
  • The syntax is docker cp <source> <target> with a colon separating container name from path: container:path.
  • Copying directories requires no special flag — just include a trailing / on the target path to place contents inside.
  • docker cp does not require a shell or any utilities inside the container, making it ideal for minimal images.
  • Edge cases like missing paths, symlinks, and overwrite behavior are common — always verify the container path exists before copying.
  • For persistent data sharing, prefer volume mounts over ad-hoc docker cp in production.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.