Elevating IaC Workflows with Spacelift Stacks and Dependencies 🛠️

Register for the July 23 demo →


Using Docker Cp Command to Copy Files in Containers [Examples]

docker cp command

Docker is the most popular platform for building and running software containers—sandboxed environments that are similar to virtual machines, but share your host’s operating system kernel. Containers have their own filesystems that contain the packages, source code, and dependencies necessary for an application to run.

Occasionally you might want to transfer files between your host and a container’s filesystem. In this guide, we’ll walk you through understanding docker cp and share some examples for using the command in common scenarios. Let’s begin!

What we will cover:

  1. What is docker cp?
  2. When to use docker cp?
  3. Examples: How to use docker cp
  4. Docker cp common issues
  5. Using bind mounts instead of docker cp

What is docker cp?

The docker cp command allows you to copy files and directories to and from your Docker containers, similar to Unix cp but with some differences and limitations. You can use it whenever you need to interact with a container’s content.

Its basic syntax is similar to a regular cp:

$ docker cp <src> <dest>

The content at the path referenced by <src> will be copied to <dest>. <src> and <dest> can either reference a path on your local filesystem or one within a container. Container references use <container>:<path> syntax, where <container> is the container’s ID or name and <path> is the path within the container’s filesystem.

The command can either copy to a container from your host, or from a container to your host. It’s not possible to copy files directly between containers; however, you can easily achieve this yourself by running docker cp twice.

Understanding docker cp behavior

Compared to Unix cp, docker cp has a few significant differences in how it handles the destination path. The behavior varies depending on whether you’re copying a file or a directory:

  • For file copies, the destination can be either a new file path or an existing file or directory. If a directory path is given, then the file will be copied into that directory. When a new path is given, then the directory must already exist.
  • For directory copies, a new directory will be created if the destination path doesn’t already exist. If the destination does exist, then the new directory will be copied into the existing one, unless the source path ends with /.—in which case, the content of the source directory will be copied into the existing destination directory.

Here’s an exhaustive table of the different options:

Type Source Destination Destination already exists? Copied Path
File /foo /bar No /bar
File /foo /bar/demo No (/bar doesn’t exist) (Error)
File /foo /bar Yes, as File /bar
File /foo /bar Yes, as Directory /bar/foo
Directory /foo /bar No /bar (contains the content of /foo)
Directory /foo /bar/demo No (/bar doesn’t exist) (Error)
Directory /foo /bar Yes, as File (Error)
Directory /foo /bar Yes, as Directory /bar/foo (contains the content of /foo)
Directory /foo/. /bar Yes, as Directory /bar (contains the content of /foo)

When to use docker cp?

The docker cp command is useful in several scenarios where you want to interact with a container’s filesystem:

  1. Debug container issues — You can diagnose problems with containerized apps by copying out logs, traces, or other generated files that help you troubleshoot.
  2. Copy out or backup stored files — Many containers create persistent data when they’re used, such as uploads to a web application. docker cp lets you make copies of these files on your host, ensuring you have a separate backup before you make changes to your container’s deployment.
  3. Make config file changes — Some apps dynamically read their configuration files. You can use docker cp to copy in new values without having to restart the container.

In general, it’s best to avoid using docker cp to apply changes to your containers. Manually altering container filesystems is often an anti-pattern because it can cause drift compared to the container image. Your copied files will also be lost when the container restarts unless the destination path is a bound Docker volume.

To summarize, you can safely rely on docker cp to copy files out of containers. This simplifies common development tasks and makes it easier to experiment. However, if changes are required to a container’s filesystem, then you should consider rebuilding the image to include your new files—unless you’re only modifying config values or other persistent data that are stored in a volume.

Examples: How to use Docker cp command

In this section, we’ll show some examples of the different ways in which you can use docker cp. Before continuing, create a new container that you can use to test different copy operations—we’re calling it demo-container:

$ docker run -d --name demo-container nginx:latest

You should also create a test file on your host, ready to copy to your container:

$ touch test

1. Copy into a container

To copy a file or directory into a container, specify the source path as the first argument, then the in-container destination as the second:

$ docker cp test demo-container:/example-file
Successfully copied 1.54kB to demo-container:/example-file

Now, the content will be available in the container’s filesystem at the specified path:

$ docker exec demo-container ls

2. Copy from a container to your host

To copy from a container to your host, simply reverse the arguments in the docker cp command:

$ docker cp demo-container:/example-file copied-file
Successfully copied 1.54kB to /home/james/copied-file

3. Copy between containers

You can’t use docker cp to directly copy between two containers (if you try, you’ll see copying between containers is not supported error). To achieve this procedure, you must first copy the files from the source container to a temporary location on your host:

$ docker cp container1:/target-file temp

Then use docker cp a second time to copy the files into the destination container:

$ docker cp temp container2:/destination

Afterwards, you can remove the temporary copy from your host:

$ rm -rf temp

4. Recursively copy directories

docker cp automatically performs recursive copies of directories. If you specify a directory as the source argument, then its entire contents will be copied to the destination using the rules discussed above.

# Copies the "config" directory as a new subfolder of "/opt/app/data"
$ docker cp config/ container1:/opt/app/data

# Copies the contents of the “config” directory into “/opt/app/data/config” directly
$ docker cp config/. container1:/opt/app/data/config

5. Identify containers by ID or name

docker cp allows you to reference containers by ID or name:

$ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS         PORTS       NAMES
e91fa84e2bea   nginx:latest     "/docker-entrypoint.…"   8 minutes ago   Up 8 minutes   80/tcp      demo-container

Our container is called demo-container and its ID is e91fa84e2bea.

All these commands can be used:

$ docker cp path demo-container:/dst
$ docker cp demo-container:/path dst

$ docker cp path e91fa84e2bea:/dst
$ docker cp e91fa84e2bea:/path dst

6. Follow symlinks in the source directory

Like Unix cp, the docker cp command won’t follow symlinks in the source directory by default. You can use the optional -L (--follow-link) flag to enable this behavior:

$ docker cp -L /path/to/src demo-container:/dst

When the flag is used, then docker cp will copy the contents of paths referenced by symbolic links, instead of copying the link itself.

7. Preserve uid/gid information using archival copying

The -a or --archive flag is the second (and final) copy option supported by docker cp. It specifies that the command should copy all user (uid) and group (gid) information from the source files to the destination. This ensures the copied files have the same permission assignments as the originals.

$ docker cp -a /path/to/src demo-container:/dst

Setting the -a flag is appropriate when you want to make an exact backup of a directory without losing important permission changes.

8. Hide progress output with quiet mode

Current Docker CLI releases emit progress information to your terminal when you use the cp command. This output can be disabled by setting the -q or --quiet flag. It makes it easier to integrate docker cp with scripts where handling progress lines might be undesirable:

# Shows default progress output
$ docker cp test demo-container:/example-file
Successfully copied 1.54kB to demo-container:/example-file

# No progress output
$ docker cp -q test demo-container:/example-file

9. Copy multiple files

It’s s not possible to copy multiple files at the same time with the docker cp command, unless you copy the entire directory that contains them or use a for loop.

Docker cp common issues

Seeing an error when running docker cp? Here’s how to troubleshoot the most common issues.

1. “docker cp” requires exactly 2 arguments

docker cp always needs two arguments: the source and destination path. If you forget to set the destination (such as by running docker cp demo-container:/foo), then you’ll see this error message.

2. Copying between containers is not supported 

You can’t use the command to directly copy between two containers. Running docker cp container1:/foo container2:/foo will show this error message—you should transfer the file to your host first, then use another docker cp operation to copy it into the second container.

3. Could not find the file in container

An error like this one appears when you’re copying a file or directory from a container, but the source path you’ve specified doesn’t actually exist. You should repeat the command after correcting the path.

4. Permission denied

You might see permission errors if you’re blocked from accessing a path you’re referencing on your host, either as a copy source or destination. You’ll need to adjust the path’s permissions or try again as an appropriately privileged user.

5. Invalid output path: directory does not exist

This error means you’ve specified an invalid host or container destination path. If you’re copying to /foo/bar/test, then docker cp requires the entire /foo/bar directory chain to already exist. Create the directory structure first, then repeat the command.

The ability to diagnose these problems will ensure your container copying operations go smoothly, without unexpected errors.

Using bind mounts instead of docker cp

docker cp isn’t quite the only way to make content on your host accessible in a container. Volume bind mounts can also be used to populate container directories upon initial creation, when you call docker run:

$ docker run -v /my-app/data:/var/app/data demo-app:latest

This example mounts the /my-app/data directory on your host to /var/app/data in the container. When the process running in the container inspects the files in /var/app/data, it’ll see the content that exists on your host.

This technique removes the need to separately run docker cp after the container starts. However, as the files aren’t actually copied—they’re merely mounted into the container—any changes made by the container’s process will affect the originals stored on your host.

Key points

This article has explored docker cp, a Docker CLI command for moving files between your host and Docker containers. It’s a useful way to debug container problems, test changes, and extract any filesystem content that you want to backup or keep after a container stops.

Copying files into containers is best reserved for development tasks or one-off experimentation. It’s ideal to avoid directly modifying the filesystems of production containers because this can introduce confusing discrepancies compared to the container image’s Dockerfile. However, an exception to this rule is if you’re writing to a directory that’s mapped to a volume on your host and the image expects you to manually populate certain persistent config files or other resources.

That’s all for this guide to docker cp—check out our Docker CLI cheat sheet to learn 35 more commands.

We encourage you also to explore how Spacelift offers full flexibility when it comes to customizing your workflow. You have the possibility of bringing your own Docker image and using it as a runner to speed up the deployments that leverage third-party tools. Spacelift’s official runner image can be found here.

The Most Flexible CI/CD Automation Tool

Spacelift is an alternative to using homegrown solutions on top of a generic CI. It helps overcome common state management issues and adds several must-have capabilities for infrastructure management.

Start free trial

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide