Write in front
In this short composition, we will learn another key problem of image construction. Why is the image created by others only 10MB and mine a few hundred MB? How to thin the mirror and reduce the mirror volume?
We can cut into thin image from two aspects:
- Reduce the number of mirror layers
- Reduced capacity
1, Reduce the number of mirror layers
1. Instruction consolidation
Each instruction in Dockerfile will create a layer, but the best practice in the official document is as follows:
In older versions of Docker, it was important that you minimized the number of layers in your images to ensure they were performant. The following features were added to reduce this limitation:
-
Only the instructions RUN, COPY, ADD create layers. Other instructions create temporary intermediate images, and do not increase the size of the build.
...
Reference address: Minimize the number of layers
This means that only the RUN, COPY and ADD instructions will create a layer, and other instructions will create an intermediate image without affecting the image size. In this way, the instruction combination we call is mainly based on these three instructions.
Let's take the Dockerfile as an example
FROM debian:stable WORKDIR /var/www LABEL version="v1" RUN apt-get update RUN apt-get -y --no-install-recommends install curl RUN apt-get purge -y curl RUN apt-get autoremove -y RUN apt-get clean RUN rm -rf /var/lib/apt/lists/*
Build mirror
docker build -t curl:v1 .
View construction history through history
# docker history curl:v1 IMAGE CREATED CREATED BY SIZE COMMENT 29b721c09b67 18 seconds ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0B aa28ae151e59 20 seconds ago /bin/sh -c apt-get clean 0B 4f733781f557 22 seconds ago /bin/sh -c apt-get autoremove -y 989kB f66887372121 29 seconds ago /bin/sh -c apt-get purge -y curl 987kB d458ee0de463 34 seconds ago /bin/sh -c apt-get -y --no-install-recommend... 4.46MB 43fdcf68018c 44 seconds ago /bin/sh -c apt-get update 17.6MB 65631e8bb010 53 seconds ago /bin/sh -c #(nop) LABEL version="v1" 0B 7ef7c53b019c 53 seconds ago /bin/sh -c #(nop) WORKDIR /var/www 0B 8bfa93572e55 13 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 13 days ago /bin/sh -c #(nop) ADD file:d78d93eff67b18592... 124MB
Mirror size
[root@localhost dockerfiles]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE curl v1 29b721c09b67 10 minutes ago 148MB
We combine RUN instructions through shell like operations & & and
RUN apt-get update && \ apt-get -y --no-install-recommends install curl && \ apt-get purge -y curl && \ apt-get autoremove -y && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
View construction history and mirror size
# docker history curl:v2 IMAGE CREATED CREATED BY SIZE COMMENT 928e12c2f57e About a minute ago /bin/sh -c apt-get update && apt-get -y ... 989kB 5a32372025fb About a minute ago /bin/sh -c #(nop) LABEL version="v2" 0B 7ef7c53b019c 30 minutes ago /bin/sh -c #(nop) WORKDIR /var/www 0B 8bfa93572e55 13 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 13 days ago /bin/sh -c #(nop) ADD file:d78d93eff67b18592... 124MB # docker images REPOSITORY TAG IMAGE ID CREATED SIZE curl v2 928e12c2f57e 3 minutes ago 125MB
It can be seen that only a simple curl application has been installed through instruction merging, and the capacity has been released by about 20MB. At the same time, it makes your dockerfile file easier to read and simpler.
2. Multi-stage construction
In docker17 05 introduces multi-stage construction, which can greatly reduce the construction complexity and make it easier to reduce the image size. Let's look at the Dockerfile built in multiple stages
#Phase 1 FROM golang:1.16 WORKDIR /go/src COPY app.go ./ RUN go build app.go -o myapp #Phase 2 FROM scratch WORKDIR /server COPY --from=0 /go/src/myapp ./ CMD ["./myapp"]
Build mirror
# docker build --no-cache -t server_app:v2 .
View the built image
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE server_app v2 20225cb1ea6b 12 seconds ago 1.94MB
The above use cases are from the previous article Dockerfile multi-stage construction practice You can check the specific content of image multi-stage construction, which will not be described here.
3. Enable the square feature
By enabling the square feature (experimental function) docker build -- square - t curl: V3, the built image can be compressed into one layer. However, in order to give full play to the superior design of container image layer sharing, this method is not recommended.
2, Reduced capacity
1. Select a small basic image
The size of each linux distribution image varies a lot, even for the same distribution. Let's take debian as an example:
The difference between the stable version and the slimming version is about 40MB
# docker images debian stable-slim 2aa48a485e3a 13 days ago 80.4MB debian stable 8bfa93572e55 13 days ago 124MB
We change the basic image in Dockerfile to Debian: stable slim
FROM debian:stable-slim
The mirror size after construction is smaller
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE curl v4 1aab5c9bf8b3 17 seconds ago 81.4MB
The current image is Debian based and contains many binaries. The Docker container should contain a process and the minimum required to run it. We don't really need the entire operating system.
We can replace the Debian base image with an Alpine based image.
FROM alpine WORKDIR /var/www LABEL version="v5" RUN echo -e 'https://mirrors.aliyun.com/alpine/v3.6/main/\nhttps://mirrors.aliyun.com/alpine/v3.6/community/' > /etc/apk/repositories && \ apk update && \ apk upgrade && \ apk add --no-cache curl
View mirror size
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE curl v5 7f735bb213be 11 seconds ago 10.1MB
At this point, our image comes to 10MB. The alpine image package management tool is apk, and some package names may be different. The biggest difference
2. Context management
We often use the COPY instruction
COPY . /server/dir
COPY copies the entire} build context into the image and produces a new cache layer. In order to load unnecessary files such as logs, cache files and Git history into the construction context, we'd better add them Dockeignore is used to ignore non mandatory files. This is also a key step in streamlining the image, and can better ensure the security of the image we build.
3. Clean up and download in time
We have the following Dockerfile
.. WORKDIR /tmp RUN curl -LO https://docker.com/download.zip && tar -xf download.zip -C /var/www RUN rm -f download.zip ...
Although we used rm to delete download Zip package. Due to the problem of image layering, download Zip is deleted in a new layer, and the previous layer still exists.
We need to clean up and download in time on the first floor
RUN curl -LO https://docker.com/download.zip && tar -xf download.zip -C /var/www && rm -f download.zip
In addition, when installing the software, you should use the package management tool to clear the software dependency and cache you downloaded in time, such as using apt package management tool in our dockerfile.
Here are the operations related to thin mirroring.