7

I'm trying to reduce the size of my docker image. In my docker file, I do this:

FROM crystal/centos
MAINTAINER crystal

ADD ./rpms/test.rpm ./rpms/ 
RUN yum -y --nogpgcheck localinstall /rpms/test.rpm 

from what I understand, the ADD command is in its own layer, and then RUN is in another layer. So after I install the rpm, how do I go about deleting the initial /rpms directory.

Roshin Raphel
  • 2,612
  • 4
  • 22
  • 40
Crystal
  • 28,460
  • 62
  • 219
  • 393

4 Answers4

9

use this technique

RUN curl http://someaddress/test.rpm &&\
    yum -y --nogpgcheck localinstall /rpms/test.rpm &&\
    rm test.rpm
Montells
  • 6,389
  • 4
  • 48
  • 53
  • 2
    You can just RUN yum -y install http://someaddress/test.rpm if the rpm is hosted somewhere. – seanmcl Oct 28 '14 at 20:08
  • My situation is that - due to security reasons I am downloading the packages in the intermediate layer. Then, ADD'ing them to the final image. Followed by using RUN command to install the packages and delete the packages. My goal is to delete the downloaded packages once the RUN command installs them. Is there any way to a) combine the ADD and RUN into one layer; b) remove the ADD layer? – variable Jun 03 '20 at 08:46
4

you cannot remove data from previous layers. If the /rpms/ folder is huge and you absolutely don't want its data in your docker image you have at least two solutions:

  1. do not ADD the data (since it will commit a layer), instead use a single RUN instruction to:
    • download the rpm file
    • install the rpm file
    • delete the rpm file
  2. flatten your image afterwards
Thomasleveil
  • 95,867
  • 15
  • 119
  • 113
1

You can do

RUN rm -rf /rpms

which will make the ultimate union file system smaller. That is, df will report less usage. It will not of course make the image database smaller, but rather very slightly larger. If you want to avoid making your database larger, you can create your own yum repository and install directly from there. This has the obvious downside that it will not be reproducible by anyone without access to your yum repo.

seanmcl
  • 9,740
  • 3
  • 39
  • 45
1

In question about mounting docker image to host filesystem I've covered some internal structure of how docker stores their images. You can refer this question Is it possible to mount a docker image and then access it (RO) as a normal directory or mounted device?

In case of AUFS graph driver, docker (at least in version 1.2 or later) does:

  • Store container layers in directory /var/lib/docker/aufs/diff
  • Keep list of layers which container consists of in simple text file /var/lib/docker/aufs/layers/${CONTAINER_ID}.

So, if you desire to delete some intermediate layer from your container, you may try to delete particular line from /var/lib/docker/aufs/layers/${CONTAINER_ID} and then remove corresponding directory from /var/lib/docker/aufs/diff/.

NOTE: I didn't try this. This may doesn't work for you, or even may be dangerous.

Community
  • 1
  • 1
Viacheslav Kovalev
  • 1,745
  • 12
  • 17