To get a quick primer on Dockerfile let’s take a look at a simple example

First we pull down a mysql:5.7 image from the mirror repository

Start the container and enter the container

Then we try to ping www.baidu.com and find that there is no ping command

If we happen to have this need, it will be very awkward. What can be done to solve it?

We can rebuild a new image based on mysql:5.7 and add what we want; Let’s take a look at the following Dockerfile content

FROM mysql:5.7

 RUN apt-get update && apt install iputils-ping -y

RUN apt-get install vim -y
Copy the code

Here we have the ping and vim tools installed (note to check the distribution information by cat /etc/issue, the installation tool command will be different for different versions).

Start building the image from Dockerfile

We’ll start building with this Dockerfile:

docker build -t mysql:mumu .
Copy the code

We can see that the build process is divided into three steps, which correspond exactly to the three commands in our Dockerfile

When the build is complete, we can see that it is 53MB larger than mysql:5.7

Start the container we built

After mirroring we can start the container:

docker run -p 3306:3306 --name mysql -v /data/mysql/data:/var/lib/mysql  -e MYSQL_ROOT_PASSWORD=123456  -d mysql:mumu
Copy the code

When we ping Baidu after startup, we can see that our tool is working normally

Through the above case we have a preliminary understanding of Dockerfile? Roughly have the following understanding

  • Dockerfile is used to build the image

  • Dockerfile Each instruction corresponds to a step

  • We can use Dockerfile to customize the image we need

We use another Dockerfile to understand the concept of image layering:

FROM debian

RUN apt-get update && apt-get -y -f install emacs

RUN apt-get update && apt-get -y -f install apache2
Copy the code

Its construction process can be understood as the superposition process of multiple images

Each instruction in the Dockerfile creates a new layer, layer upon layer, to form the image we want

For example, this command creates three layers, each of which records only the changes made to its own layer, and these layers are read-only. When a container is started, Docker adds a read-write layer at the top, which is commonly referred to as the container layer.

Each container has its own independent container layer, so the changes will only exist in its own container layer and will not affect each other. This way, different containers can share a mirror layer.

Why a layered structure?

The biggest advantage is sharing resources. For example, many images are built from base images. After saving a copy to disk, all images can be shared

For example, if the image derived container changes the file inside it, such as modifying a file under /opt, will the /opt file in other containers also be changed?

We mentioned the container layer above, which is per-container independent. The modified data is stored directly in the container layer, and the mirror layer remains unchanged.

Introduction to the Dockerfile command

FROM: Specifies the base mirror. It must be the first command

FROM <image>:<tag>

FROM <image>@<digest>
Copy the code

Example:

The FROM elasticsearch: 7.6.0Copy the code

Note: Tag and digest are optional, and the latest version of the base image is automatically used if empty

MAINTAINER: MAINTAINER information

MAINTAINER <name>
Copy the code

Example:

MAINTAINER mumu

MAINTAINER [email protected]

MAINTAINER mumu<[email protected]>
Copy the code

RUN: indicates the command executed during image construction

RUN <command>

RUN ["executable", "param1", "param2"]
Copy the code

Example:

RUN apk update

RUN ["./test", "dev", "offline"]
Copy the code

Note: The intermediate image created by the RUN directive is cached and used in the next build. If you don’t want to use these cache images, you can use the –no-cache parameter when building a build, such as docker build –no-cache

ADD: ADD local files to the container. Tar files are automatically decompressed (network compressed resources are not decompressed), and network resources can be accessed, similar to wget

ADD <src>   <dest>
Copy the code

Example:

ADD  mumu.txt /mydir/
Copy the code

Note: COPY is similar to ADD, but does not automatically extract files or access network resources

CMD: called after the container is built, that is, when the container is started.

CMD ["executable", "param1", "param2"] CMD ["param1", "param2"] CMD command param1 param2Copy the code

Example:

CMD ["java", "-jar" ,"/opt/server/product.jar"]
Copy the code

Note: CMD is used to specify the commands to be executed when the container is started, while RUN is used to specify the commands to be executed when the image is built. Each Dockerfile can have only one CMD command. If multiple commands are specified, only the last one will be executed. If you specify a run command when you start the container, the CMD command will be overwritten.

ENTRYPOINT: Configure the container to be executable, with CMD to omit application and use only parameters.

ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param2Copy the code

Example:

ENTRYPOINT ["/bin/echo", "hello"]
Copy the code

Note: ENTRYPOINT is very similar to CMD, but the commands executed by Docker run do not overwrite ENTRYPOINT. However, if a docker run uses the — ENTRYPOINT option, The parameters of this option override the program specified by the ENTYPPOINT directive as the program to be run, and any parameters specified in the Docker run command are passed to ENTRYPOINT as parameters. Only one ENTRYPOINT command is allowed in a DockerFile. If multiple ENTRYPOINT commands are specified, the previous one will be overridden and only the last one will be executed.

When ENTRYPOINT is specified, the meaning of CMD changes. Instead of running the command directly, the contents of CMD are passed to the ENTRYPOINT directive as arguments. In other words, the actual execution will become “”.

If I’m getting a little confused here, what does CMD have to do with ENTRYPOINT?

In Dockerfile, you should specify at least one CMD and ENTRYPOINT;

Docker should be configured as an executable using ENTRYPOINT;

CMD can be used as the default argument to ENTRYPOINT or as the default command for Docker;

CMD can be overridden by arguments passed in by docker run;

Arguments passed in by docker Run are appended to ENTRYPOINT, provided the exec format is used

For example, let’s look at the following Dockerfile:

FROM nginx

ENTRYPOINT ["nginx", "-c"]

CMD ["/etc/nginx/nginx.conf"]
Copy the code

When we enable nginx: docker run nginx:mumu

The following command is executed: nginx -c /etc/nginx/nginx.conf

Docker run nginx:mumu -c /etc/nginx/new.conf

Run the following command: nginx -c /etc/nginx/new.conf

LABEL: adds metadata to an image

LABEL <key>=<value>  <key>=<value>  <key>=<value>
Copy the code

Example:

LABEL version="1.0" descriptioin=" This is descriptioin"Copy the code

Note: When using LABEL to specify metadata, a LABEL can specify one or more metadata, separated by Spaces. It is recommended to specify all metadata through a LABEL directive to avoid generating too many intermediate images.

ENV: Sets environment variables

ENV <key> <value> Only one variable can be set at a time. All variables following key are treated as value ENV <key>=<value>... Multiple variables can be set, each as a "<key>=<value>" key-value pair,Copy the code

If the character contains a space, you can use \ to escape

Example:

ENV username admin

ENV password 123456

ENV port=3306
Copy the code

EXPOSE: Specifies the port for external interaction

EXPOSE <port> [<port>...]
Copy the code

Example:

EXPOSE 80 443

EXPOSE 11221/tcp  11221/udp
Copy the code

Note that the EXPOSE command only states that the container should open ports and doesn’t actually open them. If you don’t specify the ports to map with -p, the container won’t map them out. To make them accessible, these ports need to be specified with -p during Docker run

VOLUME: specifies the persistent directory

VOLUME ["/path/to/dir"]
Copy the code

Example:

VOLUME ["/ect/nginx/con.d"]

VOLUME["/etc/nginx/con.d", "/etc/nginx/logs" ]
Copy the code

Description: container runtime should try to keep the container storage layer don’t write operation, in order to prevent users from runtime forget to save dynamic document directory mounted as volumes, we can advance in Dokcerfile specify certain directory mounted as anonymous, so even if the user does not specify a mount, its will not to write a lot of container storage layer data; It cannot specify the corresponding directory on the host and is automatically generated.

Note: Volumes can be shared with other containers, and their life cycle is independent of the container. Docker does not automatically delete volumes after the container is deleted, and there is no garbage collection mechanism for handling volumes referenced by any container if the container needs to be removed at the same time. You can use the docker rm -v command to delete containers

WORKDIR: working directory, similar to the CD command

WORKDIR /path/to/dir
Copy the code

Example:

WORKDIR /etc WORKDIR nginxCopy the code

Note: After the WORKDIR directory is set, all subsequent commands in the Dockerfile are executed in the specified directory. The working directory of the Dockerfile can be overwritten with -w while the container is running.

USER: Specifies the USER name or UID for running the container, which will be used in subsequent commands.

USER user

USER uid

USER uid:gid

USER user:gid

USER uid:group

USER user:group
Copy the code

Example:

USER mumu
Copy the code

Note: When you specify a USER using USER, all commands following Dockerfile will use that USER, but you can override the specified USER when running the container with the -u argument.

ARG: Used to specify variables passed to the build run time

ARG <name>[=<default value]
Copy the code

Example:

ARG site

ARG user=mumu
Copy the code

Note: If the ARG specifies a default value and no value is passed in during the build, the default value is used.

ONBUILD: Used to set the mirror trigger

ONBUILD [INSTRUCTION]
Copy the code

Example:

ONBUILD ADD . /etc/nginx

ONBUILD RUN
Copy the code

Note: Its parameters can be any A Dockerfile instruction, the instruction was not substantial influence on the current mirror (the current mirror called A), but if the mirror image based on A, B, then in the process of building image B will perform its instructions, but when A B C will not perform this instruction (can be understood as cannot atavism, ha ha).

Here is another case to test our learning achievements:

Let’s take a look at nginx:latest version of Dokcerfile, with the comments removed for neatness

FROM Debian: Bust-Slim LABEL Maintainer ="NGINX Docker Maintainers <[email protected]>" ENV NGINX_VERSION 1.19.6 ENV NJS_VERSION 0.5.0 ENV PKG_RELEASE 1~ Buster RUN set -x \ COPY docker-entrypoint.sh/COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d COPY 20-envsubst-on-templates.sh /docker-entrypoint.d ENTRYPOINT ["/docker-entrypoint.sh"] EXPOSE 80 STOPSIGNAL SIGQUIT CMD ["nginx", "-g", "daemon off;"]Copy the code
  • Reference base mirror: Debian: Bust-Slim
  • Add source data: Maintainer =”NGINX Docker Maintainers [email protected]
  • Three environment variables are introduced: NGINX_VERSION 1.19.6 NJS_VERSION 0.5.0 PKG_RELEASE 1~ BUSTER
  • Execute the command set-x, which is the shell’s command to print the command to the screen.
  • . Copies the three files to the specified location
  • / docker-entrypoint. sh nginx -g daemon off
  • Specify port 80
  • STOPSIGNAL was introduced after Docker1.9. This command is sent to the system call signal pushed out by the container, for example, what operation should be performed before exiting the system