We love using go to build our backend services. Among many reasons one is the fact that when you build your application into a docker image, it contains literally nothing except your application. Many other languages or frameworks require a complete linux to be packaged into the container (or even a virtual machine running on a linux!), making it bigger and more complex.
While we find it very awesome when our build pipeline spits out a 6mb docker image that contains basically an executable and a folder with some compiled HTML/CSS/JS initially there seems to be a downside: You cannot get at the contents of the running container as easily as when you can actually connect with a shell into the container. You see it is running in a
docker ps but it's a bit of a black box. Of course you can mount volumes to have the application store information outside the container, but you may have forgotten to do so and now some bit of information is locked up in there? Worry not, there is a way to get at it.
Lets say our server generates a pdf file with a name based on a timestamp (so we do not know the name). The container is running, the pdf is saved inside the containers filesystem. Now we want to get it out for inspection.
So first we need to know the id of the container. So we run
docker ps to get our container id. Say it is "8f87b75b584e".
Docker export to the rescue
Docker supports a command that will take the filesystem of a container and export it to STDOUT. This is useful for instance to export the filsystem from inside a container into a tar file:
docker export 8f87b75b584e > my_container.tar
You can also use it to export the filesystem into the tar executable to output what files are contained inside like so:
docker export 8f87b75b584e | tar t
This will output something like the following:
.dockerenv app/ app/server app/documents/1590404561193689502.pdf app/public/ app/public/assets/favicon.ico app/public/assets/logo.svg app/public/index.html app/public/static/ app/public/static/css/ app/public/static/css/main.5de28820.chunk.css app/public/static/css/main.5de28820.chunk.css.map app/public/static/js/ app/public/static/js/2.20a9197e.chunk.js app/public/static/js/2.20a9197e.chunk.js.LICENSE.txt app/public/static/js/2.20a9197e.chunk.js.map app/public/static/js/main.c34e0be6.chunk.js app/public/static/js/main.c34e0be6.chunk.js.map app/public/static/js/runtime-main.7eede39e.js app/public/static/js/runtime-main.7eede39e.js.map dev/ dev/console dev/pts/ dev/shm/ etc/ etc/hostname etc/hosts etc/mtab etc/resolv.conf proc/ sys/
So now we know what it is called:
1590404561193689502.pdf That makes it possible to copy the file from the running docker container to the hosts filesystem:
docker cp 8f87b75b584e:app/documents/1590404561193689502.pdf test.pdf
Voila! Having these tools at hand takes away what might otherwise be a drawback to the ultra lean docker images possible when packaging a go application in an image based on "scratch".