Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerfile - removing a file in one RUN command, it is still present in the next RUN command

Tags:

docker

windows

I have a Dockerfile (https://gist.github.com/hasMobi/e198555704ee57e84399) that have these two commands in sequence:

RUN rm -frv /usr/share/nginx/html/*
RUN ls /usr/share/nginx/html/

When I look at the console while building hte image, I can clearly see 2 files being removed from that folder, but when the next RUN command comes, it lists the directory's contents and the files are still there?:

Step 6 : RUN rm -fry /usr/share/nginx/html/* 
 ---> Running in b9a69992e4e0 
removed '/usr/share/nginx/html/index.html' 
removed '/usr/share/nginx/html/index.php' 
 ---> 2bfe01cbd007 
Removing intermediate container b9a69992e4e0 
Step 7 : RUN is /usr/share/nginx/html/ 
 ---> Running in 08396f6029e1 
index.html 
index.php 
 ---> a6471052519d 

What is going on here? I understand that each RUN command creates a separate layer and one is isolated from the other, but isn't the second RUN command supposed to inherit the file system in the exact state that it was in the previous RUN command (with the 2 files gone)?

like image 718
Dzhuneyt Avatar asked Mar 12 '16 19:03

Dzhuneyt


People also ask

Can Dockerfile have multiple run commands?

You can separate your commands with ; or && . If you use the second method, and one of the commands fails, the docker build also fails. This is usually a good idea.

What does run command do in Dockerfile?

The docker run command first creates a writeable container layer over the specified image, and then starts it using the specified command. That is, docker run is equivalent to the API /containers/create then /containers/(id)/start .

How do I create a Run command in Dockerfile?

The basic syntax for the command is: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] You can run containers from locally stored Docker images. If you use an image that is not on your system, the software pulls it from the online registry.


2 Answers

I had a similar issue:

   RUN rm -rf /full/path
   RUN ln -s /other /full/path

This fails because "/full/path" still exists on the second RUN. This workaround works:

   RUN rm -rf /full/path; ln -s /other /full/path

I don't understand the behavior but was able to work around it in my case.

like image 60
PaulC Avatar answered Sep 20 '22 20:09

PaulC


Basically, the ADD commands from the base image are overwriting the RUN commands in your Dockerfile. See this for more information.

Note: The first encountered ADD instruction will invalidate the cache for all following instructions from the Dockerfile if the contents of have changed. This includes invalidating the cache for RUN instructions. See the Dockerfile Best Practices guide for more information.

You may consider forking the source base image and using your customized version instead.

like image 45
ntwrkguru Avatar answered Sep 20 '22 20:09

ntwrkguru