Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cat a file inside a docker image?

Assume that there are 40 steps in a Dockerfile. Imagine a situation where you change a file(say prod.json) and it reruns the 3rd step in the Dockerfile on running the docker build command. Since docker build takes more than a minute to run, is there a way to view the content of the file prod.json in the current docker image. This will allow me to decide whether to rebuild the docker image or not.

Alternate explanation of my question:

  1. Run docker build to create a docker image with tag service (call it v1)
  2. Change a file(say prod.json) that required the 3rd step in the Dockerfile to rerun (thus failing the cache)
  3. Run docker build to create docker image with tag service (call it v2)
  4. Go on a break and come back after 1 hour
  5. Get confused if the current build has the change you included in the 2nd step - is there some way to cat the file directly from the docker image without running the container at this stage?
like image 484
Abhishek Kandoi Avatar asked Mar 28 '17 07:03

Abhishek Kandoi


2 Answers

This seems to work dependably for me as it resolves the entrypoint conflict and assures output to stdout. It also kills the container immediately after gathering the data to keep things clean, almost as good as not running it at all. I hope it'll help others.

docker run -it --rm -a stdout --entrypoint cat <image> <filename>

Also easy to alias if you do this a lot. Add the first line to your ~/.bash_aliases or ~/.bashrc.

$ alias dcat='docker run -it --rm -a stdout --entrypoint cat'
$ dcat <image> <filename>
like image 182
Josiah Avatar answered Nov 02 '22 16:11

Josiah


When you do docker build, docker will start a intermediate container and run your command inside, then the container will be removed after the process is done. So if you want to check the content of some file while the image is still under building, just docker exec -it <intermediate_container_id> /bin/bash and check it.

Here's a detailed example:

Dockerfile with mock long build process:

FROM alpine:3.3

RUN echo '["name": "docker"]' > /root/prod.json
RUN echo "prod.json modified, start long build process" && sleep 120 && echo "Long build process finished"

Build the image

 ~/test/long-build-dockerfile/ [test1*] docker build -t long-running-build .
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM alpine:3.3
---> 6c2aa2137d97
Step 2/3 : RUN echo '["name": "docker"]' > /root/prod.json
 ---> Running in 4045ab129add
 ---> f5d21892fa51
Removing intermediate container 4045ab129add
Step 3/3 : RUN echo "prod.json modified, start long build process" && sleep 120 && echo "Long build process finished"
 ---> Running in dd45b269efda
prod.json modified, start long build process

Now the build process will be stuck for 120 seconds here, then open another terminal and find the intermediate container:

 ~/ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
dd45b269efda        f5d21892fa51        "/bin/sh -c 'echo ..."   11 hours ago        Up 4 seconds                            serene_gates

Go inside and check the content:

 ~/ docker exec -it serene_gates sh
/ # cd /root/
~ # ls
prod.json
~ # cat prod.json
["name": "docker"]
like image 27
shizhz Avatar answered Nov 02 '22 15:11

shizhz