29

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)?

Dzhuneyt
  • 8,437
  • 14
  • 64
  • 118
  • If you were to change line 12 of your dockerfile to be: `RUN rm -frv /usr/share/nginx/html/* && ls /usr/share/nginx/html/`, what output do you get? Just trying to isolate if the issue is with your command, or if it is with the layers in your image not correctly building on top of each other – CtheGood Mar 14 '16 at 16:00
  • 5
    I encountered the same issue, and eventually realized that the files I was trying to remove were defined as being within a volume by the base image Dockerfile, so that volume was therefore getting recreated in every layer. From the [Docker documentation](https://docs.docker.com/engine/reference/builder/#volume): `If any build steps change the data within the volume after it has been declared, those changes will be discarded.` – Dustin Martin Jun 22 '17 at 14:01

2 Answers2

18

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.

PaulC
  • 505
  • 4
  • 10
  • 3
    You should use && instead of the semicolon, because the command after && only executes if the first command didn't fail. If it doesn't matter if the first command fails, or its important that the second command executes even if the first command fails, then command chaining with the semicolon is what you want. – Phillip H. Blanton Sep 13 '22 at 16:38
4

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.

ntwrkguru
  • 1,644
  • 1
  • 11
  • 14
  • Dockerfile: https://gist.github.com/hasMobi/e198555704ee57e84399 Result: http://prntscr.com/aeng43 Inside the same folder as the `Dockerfile` I the only other file present is /code/index.html, with a "Hello world" text inside. My final goal is to have only this file present in `/usr/share/nginx/html/`. But the index.php seems to be restored inside the `html` folder with each RUN command. – Dzhuneyt Mar 13 '16 at 10:56
  • By the way I am using Docker v1.10.3 on Windows. – Dzhuneyt Mar 13 '16 at 11:07
  • If you were to try and change line 12 to be: `RUN rm -frv /usr/share/nginx/html/* && ls /usr/share/nginx/html/`, what output do you get? Just trying to isolate if the issue is with your command, or if it is with the layers in your image not correctly building on top of each other. – CtheGood Mar 14 '16 at 14:22
  • 2
    I tried combining a `ls` command, a `rm` command and a subsequent `ls` command all within the same RUN instruction. The effect of the chained command is: files are listed as existing, deleted, the directory is listed to be empty (as expected). But a subsequent `RUN ls /samedirectory` command in its own RUN instruction lists the same files which I just deleted in the previous RUN instruction. – Dzhuneyt Mar 14 '16 at 19:22