Extracting files from Docker Images and Containers
Yash Soni / December 12, 2022
3 min read
Docker is a powerful tool for running and managing containers, which are lightweight and portable packages that contain all the necessary files and dependencies for an application to run.
One useful feature of Docker is the ability to extract the contents of a container image, which can be useful for debugging or for making backups.
There are a few ways to achive this.
We will begin with a very simple Dockerfile which creates a
build-logs.txt file during the build process.
FROM alpine as BUILD WORKDIR /home RUN echo "Hello Docker" > build-logs.txt
docker build -t buildx-cp . # create a container named "tmp" without running it docker create --name tmp buildx-cp # export the contents of entire image to a tar file docker export tmp > myimage.tar # remove the created container docker rm tmp
When we need a specific file from the running container,
we can use the
cp command to copy contents from the container to the filesystem (or vice-versa).
# copy the file from a container to filesystem docker cp tmp:/home/build-logs.txt . # copy myFile from filesystem to the container docker cp ./myfile tmp:/home
Docker multi-staged builds are a way to optimize the Docker build process by using multiple build stages in a single Dockerfile. This allows you to separate your build process into multiple stages, each with its own specific purpose, and only include the necessary files and dependencies in the final Docker image. This can result in smaller, more efficient Docker images that are easier to manage and deploy.
FROM alpine as BUILD WORKDIR /home ADD ./isPrime.sh . RUN chmod +x ./isPrime.sh RUN echo "Hello Docker" >build-logs.txt FROM alpine as FINAL WORKDIR /home COPY /home/isPrime.sh . CMD ["sh", "isPrime.sh"]
Here we create a FINAL image copying only required files from the BUILD stage.
Let's say we need to get the contents of the
build-logs.txt file which is generated as a part of the build process.
With the solutions mentioned till now, we will have to unnecessarily copy this file in FINAL layer to be able to copy the contents.
A better way is to use Docker Exporters
which provides handy options to output the entire Docker image to disk as a directory or TAR ball alongwith a
However, instead of copying the entire contents, we can use the minimilist
image to copy only the required files in an intermediate stage.
FROM alpine as BUILD WORKDIR /home ADD ./isPrime.sh . RUN chmod +x ./isPrime.sh RUN echo "Hello Docker" >build-logs.txt # take an "empty" image as a starting point & copy the requires artefacts FROM scratch as EXPORT COPY /home/build-logs.txt ./ FROM alpine as FINAL WORKDIR /home COPY /home/isPrime.sh . CMD ["sh", "isPrime.sh"]
Now we can "target" the docker build till the
EXPORT stage and gather the output using the
docker build --target EXPORT --output type=local,dest=out . ls out/ build-logs.txt
Using this method, we can extract files generated in intermediatery stages without copying to subsequent stages!