In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/03 Report--
This article shows the introduction of the Dockerfile configuration file in the Docker container. This article mainly introduces the process of Docker executing Dockerfile, the structure of Dockerfile, common Dockerfile instructions and image cache, which can be referenced by partners who need it.
Introduction to Dockerfile
Dockerfile is the configuration file used in Docker to define the automated build process for images. In Dockerfile, there are commands and other actions that need to be performed during the process of building the image. Through Dockerfile, the production process of a given Docker image can be more clearly and clearly. Because it is only a simple, small size file, and the transmission speed is fast in the network and other media, container migration and cluster deployment can be realized faster.
Dockerfile is a text file that contains instructions, each of which builds a layer, so the content of each instruction is to describe how the layer should be built.
Compared with submitting container modifications in the way of image migration, using Dockerfile has many advantages:
Dockerfile is much smaller than the mirror package, making it easier to migrate and deploy quickly. The environment build process is recorded in Dockerfile, and the sequence and logic of image construction can be seen visually. Building an image using Dockerfile makes it easier to automate processes such as automatic deployment. When modifying the environment build details, it is easier to modify the Dockerfile file.
In actual development and use, container submission is rarely chosen to build the image, but almost Dockerfile is used to make the image.
The general process for Docker to execute Dockerfile: (1) docker runs a container (2) from the base image specified by the Dockerfile header FROM and then executes an instruction to modify the container. (3) then do something similar to docker commit to create a new mirror layer. (4) run a new container based on the image just created. (4) execute the next instruction in dockerfile until all instructions have been executed.
Docker deletes the container created by the middle tier, but not the middle tier image, so you can use docker run to run a middle tier container to view the image status after each step of the build, so that you can debug.
Basic structure of Dockerfile
Dockerfile consists of another line of command statements and supports comment lines that begin with #.
Dockerfile is divided into four parts: basic image information, maintainer information, mirror operation instructions, and instructions to execute when the container starts.
For example, the following is a complete Dockerfile:
# This dockerfile uses the ubuntu image# VERSION 2-EDITION mirror Author: docker_user# Command format: Instruction [arguments / command]. # Base image to use, this must be set as the first line1, the first line must specify basic image information FROM ubuntu# Maintainer: docker_user (@ docker_user) 2, maintainer information MAINTAINER docker_user docker_user@email.com# Commands to update the image3 Mirror operation instruction RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" > > / etc/apt/sources.listRUN apt-get update & & apt-get install-y nginxRUN echo "\ ndaemon off "> > / etc/nginx/nginx.conf# Commands when creating a new container4, container startup execution instruction CMD / usr/sbin/nginx
In the beginning, you must specify the name of the image on which you are based, followed by maintainer information, followed by mirror operation instructions, such as the RUN instruction. Each time a RUN instruction is executed, the mirror adds a new layer and submits it; finally, the CMD instruction indicates the operation command when the container is run.
Dockerfile common instructions
The following common dockerfile instructions basically contain 90% of the commonly used functions.
Common instruction directory: 1 mirroring FROMmure-specify basic image 2MAINTAINERMAINERMAINERMAINERMAINERMY-specify maintainer information 3GRUNMAINERMAINERMAINERMAINERMY-run the specified command 4 EXPOSE-- color-commands executed when the container is started, EXPOSE-- declares that the service port of the container 6 is powerful, set the environment variable 7, ARGlam, build parameter 8, copy files or directories, copy files or directories, 9 copy ADD houses, more advanced replication files / directories, 10 entry points, 11 ENTRYPOINT is used in conjunction with the CMD directive 12Magi Volume-Definitions Anonymous Volume 13JWORKDIRMI-specify working Directory 14Go USERLY-specify current user 15J ONBUILDMY-add triggers for image
1memeFROMMAY-specify the basic image
The first instruction must be a FROM instruction.
If it is not based on any image, it is written as follows, which also means that the next instruction will start as the first layer of the mirror:
FROM nginx
The FROM instruction supports three formats:
FROM
FROM:
FROM:
There are three ways to write, the second and the third are optional, if not selected, then the default is latest.
The FROM instruction can appear multiple times in Dockerfile. When the FROM appears for the second time or later, it means that when building at this time, the contents currently indicated by the image should be merged with the contents of the current build image.
ARG is the only parameter that can be executed before FROM:
ARG CODE_VERSION=latestFROM base:$ {CODE_VERSION} CMD / code/run-appFROM extras:$ {CODE_VERSION} CMD / code/run-extras
2MAINTAINERR-specify maintainer information
Format: MAINTAINER, specify maintainer information (mirror maintainer name or mailbox), optional.
For example:
MAINTAINER docker_user docker_user@email.com
3. Run the specified command.
RUN has two formats:
RUN
RUN ["executable", "param1", "param2"]
The former will run the command / bin/sh-c on the shell terminal; the latter will be executed using exec. Specifying the use of other terminals can be done in a second way, such as using bash terminals: RUN ["/ bin/bash", "- c", "echo hello"].
Note: multi-line commands do not write multiple RUN, because each instruction in Dockerfile will build a layer, and the number of RUN will build as many layers of images, resulting in bloated and multi-tiered images, which will not only increase the time for component deployment, but also prone to errors. Generally, a RUN instruction can be followed by multiple commands to be executed (using the & & symbol), and when the command is long, you can use "\" to wrap the line.
Examples are as follows:
RUN yum-y install gcc* pcre-devel openssl-devel zlib-devel unzip make vim net-tools elinks tree\ & & groupadd nginx\ & & useradd nginx-g nginx-s / sbin/nologin
4CMD talk-commands executed when the container is started
CMD supports three formats:
CMD ["executable", "param1", "param2"] is executed using exec, recommended
CMD command param1 param2 is executed in / bin/sh and provided to applications that need to interact
Default parameters provided to ENTRYPOINT by CMD ["param1", "param2"]
Specifies the command to be executed when the container is started, and there can be only one CMD command per dockerfile. If multiple commands are instructed, only the last one will be executed.
If the user starts the container and specifies the command to run, the command specified by CMD will be overwritten.
Additional details: if you do not use shell (/ bin/sh), the parentheses that include parameters in "[]" must be in double quotation marks, never in single quotation marks. The reason is that after the parameter is passed, docker parses a JSON array
For example:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centos:latestCMD echo hello worldCMD echo hello china [root@sqm-docker01 dfs] # docker run-- rm test:v1 # only the last CMD command will be executed hello china [root@sqm-docker01 dfs] # docker run-- rm test:v1 echo "hello friend" # specify the run command when starting the container, which will overwrite the hello friend
In exec format, the above example is changed to:
FROM centos:latestCMD ["/ bin/bash", "- c", "echo hello world"] CMD ["/ bin/bash", "- c", "echo hello china"]
There is also a case where CMD is used in conjunction with the ENTRYPOINT instruction, which will be discussed later.
5. EXPOSE-- declares the service port of the container
The format is EXPOSE [...].
The EXPOSE directive declares that the runtime container provides a service port, which is just a declaration that the service on this port will not be opened by the application at runtime because of this declaration.
Writing such a declaration in Dockerfile has two advantages: one is to help mirror consumers understand the daemon port of the mirror service to facilitate configuration mapping, and the other is that when the runtime uses random port mapping, that is, docker run-P, EXPOSE ports are automatically randomly mapped.
Distinguish EXPOSE from using-p: at run time. -p, which maps the host port and the container port, in other words, exposes the corresponding port service of the container to external access, while EXPOSE only declares what port the container intends to use and does not automatically map the port in the host.
For example:
EXPOSE 80 443
6century ENV talk-set the environment variable
There are two formats:
ENV
ENV = =...
The difference between the two is that the first is to set one at a time, and the second is to set more than one at a time.
The ENV directive is to specify an environment variable that will be used by subsequent RUN and maintained while the container is running.
ENV VERSION=1.0 DEBUG=on\ NAME= "Happy Feet"
This example demonstrates how to wrap lines and enclose values containing spaces in double quotes, which is consistent with the behavior under shell.
Examples are as follows:
[root@sqm-docker01 dfs] # cat Dockerfile FROM busybox:latestENV var1= var2=heheRUN echo $var1 > a.txt & & echo $var2 > b.txt after executing dockerfile, view the container file: [root@sqm-docker01 dfs] # docker run-- rm test:v2 / bin/sh/ # cat a.txt / # cat b.txt hehe# and the defined variables will be maintained during the container run: / # echo $var1/ # echo $var2hehe
7 ARG talk-build parameters
Format:
ARG [=]
The build parameters have the same effect as ENV, setting environment variables. The difference is that the environment variables set by ARG for the build environment will not exist when the container runs in the future. But don't use ARG to save information like passwords, because docker history can still see all the values.
# usage 1: pass parameters when performing a docker build build
[root@sqm-docker01 dfs] # cat Dockerfile FROM nginx:latestARG userARG passwordRUN echo $user > a.txt\ & & echo $password > > a.txt# passes two parameters, then add-- build-arg to each parameter. [root@sqm-docker01 dfs] # docker build--build-arg user=sqm-- build-arg password=123.com-t arg:v1. # run the container with parameters passed successfully [root@sqm-docker01 dfs] # docker run-it-- rm arg:v1 / bin/bashroot@4809b0c54f8d:/# cat a.txt sqm123.com#, unlike ENV, is root@9383b7d3d21e:/# echo $userroot@9383b7d3d21e:/# echo $passwordroot@9383b7d3d21e:/# in which these variables do not exist in the container
Note: if this parameter is specified but not used in Dockerfile, a warning will be output during the build process.
# usage 2: set a default value in dockerfile. If the ARG instruction has a default value and no parameters are passed during the build, then the build will use the default value
[root@sqm-docker01 dfs] # cat Dockerfile FROM nginx:latestARG user=zhangsanARG password=123456RUN echo $user $password > a.txt# builds the image without passing any parameters: [root@sqm-docker01 dfs] # docker build-t arg:v2. # run the container, and the parameters are passed successfully [root@sqm-docker01 dfs] # docker run-it-- rm arg:v2 / bin/bashroot@b52fa70086de:/# cat a.txt zhangsan 123456
# each phase of a multi-phase build must contain an arg directive:
FROM busyboxARG userRUN. / run/setup $userFROM busyboxARG userRUN. / run/other $user
# ENV variable overrides the ARG variable with the same name:
[root@sqm-docker01 dfs] # cat Dockerfile FROM nginx:latestARG user=zhangsanENV user lisiRUN echo $user > a.txt [root@sqm-docker01 dfs] # docker build-t arg:v3. [root@sqm-docker01 dfs] # docker run-it-- rm arg:v3 / bin/bashroot@a2aefd05efee:/# cat a.txt lisi
# ARG is used in conjunction with the ENV instruction: (general usage, not commonly used)
[root@sqm-docker01 dfs] # cat Dockerfile FROM centosARG varENV user=$ {var} RUN echo $user > a.txt [root@sqm-docker01 dfs] # docker build--build-arg var=zhangsan-t arg:v4. [root@sqm-docker01 dfs] # docker run-it-- rm arg:v4 / bin/bash [root@26bf8c139a3f /] # cat a.txt zhangsan
8 copy copy file or directory'
Format:
COPY [--chown=:]...
COPY [--chown=:] [",..."]
Like RUN instructions, there are two formats, the former runs on the shell terminal, and the latter is executed using exec.
The path on the host can be multiple or even wildcards. The wildcard rules must meet the filepath.Match rules of Go, such as:
COPY hom* / mydir/COPY hom?.txt / mydir/
Is the path in the container, either absolute or relative to the working directory (which can be specified with the WORKDIR directive). The destination path does not need to be created beforehand, and if the directory does not exist, the missing directory will be created before copying the file.
In addition, it is important to note that with the COPY directive, all kinds of metadata for the source file are retained. Such as read, write, execution permissions, file change time, and so on. You can specify it using the following command:
COPY [--chown=:]... COPY [--chown=:] [",..."] (paths containing spaces need this form)
-the chown feature is only supported on the Dockerfiles used to build Linux containers
For example:
COPY-chown=nginx:nginx files* / somedir/
For example:
[root@sqm-docker01 dfs] # echo "hello world" > index.html [root@sqm-docker01 dfs] # echo aaaaaa > a.txt [root@sqm-docker01 dfs] # cat Dockerfile FROM nginx:latestCOPY. / index.html / usr/share/nginx/html/COPY. / a.txt / test/ [root@sqm-docker01 dfs] # docker run-rm nginx:v1 / bin/bashroot@8a1ee4925b43:/# cat / usr/share/nginx/html/index.html hello world# even if the target directory does not exist Will create root@8a1ee4925b43:/# cat / test/a.txt aaaaaa beforehand
# # copy the entire directory:
Format: COPY src WORKDIR/src
For example:
[root@sqm-docker01 dfs] # cat test/a.txt addddddddddddaaaaa [root@sqm-docker01 dfs] # cat Dockerfile FROM nginx:latestCOPY. / test/ usr/share/nginx/test/ # must specify the directory to be copied under the destination path, otherwise only the files in the source directory must be copied Instead of copying the directory # enter the container to view the entire directory and the files under it [root@sqm-docker01 dfs] # docker run-- rm nginx:v2 / bin/bashroot@4eae96cbe364:/# cd / usr/share/nginx/root@4eae96cbe364:/usr/share/nginx# lshtml testroot@4eae96cbe364:/usr/share/nginx# cat test/a.txt addddddddddddaaaaa
9recoverADDMusi-more advanced copy files / directories
The format is:
ADD [--chown=:]...
ADD [--chown=:] [",..."]
The format and nature of the ADD instruction and COPY are basically the same. However, some features have been added to COPY`: it can be a URL (automatically set permissions 600 when downloaded through URL), or a tar file (automatically decompressed to a directory).
For example:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centosADD nginx-1.8.0.tar.gz / usr/src [root@sqm-docker01 dfs] # docker run-- rm nginx:v3 / bin/bash [root@0c8d6789aa4c /] # cd / usr/src/ [root@0c8d6789aa4c src] # ls debug kernels nginx-1.8.0 # automatically extract tar package [root@0c8d6789aa4c src] # ls nginx-1.8.0/CHANGES CHANGES.ru LICENSE README auto conf configure contrib html man src
# download the link file through url and put it under the destination path:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centosADD http://nginx.org/download/nginx-1.9.0.tar.gz / [root@sqm-docker01 dfs] # docker run-- rm nginx:v4 / bin/bash [root@b9d978e3a333 /] # ls-lh nginx-1.9.0.tar.gz-rw- 1 root root 835K Apr 28 2015 nginx-1.9.0.tar.gz# default permission
# the difference between COPY and
It is similar to COPY, except that COPY can only be local files / directories. If src is an archive file (tar,zip,tgz,xz, etc.), files using the ADD command will be automatically extracted to dest.
So when choosing between the COPY and ADD instructions, you can follow the principle that all file copies use COPY, and use ADD only where automatic decompression is required.
10memeENTRYPOINTRAY-entry point
There are two formats:
ENTRYPOINT ["executable", "param1", "param2"] (exec format)
ENTRYPOINT command param1 param2 (executed in shell).
The purpose of ENTRYPOINT, like CMD, is to start the program and parameters in the specified container. ENTRYPOINT can also be replaced at run time, but it is slightly more cumbersome than CMD and needs to be specified by the parameter entrypoint of docekr run.
# compare with CMD:
1) the same point: only one can be written. If you write more than one, only the last one will take effect.
The container does not run until it is started, and the timing is the same.
2) the difference: ENTRYPOINT will not be overwritten by the running command, while CMD will be overwritten.
Example:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centos:latestENTRYPOINT echo hello worldENTRYPOINT echo hello china# is the same as CMD Only the last instruction takes effect [root@sqm-docker01 dfs] # docker run-- rm en:v1 hello china# is not overwritten by the runtime command [root@sqm-docker01 dfs] # docker run-rm en:v1 echo "test" hello china# unless you use the-- entrypoint parameter [root@sqm-docker01 dfs] # docker run-- rm-- entrypoint hostname en:v1 fa667d019ce5# here use the hostname command to override hello china
11pm enter Point is used in conjunction with the CMD instruction
# if we write both ENTRYPOINT and CMD in Dockerfile, then the content specified by CMD will be used as a parameter to ENTRYPOINT.
Examples are as follows:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centos:latestENTRYPOINT ["/ usr/bin/ping", "baidu.com" "- c"] CMD ["4"] # run a container: [root@sqm-docker01 dfs] # docker run-rm en:v2PING baidu.com (39.156.69.79): 56 data bytes64 bytes from 39.156.69.79: seq=0 ttl=127 time=72.931 ms64 bytes from 39.156.69.79: seq=1 ttl=127 time=62.366 ms64 bytes from 39.156.69.79: seq=2 ttl=127 time=58.875 ms64 bytes from 39.156.69.79: seq=3 ttl=127 time=50.662 ms--- baidu.com ping statistics-4 packets transmitted 4 packets received, 0% packet lossround-trip min/avg/max = 50.662 ms 61.208 ms
The command that runs in the container at this point is: ping baidu.com-c 4.
The parameters in # ENTRYPOINT are always used, while the additional parameters of CMD can be replaced dynamically when the container starts, as shown in the following example:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centos:latestENTRYPOINT ["/ usr/bin/ping", "baidu.com" "- c"] CMD ["4"] [root@sqm-docker01 dfs] # docker run-- rm en:v2 2PING baidu.com (39.156.69.79) 56 (84) bytes of data.64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=1 ttl=127 time=80.4 ms64 bytes from 39.156.69.79 (39.156.69.79): icmp_seq=2 ttl=127 time=61.5 ms--- baidu.com ping statistics-2 packets transmitted, 2 received, 0 packet loss Time 3msrtt min/avg/max/mdev = 61.532 ms 70.945 + 80.358 * *
The life of the container running at this time is: ping baidu.com-c 2.
What are the benefits of combining these two instructions? We understand it through the scenario: (the example is more or less the same as the above example)
/ / suppose we need an image that is aware of our current public network IP, and we can first use CMD to implement it:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centos:latestRUN yum-y install curlCMD ["/ usr/bin/curl", "- s", "https://ip.cn"]# build image and run container: [root@sqm-docker01 dfs] # docker build-t myip:v1. [root@sqm-docker01 dfs] # docker run-- rm myip:v1 {" ip ":" 117.136.60.216 "," country ":" Jiangxi Province "," city ":" Mobile "}
It looks like we can use it as a command, but commands always have parameters, and if we want to display HTTP header information, we need to add the-I parameter. So can we add the-I parameter directly to docker run myip?
[root@sqm-docker01 dfs] # docker run-rm myip:v1-idocker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec:\"-I\ ": executable file not found in $PATH": unknown.
We can see that the error cannot be found in the replacement file, executable file not found. As we said earlier, the name above is followed by command, and the runtime will replace it with the value of CMD. So the-I here replaces the original CMD instead of adding it after the original curl-s https://ip.cn. -I is not an order at all, so naturally I can't find it.
/ / in order to solve this problem, we use CMD and ENTRYPOINT together:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centos:latestRUN yum-y install curlENTRYPOINT ["/ usr/bin/curl", "- s", "https://ip.cn"]CMD ["-I "] # build and run the container: [root@sqm-docker01 dfs] # docker build-t myip:v2. [root@sqm-docker01 dfs] # docker run-- rm myip:v2 HTTP/2 200 date: Wed, 19 Feb 2020 07:10:48 GMTcontent-type: application/json; charset=UTF-8set-cookie: _ _ cfduid=d1903fe7e93a885c6ae4890572cda42161582096248 Expires=Fri, 20-Mar-20 07:10:48 GMT; path=/; domain=.ip.cn; HttpOnly; SameSite=Laxcf-cache-status: DYNAMICexpect-ct: max-age=604800, report-uri= "https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"alt-svc: h4-25 =": 443 "; ma=86400, h4-24 =": 443 "; ma=86400, h4-23 =": 443 " Ma=86400server: cloudflarecf-ray: 56766c505d6fb22e-HKG {"ip": "117.136.60.216", "country": "Jiangxi Province", "city": "Mobile"}
You can see that it is successful, because when ENTRYPOINT exists, the contents of CMD will be passed to ENTRYPOINT for use, thus achieving the desired results.
# # summarize several rules:
If ENTRYPOINT uses shell mode, the CMD instruction is ignored. If ENTRYPOINT uses exec mode, the content specified by CMD is appended to the parameters of the command specified by ENTRYPOINT. If ENTRYPOINT uses exec mode, CMD should also use exec mode
127VOLUMEMAE-define anonymous volume
The format is:
VOLUME [","...]
VOLUME
In Dockerfile, we can pre-specify some directories to be mounted as anonymous volumes, so that if the user does not specify the mount, the application can run normally and will not write a large amount of data to the container storage layer.
VOLUME / data
The / data directory here is automatically mounted as anonymous volumes at run time, and any information written to / data will not be recorded in the container storage layer, thus ensuring that the container storage layer is stateless. Of course, you can override this mount setting when running the container.
Docker run-d-v mydata:/data xxxx
In the above command, the named volume mydata is mounted to the / data location, replacing the mount configuration of the anonymous volume defined in Dockerfile.
# Note: as you can see from the supported format of this directive, VOLUME only supports the mount mode of docker manager volume, but not that of bind mount.
Docker manager volume: you don't need to specify the source file, you just need to specify mount point. The directory in the container is mapped to the local (host).
Examples are as follows:
[root@sqm-docker01 dfs] # cat Dockerfile FROM nginx:latestVOLUME / usr/share/nginx/html/# build and run container: [root@sqm-docker01 dfs] # docker build-t volume:v1. [root@sqm-docker01 dfs] # docker run-itd-name volume volume:v1 5d963fb3b51ae9ddcc3b55382e289e0447235676f8893900a440f5f9500f035e
When we view a large number of generated containers created through the dockerfile through docker inspect, we can see the mount point information:
[root@sqm-docker01 dfs] # docker inspect volume "Mounts": [{"Type": "volume", "Name": "190c5a22df09462a9f5fd54209b8bc5ad06fc9382f9c8b9c665c734e4bcf95e0", "Source": "/ var/lib/docker/volumes/190c5a22df09462a9f5fd54209b8bc5ad06fc9382f9c8b9c665c734e4bcf95e0/_data", "Destination": "/ usr/share/nginx/html" "Driver": "local", "Mode": "," RW ": true," Propagation ":"}]
From the above information, you can see that the default source path mounted to the local is "/ var/lib/docker/volumes/190c5a22df09462a9f5fd54209b8bc5ad06fc9382f9c8b9c665c734e4bcf95e0/_data", while the destination path (the path within the container) is the custom "/ usr/share/nginx/html".
13th WORKDIRMI-specify the working directory
The format is:
WORKDIR
Set the working directory, which is effective for RUN,CMD,ENTRYPOINT,COPY,ADD. If the directory does not exist, it will create it for you, or you can set it multiple times, such as:
The final path for WORKDIR / aWORKDIR bWORKDIR cRUN pwd# is / a/b/c.
# # WORKDIR can also resolve environment variables, such as:
The result of execution of ENV DIRPATH / usr/srcWORKDIR $DIRPATHRUN pwd#pwd is / usr/src.
Note: never equate dockerfile with shell scripts, for example:
RUN cd / appRUN echo "hello" > world.txt
After running the dockerfile in a build image, you will find that the / app/world.txt file cannot be found, or that its content is not hello. The reason is very simple: in dockerfile, these two lines of RUN commands are executed in different environments, and they are two completely different containers. This is the error caused by a lack of understanding of Dockerfile's concept of building tiered storage.
If you need to change the location of the working directory for future layers, you should use the WORKDIR directive.
140.USERMAL-specify current user
Format: USER [:]
USER instructions are similar to WORKDIR in that they change the state of the environment and affect subsequent layers.
WORKDIR is to change the working directory, USER is to change the layer's execution RUN,CMD, and the identity of commands such as ENTRYPOINT.
Of course, like WORKDIR, USER only helps you switch to a specified user, which must be established in advance, otherwise it cannot be switched:
RUN groupadd-r redis & & useradd-r-g redis redisUSER redisRUN ["redis-server"]
If you execute the script in root, you want to change your identity during execution, such as wanting to run a service process as an established user, instead of using su or sudo, which require cumbersome configuration and often make errors in an environment where TTY is missing. Gosu is generally used.
Examples are as follows:
# establish a redis user and use gosu for another user to execute the command RUN groupadd-r redis & & useradd-r-g redis redis# to download gosuRUN wget-O / usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64"\ & & chmod + x / usr/local/bin/gosu\ & & gosu nobody true# to set CMD And execute CMD as another user (redis) ["exec", "gosu", "redis", "redis-server"]
1514 ONBUILDMI-add triggers for mirrors
Format: ONBUILD
ONBUILD is a special instruction that is followed by other instructions, such as RUN,COPY, that are not executed during the current image build.
It is executed only when the image is based on the current image to build the next level of mirror.
Other instructions in Dockerfile are prepared to customize the current image, but ONBUILD is prepared to help others customize themselves.
Examples are as follows:
/ / write a Dockerfile file with the following contents:
[root@sqm-docker01 dfs] # cat Dockerfile FROM nginx:latestONBUILD COPY. / index.html / # copy the file to / under the container
/ / use the above dockerfile file to build an image:
[root@sqm-docker01 dfs] # docker build-t image1.
/ / create a container using image1 image:
[root@sqm-docker01 dfs] # docker run-- rm-it image1 / bin/bashroot@db8a068d9f30:/# ls bin dev home lib64 mnt proc run srv tmp varboot etc lib media opt root sbin sys usr
We found that there is no index.html file in the container / directory running as the image1 image, which means that the instructions specified by ONBUILD will not be executed in its own image build.
/ / write a new Dockerfile file as follows:
The basic image used by [root@sqm-docker01 dfs] # cat Dockerfile FROM image1 # is the image image1CMD echo hello world built above
/ / use the above dockerfile file to build an image:
[root@sqm-docker01 dfs] # docker build-t image2 .Sending build context to Docker daemon 102.6MBStep 1 build trigger 2: FROM image1# Executing 1 build trigger-- > 796e32308d29Step 2 796e32308d29Step 2: CMD echo hello world-> Running in 5c16f913f5e9Removing intermediate container 5c16f913f5e9-- > 4c0a45374727Successfully built 4c0a45374727Successfully tagged image2:latest
/ / create a container using image2 image:
[root@sqm-docker01 dfs] # docker run-it-- rm image2 / bin/bashroot@3e3c1d0fe3f6:/# lsbin dev home lib media opt root sbin sys usrboot etc index.html lib64 mnt proc run srv tmp varroot@3e3c1d0fe3f6:/# cat index.html hello world
We found the index.html file in the root directory of the container running as an image2 image, indicating that the trigger executed the COPY. / index.html / instruction.
Mirror cache properties:
1) Docker caches the existing mirror layer. When building a new image, if a mirror layer already exists, it can be used directly without recreating it, as shown below:
/ / create a new dockerfile
[root@sqm-docker01 dfs] # cat Dockerfile FROM centosRUN yum-y install vim// build an image [root@sqm-docker01 dfs] # docker build-ta: V1.
# add a little new content to the dockerfile you just created (add a COPY directive in the image):
[root@sqm-docker01 dfs] # cat Dockerfile FROM centosRUN yum-y install vimCOPY testfile /
# rebuild the image with the same dockefile:
[root@sqm-docker01 dfs] # touch testfile [root@sqm-docker01 dfs] # docker build-ta: v2.Sending build context to Docker daemon 102.6MBStep 1 y install vim 3: FROM centos-- > 0f3e07c0138fStep 2 y install vim 3: RUN yum-y install vim-> Using cache-- > 6467d4675159Step 3 y install vim 3: COPY testfile /-> 6b92fe05882fSuccessfully built 6b92fe05882fSuccessfully tagged a:v2
(1) make sure the testfile file already exists
(2) Using cache, the focus is here: the same RUN instruction has been run before, this time directly using the mirror layer 6467d4675159 in the cache.
(3) execute COPY instruction.
The process is to start the temporary container, copy the testfile, submit a new mirror layer 6b92fe05882f, and delete the temporary container.
If we want to build the image without caching, we can add the-- no-cache parameter to the docker build command.
2) each instruction in Dockerfile creates a mirror layer, and the upper layer depends on the lower layer. Whenever a layer changes, the cache of all layers above it will be invalidated.
That is, if we change the order in which Dockerfile instructions are executed, or modify or add instructions, the cache will be invalidated.
For example, for example, the order in which the above RUN and COPY instructions are exchanged:
[root@sqm-docker01 dfs] # cat Dockerfile FROM centosCOPY testfile / RUN yum-y install vim
Although logically this change has no effect on the content of the mirror, because of the hierarchical structure, Docker must reconstruct the affected mirror layer.
/ / rebuild the image:
[root@sqm-docker01 dfs] # docker build-ta: v3.Sending build context to Docker daemon 102.6MBStep 1apace 3: FROM centos-- > 0f3e07c0138fStep 2Unip 3: COPY testfile /-- > 97e725434a6bStep 3max 3: RUN yum-y install vim-> Running in 5f30ff393047.Removing intermediate container 5f30ff393047-- > 90ceae8b3638Successfully built 90ceae8b3638Successfully tagged a:v3
From the output above, you can see that a new mirror layer 97e725434a6b has been generated and the cache has been invalidated.
In addition to using caching when building, Docker also uses it when downloading images. For example, we download the httpd image:
[root@sqm-docker01 dfs] # docker pull httpdUsing default tag: latestlatest: Pulling from library/httpdf17d81b4b692: Already exists 06fe09255c64: Already exists 0baf8127507d: Already exists 07b9730387a3: Already exists 6dbdee9d6fa5: Already exists Digest: sha256:76954e59f23aa9845ed81146ef3cad4a78f5eb3daab9625874ebca0e416367e2Status: Image is up to date for httpd:latest
The output of the docker pull command shows that the first layer (base image) already exists and does not need to be downloaded.
A simple understanding of the concept of mirror layering
Each line of code in Dockerfile produces a new layer, a mirror cannot exceed 127layers, and each layer produces a separate id.
Layers that already exist in image are read-only. When an image is run as a container, the layer is readable and writable. When you need to manipulate the files in the mirror layer, you copy a copy through the container layer, and then do the operation. This mechanism is copy on write (copy on write).
The above is a detailed description of the configuration file Dockerfile of the Docker container. Have you learned anything after reading it? If you want to know more about it, you are welcome to follow the industry information!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.