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:
Dockerfile:
FROM centos:7
RUN yum install -y net-tools
Build command:
$ docker build -t trial:1 . --no-cache
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
$ 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.