How do I get files out of a Docker container without exec?

A helpful technique for extracting contents from minimal containers.

How do I get files out of a Docker container without exec?
Photo by Lucas van Oort / Unsplash
🙏
Special shout-out to Tom D'Aquino for sharing this nifty tip!

Sometimes when debugging/troubleshooting a docker issue, it's helpful to examine the file contents of a live container. My initial go-to action for something like this is launching an interactive terminal; usually something like docker exec -it <container_name> /bin/sh. That typically works but... some minimal containers (like those that use distroless images) intentionally have no shell for security reasons. So can we do then?

For situations like this, a great alternative is to leverage the docker export subcommand. This effectively generates a point-in-time snapshot of the container file system and copies it to an archive file on the docker node. Syntax looks like this:

docker export <containerName> > <outputfile>

Let's consider Portainer for example. Some of its images are restricted and don't have a built-in native shell option. So if I want to extract contents from a running instance of Portainer, I could execute a command like:

docker export portainer > portainer-file-contents.tar

If I want to extract the contents of the file locally on my Docker node, I could run something like:

tar -xf portainer-file-contents.tar -C ./extracted

Nifty, huh!

🚧
One small caveat that's worth (re)mentioning: docker export captures the current state of the container's filesystem (including any real-time changes made post-launch). That also means that it's not going to include mounted volumes.

For more information on this, check out the following resources:

docker container export
″”