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:
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 ) |
The docker cp
command is useful in several scenarios where you want to interact with a container’s filesystem:
- Debug container issues — You can diagnose problems with containerized apps by copying out logs, traces, or other generated files that help you troubleshoot.
- 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.
- 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.
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
e91fa84e2bea7d130301d414f121e75b28b3c1820d235ad4c6df31abdea1aebc
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
bin
boot
dev
docker-entrypoint.d
docker-entrypoint.sh
etc
example-file
...
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.
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.
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.
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.