简体   繁体   中英

Docker - install stuff in Dockerfile or external shell script

I figure there are two ways to install some dependency in Dockerfile:

1) in Dockerfile:

RUN yum install xxx 

2) put "yum install xxx" in a script install.sh and in Dockerfile

RUN ./install.sh 

Both seems to be working, just wandering is any one better than the other?

There is nearly no difference for your afforded options. If you insist, I can tell you some little difference:

1. The output of two images have different number of layers & a little size difference:

A simple example as next:

Option 1:

Dockerfile:

FROM centos:7
RUN yum install -y net-tools

Build command:

$ docker build -t trial:1 . --no-cache

Option 2:

Dockerfile:

FROM centos:7
ADD install.sh .
RUN ./install.sh

install.sh:

yum install -y net-tools

Build command:

$ docker build -t trial:2 . --no-cache

Compare:

$ docker history trial:1
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
f86f153f9d95        12 minutes ago      |0 /bin/sh -c yum install -y net-tools          105MB
9f38484d220f        3 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           3 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>           3 months ago        /bin/sh -c #(nop) ADD file:074f2c974463ab38c…   202MB

$ docker history trial:2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
775be0061903        10 minutes ago      |0 /bin/sh -c ./install.sh                      105MB
b7ca1d2a7e8b        10 minutes ago      /bin/sh -c #(nop) ADD file:6f96562be8deac728…   25B
9f38484d220f        3 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           3 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>           3 months ago        /bin/sh -c #(nop) ADD file:074f2c974463ab38c…   202MB

From above, you can see if you use ./install.sh , you will have to have a ADD instruction in Dockerfile . Compared to the option 1, it will increase a image layer about 20B for your finally generated image.

2. Maximum image layer limit:

See this discussion , the maximum of docker image layers is 127, so if you in a special situation which base image or your image uses too many layers already, it maybe helpful.

3. Efficiency of copy files from host to container:

ADD need to copy file from docker host to container. Internally, docker build will create a tar file of the context directory, sending it to the docker daemon and unpack it. So the question will be why we need this if we could do it directly in Dockerfile ?

But do you really care the 20B , one more layer & a little speed of COPY? I guess unless in some very bare situations, there is no difference for the 2 options.

However, seems put package install directly in Dockerfile is most people's choice, because folks may ask why I should put effort to maintain a install.sh if it did not bring any benefit to me.

Docker will create an image for each Instruction on your Dockerfile but if there was an image created with that Instruction already, it will use that image instead.

So when you have multiple Instructions on your Dockerfile to create your image, it's important to organize your Instructions in a way that it reduces the number of intermediate images.

So i think, if you put all your Instructions in one single file you may have less intermediate images. But also note that, any future changes in that file, will lead to creating a new intermediate image since there is nothing already created to be used which will make image creation time slower.

If you are building docker images then use the below in the Dockerfile not the script to install the packages and its dependencies.

RUN yum -y update && \\ yum -y install .. && \\ yum clean all

Use the custom shell script for running the application specific service(s) inside ENTRYPOINT in the Dockerfile.

Use the instructions for adding/installing packages in one RUN command to reduce the intermediate image layers.

Its good to use the shell script for installing the packages and its dependencies for non containers images/non docker images for automating the process for VM based apps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM