Thin images have been selected, so reduce the number of layers of images and merge the previous runs together. Switch WORKDIR to cd under RUN
Previous Dockerfile:
FROM rhel7 EXPOSE 80 VOLUME ["/usr/local/nginx/html"] COPY dvd.repo /etc/yum.repos.d/dvd.repo RUN rpmdb --rebuilddb RUN yum install -y gcc pcre-devel zlib-devel ADD nginx-1.18.0.tar.gz /mnt WORKDIR /mnt/nginx-1.18.0 RUN ./configure --prefix=/usr/local/nginx RUN yum install make -y RUN make RUN make install CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
After reducing the number of mirror layers:
[root@docker1 docker]# cat Dockerfile FROM rhel7 EXPOSE 80 VOLUME ["/usr/local/nginx/html"] COPY dvd.repo /etc/yum.repos.d/dvd.repo ADD nginx-1.18.0.tar.gz /mnt RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel && cd /mnt/nginx-1.18.0 && ./configure --prefix=/usr/local/nginx && yum install make -y && make && make install CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
Clean up the cache path of the intermediate product: / var / cache / yum, delete the nginx installation package, and delete the make gcc after compiling (dependencies will be installed when installing make packages, but they will not be deleted when deleting them)
[root@docker1 docker]# cat Dockerfile FROM rhel7 EXPOSE 80 VOLUME ["/usr/local/nginx/html"] COPY dvd.repo /etc/yum.repos.d/dvd.repo ADD nginx-1.18.0.tar.gz /mnt RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && cd /mnt/nginx-1.18.0 && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.18.0 /var/cache/yum CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@docker1 docker]# docker build -t webserver:v2 .
Mirror size gap after optimization:
[root@docker1 docker]# docker images webserver REPOSITORY TAG IMAGE ID CREATED SIZE webserver v2 503439033877 24 seconds ago 258MB webserver v1 bdd2829a42e3 36 minutes ago 346MB
[root@docker1 docker]# docker images rhel7 rhel7 latest 0a3eb3fde7fd 7 years ago 140MB
Optimized: 346-258. It's more than 140 base images
It can be seen that most of them are 111MB in Yum, and this layer is mainly used for installation package compilation, etc
[root@docker1 docker]# docker history webserver:v2 IMAGE CREATED CREATED BY SIZE COMMENT 503439033877 6 minutes ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb... 0B c140026256fd 6 minutes ago /bin/sh -c rpmdb --rebuilddb && yum install ... 111MB 8b163bc5912e 7 minutes ago /bin/sh -c #(nop) ADD file:a90dc1ecadbd423a5... 6.25MB b17ef4913f9c 48 minutes ago /bin/sh -c #(nop) COPY file:fe5cdcb63a06bd4c... 67B 82ca7e5c38e6 49 minutes ago /bin/sh -c #(nop) VOLUME [/usr/local/nginx/... 0B 8aa3b0c110c7 49 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B 0a3eb3fde7fd 7 years ago 140MB Imported from -
It can be seen that when v1 is not optimized, you can only use yum code.
[root@docker1 docker]# docker history webserver:v1 IMAGE CREATED CREATED BY SIZE COMMENT bdd2829a42e3 44 minutes ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb... 0B 9e03306cbffd 44 minutes ago /bin/sh -c yum install make -y 43.6MB bf1e3007a03b 49 minutes ago /bin/sh -c yum install -y gcc pcre-devel zli... 133MB
After compiling the source code, you really only need the compiled binary code
Therefore, I really only need the binary code of / usr/local/nginx, which is only 5M, and the rest (intermediate products) do not need it. If I turn off debug, it will be less than 1M
You can only compile the source code (binary code) of the operating system for direct use by other operating systems
Use multistage build
It is divided into two parts. First compile the binary code in one container, and then copy it to the second container for use
Comment out debug
[root@docker1 nginx-1.18.0]# vim auto/cc/gcc
[root@docker1 nginx-1.18.0]# sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
Replace all completed
Add the instruction to the Dockerfile and build it in multiple stages (use the binary code of nginx compiled by the previous container)
as build is named build
COPY --from=build /usr/local/nginx /usr/local/nginx put the binary encoding directory of the previous container (/ usr/local/nginx) in / usr/local/nginx of the next container
It is not necessary to expose ports and volumes, so it is deleted and a streamlined Dockerfile is compiled
[root@docker1 docker]# cat Dockerfile FROM rhel7 as build COPY dvd.repo /etc/yum.repos.d/dvd.repo ADD nginx-1.18.0.tar.gz /mnt RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && cd /mnt/nginx-1.18.0 && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.18.0 /var/cache/yum FROM rhel7 COPY --from=build /usr/local/nginx /usr/local/nginx CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@docker1 docker]# docker build -t webserver:v3 .
Remove the 140MB basic image base and an nginx 1MB
[root@docker1 docker]# docker images webserver REPOSITORY TAG IMAGE ID CREATED SIZE webserver v3 5cd6dd1fdc7f 31 seconds ago 141MB webserver v2 503439033877 35 minutes ago 258MB webserver v1 bdd2829a42e3 About an hour ago 346MB
It must be nginx OK for docker to run. CMD reports errors when there are problems
[root@docker1 docker]# docker run -d --name nginx webserver:v3 [root@docker1 docker]# docker container inspect nginx | grep "IPAddress" "IPAddress": "172.17.0.2", [root@docker1 docker]# curl 172.17.0.2 <h1>Welcome to nginx!</h1>
No optimization can be smaller than the base image
Therefore, we need to find a more streamlined base in optimization https://hub.docker.com/ Find or www.github.com Com or www.gitee.com Com
When nginx is running, it will call the dynamic library file of the system
Library files are indispensable. Without binary files, you can't get up.
Therefore, when copying the binary file directory, the library files should also be included. At the same time, the library files called by different compiled nginx are also different. Opensll and Lib opensll libraries are added. Therefore, if you exchange smaller images, you need to migrate the library files and binary files at the same time. At the same time, we should also consider whether these library files are dependent or not, and call other library files.
[root@docker1 docker]# docker run -it --rm webserver:v3 bash bash-4.2# ldd /usr/local/nginx/sbin/nginx linux-vdso.so.1 => (0x00007ffc06f6d000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f3560c8a000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3560a6e000) libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f3560837000) libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f35605d6000) libz.so.1 => /lib64/libz.so.1 (0x00007f35603c0000) libc.so.6 => /lib64/libc.so.6 (0x00007f355ffff000) /lib64/ld-linux-x86-64.so.2 (0x00007f3560e8e000) libfreebl3.so => /lib64/libfreebl3.so (0x00007f355fd80000)
Search github for destroy, Google's container tool.
download
I use debian10 to import images.
[root@docker1 docker]# docker load -i base-debian10.tar
The base image is small
[root@docker1 docker]# docker images gcr.io/distroless/base-debian10 latest d48fcdd54946 52 years ago 19.2MB
First, search github for troubleshooting nginx and go in
Then check the Dockerfile written by others. It can be seen that it uses the smallest image provided by the official, and it is a multi-stage construction, and the library file of the system is included.
Write Dockerfile2
[root@docker1 docker]# cat Dockerfile2 FROM nginx:1.18.0 as base # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones ARG TIME_ZONE RUN mkdir -p /opt/var/cache/nginx && \ cp -a --parents /usr/lib/nginx /opt && \ cp -a --parents /usr/share/nginx /opt && \ cp -a --parents /var/log/nginx /opt && \ cp -aL --parents /var/run /opt && \ cp -a --parents /etc/nginx /opt && \ cp -a --parents /etc/passwd /opt && \ cp -a --parents /etc/group /opt && \ cp -a --parents /usr/sbin/nginx /opt && \ cp -a --parents /usr/sbin/nginx-debug /opt && \ cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \ cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \ cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \ cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime FROM gcr.io/distroless/base-debian10 COPY --from=base /opt / EXPOSE 80 443 ENTRYPOINT ["nginx", "-g", "daemon off;"]
To build an image, - f specify dockerfile2, otherwise the default Dockerfile will be read
[root@docker1 docker]# docker build -t webserver:v4 -f Dockerfile2 .
effect
[root@docker1 docker]# docker images webserver REPOSITORY TAG IMAGE ID CREATED SIZE webserver v4 0fce27d5ac56 15 seconds ago 31.7MB
Run the container successfully.
[root@docker1 docker]# docker run -d --name nginx webserver:v4 [root@docker1 docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 79bc3e329d8f webserver:v4 "nginx -g 'daemon of..." 23 seconds ago Up 22 seconds 80/tcp, 443/tcp nginx
[root@docker1 docker]# docker inspect nginx | grep IP "IPAddress": "172.17.0.2",
Visit successful
[root@docker1 docker]# curl 172.17.0.2 <h1>Welcome to nginx!</h1>