Dockerfile
The customization of the image is actually customizing the configuration and files that are added to each layer. If we could write each layer of modify, install, build, and manipulate commands into a script, and use this script to build and customize the image, this script would be a Dockerfile.
Dockerfile is a text file containing instructions, each Instruction builds a layer, so the content of each Instruction describes how the layer should be built.
Create a mirror image
Take nginx mirroring as an example
- In a blank directory, create a text file and name it
Dockerfile
$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile
Copy the code
Its contents are as follows:
FROM nginx RUN echo '<h1>Hello, Docker! </h1>' > /usr/share/nginx/html/index.htmlCopy the code
This Dockerfile is very simple, just two lines in total. There are two instructions involved, FROM and RUN.
FROM Specifies the base image
Custom mirror, that must be based on a mirror, on which to customize. Just as we ran an Nginx image container and then modified it, the base image must be specified. FROM specifies the base image, so in a Dockerfile, FROM is the required instruction and must be the first instruction.
Docker Hub has a lot of high quality official images, there are directly used service class images, such as Nginx, Redis, Mongo, mysql, HTTPD, PHP, tomcat, etc. There are also images for developing, building, and running applications in various languages, such as Node, OpenJDK, Python, Ruby, Golang, etc. We can customize the base image by looking for the one that best fits our final goal.
If you cannot find the corresponding service image, the official image also provides some more basic OPERATING system images, such as Ubuntu, Debian, centos, Fedora, alpine, and so on. These operating system software libraries provide a broader space for expansion.
In addition to choosing an existing image as the base image, Docker also has a special image called Scratch. This image is a virtual concept, it does not exist, it represents a blank image.
Scratch blank image
FROM scratch
...
Copy the code
RUN RUN command
The RUN command is used to execute command line commands. Because of the power of the command line, the RUN directive is one of the most commonly used directives when customizing images. There are two formats:
- shellFormat:
RUN < command >
, just like a command typed directly from the command line. In the Dockerfile I just wroteRUN
Instructions are in this format.
RUN echo '<h1>Hello, Docker! </h1>' > /usr/share/nginx/html/index.htmlCopy the code
- execFormat:
RUN [" executable ", "parameter 1"," parameter 2"]
This is more like the format in a function call.
Since RUN can execute commands just like Shell scripts, can we have a RUN for each command just like Shell scripts? Like this:
FROM debian:stretch RUN apt-get update RUN apt-get install -y gcc libc6-dev make wget RUN wget -O redis.tar.gz "Http://download.redis.io/releases/redis-5.0.3.tar.gz" RUN the mkdir -p/usr/SRC/redis RUN tar - XZF redis. Tar. Gz - C /usr/src/redis --strip-components=1 RUN make -C /usr/src/redis RUN make -C /usr/src/redis installCopy the code
Each instruction in a Dockerfile creates a layer, and RUN is no exception. The behavior of each RUN is the same as that of the manual mirroring process: create a new layer, execute these commands on it, and commit the layer changes to form a new image.
This way, it creates seven mirrors. This makes no sense at all, and many things that are not needed at runtime are loaded into the image, such as compilation environments, updated packages, and so on. The result is a very bloated, multi-tiered image that not only increases build and deployment time, but is also prone to error.
Union FS has a maximum number of layers, such as AUFS, which used to have a maximum of 42 layers, now has a maximum of 127 layers.
The correct way to write the Dockerfile above should look like this:
FROM debian:stretch RUN set -x; buildDeps='gcc libc6-dev make wget' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "Http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && mkdir -p/usr/SRC/redis \ && tar - XZF redis. Tar. Gz - C /usr/src/redis --strip-components=1 \ && make -C /usr/src/redis \ && make -C /usr/src/redis install \ && rm -rf /var/lib/apt/lists/* \ && rm redis.tar.gz \ && rm -r /usr/src/redis \ && apt-get purge -y --auto-remove $buildDepsCopy the code
First of all, all the previous commands had only one purpose, which was to compile and install the Redis executable. So there’s no need to build many layers, it’s just a one layer thing. Therefore, instead of using multiple runs to correspond to different commands, you use just one RUN directive and chain the required commands together using &&. I’m going to simplify the previous 7 layers to 1 layer. When writing a Dockerfile, always remind yourself that you are not writing a Shell script, but defining how each layer should be built.
Also, there are line breaks for formatting purposes. Dockerfile supports Shell classes to add ‘ ‘to the end of the line, as well as the first line of the comment format. Good formatting, such as line breaks, indentation, comments, etc., makes maintenance and elimination easier, which is a good habit.
In addition, you can also see that a cleanup command was added at the end of this set of commands, deleting the software needed for the build, cleaning up all downloaded and expanded files, and cleaning up the APT cache files. This is an important step, as we said before, mirrors are layers of storage, and things on each layer don’t get deleted from the next layer, they follow the image. So when building a mirror, make sure that each layer only adds what really needs to be added. Anything that doesn’t need to be added should be removed.
Build the mirror
Run the following command in the Dockerfile directory:
docker build -t nginx:v3 .
$docker build -t nginx:v3. Sending build context to docker daemon 2.048 kB Step 1: FROM nginx ---> e43d811ce2f4 Step 2 : RUN echo '<h1>Hello, Docker! </h1>' > /usr/share/nginx/html/index.html ---> Running in 9cdc27646c7b ---> 44aa4490ce2c Removing intermediate container 9cdc27646c7b Successfully built 44aa4490ce2cCopy the code
We used the Docker build command to build the image. The format is:
Docker build [options] < context path /URL/->Copy the code
We specify the final image name -t nginx:v3. After the build is successful, we can use docker run-dp 82:80 nginx to start the image
conclusion
1. Create Dockerfile and write instructions
2. Use Docker Bulid to build an image