Docker uses the Docker build command to build the image, and the specific instructions to build the image are saved in the Dockerfile.

When the docker build command is executed, no matter where the Dockerfile file is located, the current directory is the build context, the working directory of the build command, and the starting directory of the COPY command

Understand image generation (commitCommand)

  • From image to container

An image is a layer of storage, and each layer is modified on the basis of the previous layer, while a container is also a layer of storage, which is added on the basis of the image as a container to run the storage layer. All changes to the container are stored in this layer. Once the container is removed, only the layer of running storage that it added on top of the image is removed (unless data persistence operations such as data volumes are used).

  • From container to image

After a series of operations are performed in a container and you want to save it as an image, you can use the Docker commit command to save the running storage layer of the current container as a new image, which will run in the same initial environment as the current container

  • docker commitThe command
#Create a new image from the containerDocker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] -a --author String: commit author -c --change list: Use the Dockerfile directive to create a mirror. -m --message string --p --pause: CONTAINER: CONTAINER ID REPOSITORY[:TAG] REPOSITORY: Docker commit -a "runoob.com" -m "my apache" a404c6C174A2 mymysql:v1 Docker images mymysql:v1#REPOSITORY TAG IMAGE ID CREATED SIZE
#mymysql v1 37af1236adef 15 seconds ago 329 MB
Copy the code
  • Try not to use the commit command

    • When the container is running, it may generate files that will not be used by subsequent images, resulting in a bloated image
    • Black box images are extremely difficult to maintain
      • usecommitThe operation of generating an image from a container is unknowable to others (i.e. a black box operation), and even the developer may not remember everything (there is no guarantee that the contents of the container will be the same every time), making subsequent modifications and maintenance of the image difficult
      • If you run the container modification again on the generated image of the container, thencommitMirroring results in layer upon layer of bloatcode

Build image commandbuild

You can use the docker build command to create a new image from the Dockerfile

docker build [OPTIONS] [NAME] PATH | URL | - NAME: Image name (and sometimes the image information such as the need to add the tag) PATH | | - URL: Dockerfile address and working directory Settings, The default is the same directory (remote Git repo or local file) --build-arg=[] : sets variables for image creation --cpu-shares: sets CPU usage weight --cpu-period: limits CPU CFS cycles --cpu-quota --cpuset-mems: specifies the MEMORY ID. --disable-content-trust: specifies that the verification is ignored. -f: specifies the path of the Dockerfile to be used. --force-rm: deletes intermediate containers during the mirroring process. -- Isolation: uses the container isolation technology --memory-swap: set the maximum size of the swap to memory +swap, "-1" indicates unlimited swap --no-cache: do not use cache during the creation of the mirror --pull: try to update the new version of the mirror --quiet, -q: quiet mode, --rm: delete the intermediate container after the mirror succeeds --shm-size: set the size of /dev/shm. The default value is 64M. --ulimit: ulimit configuration --tag, -t: The name and label of the image, usually in the name:tag or name format. Multiple labels can be set for an image in a single build --network: default. Set the network mode of the RUN directive during buildCopy the code
Create an image and set the image label

.The Dockerfile file in the current directory has a context ofCurrent folder

docker build -t runoob/ubuntu:v1 .
Copy the code
According to theGitHubCreate an image on the file

When usinggit repoWhen you build the image,dockerThemselves withgit cloneA folder into which to start building

The context isgit cloneAnd then inside the file,DockerfileIt’s in the file

docker build github.com/creack/docker-firefox
Copy the code
-f DockerfileSpecifies the location of the file

The last of the.At this time only asWorking directory definition.DockerfileThe path will be-fParameter coverage of

#In this case, no label such as name is specified, and all the mirrored labels displayed by ps are < None >. Avoid this situation
docker build -f /path/to/a/Dockerfile .
Copy the code
Build by reading a Dockerfile from standard input

dockerWill take the standard input text asDockerfile, there is no context and cannot be executedCOPYAnd other instructions to manipulate context files

docker build - < Dockerfile
cat Dockerfile | docker build -
Copy the code
Build by reading the context compression package from standard input

If the input in the previous item is compressed file (supported onlyGzip, bzip, xzFormat),dockerIt expands it, treats the contents of the file as context,DockerfileFiles are also read from within

docker build - < context.tar.gz
Copy the code

.dockerignorefile

If there are too many files in the context, it can lead to a very large and bloated image, especially one with many files that we don’t need. This is where the.dockerignore file is used.

.dockerIgnore is a.gitignore-like file that is used to ignore certain files when building context. It supports regex and wildcards, and its rules are defined as follows:

# syntax # comment * Matches zero or more characters that are not /? Matches 1 non-/ character ** 0 or more directories! In addition to... All md files (including readme-secret.md) are ignored by Docker *.md! README*.md README-secret.mdCopy the code

Dockerfilegrammar

The essence of mirror building is to customize the configuration and files added to each layer. If we could write each layer of modification, installation, build, and operation commands into a script, and use this script to build and customize the image, the problems of unrepeatability, transparency, and volume mentioned above would all be solved

This script is called a Dockerfile, which is a text file containing the instructions and instructions required to build the image

# Dockerfile common instruction set
FROM Ubuntu: 18.04
# build images based on the images specified by FROM
COPY . /app
# copy files from the current working directory to the container.
# ADD . /app
# ADD is the same as COPY, but ADD will unzip the compressed file
LABEL Com. Example. Version = "0.0.1 - beta"
LABEL vendor1="ACME Incorporated"
LABEL com.example.version.is-production=""
# Set the mirror tag
ENV file=docker
Set environment variables
ARG app=test
Declare environment variables that are valid only in build
VOLUME /foo
Data volume default mount directory (container data persistent use)
RUN echo 'build ubuntu18.04 image'
# Command line command after running RUN
CMD echo cmd
# specify the command to run in the container
ENTRYPOINT echo 12121
# run starts the command by default
WORKDIR /mydir
# specify the working directory to take effect in subsequent instructions
EXPOSE 5000
# declare port
USER patrick
# Specify the user and user group to execute the subsequent command
ONBUILD RUN echo 'The current base image is Ubuntu18.04'
# execute when the image built using the current file is the base image
Copy the code
FROM the instructions

FROM is used to specify the base image to build the new image

CPOYinstruction
  • The source path: source file or source directory, which can be wildcard expressions
  • The target path: Specifies a path in the container. This path does not need to be created in advance. If no path exists, it will be created automatically
COPY [--chown=<user>:<group>] < source path 1>... COPY [--chown=<user>:<group>] [< source path 1>.< target path >] [--chown=<user>:<group>] : Optional. The user changes the owner and owner group of the file copied to the container.# sampleCOPY hom* /mydir/ COPY hom? .txt /mydir/Copy the code
ADDinstruction

ADD is used in the same way as COPY and has similar functions. However, when the source file is a compressed file (gzip, bzip2, or xz), the ADD command automatically decompresses the file, which is friendly to the file to be decompressed, but cannot transfer the file that does not need to be compressed. Therefore, you are advised to use CPOY in non-special cases

RUNinstruction

The following command line commands can be written in two ways

Executed when building a mirrored Docker build

  • shellCommand writing:RUN < command line command >It’s the same thing as operating at the terminalshellCommand.
  • execFormat:RUN [executable, arg1, arg2...
CMDinstruction

CMD is executed when Docker runs the image (Docker run) and is the default container start command. The command is similar to run in that it runs command line commands and supports shell and exec writing, but there is one more CMD

  • CMD [arg1, arg2, arg3 ...]The writing method is mainly forENTRYPOINTInstruction provides parameters
  • Running imagedocker runWhen performing
  • CMDWill berunAfter the command container is started, the command is overwritten
  • CMDThis command can be executed only once if there are more than oneCMD
ENTRYPOINTinstruction

The ENTRYPOINT command is also run when the image runs a Docker run (which is one of the default container start commands), but it is not overwritten by the commands specified by run, which are also used as arguments to the ENTRYPOINT command (CMD arguments are overwritten). It also supports shell and exec writing

When the run command is set –entrypoint can be overridden with command-line arguments

FROM nginx
ENTRYPOINT ["nginx"."-c"] # set the cords
CMD ["/etc/nginx/nginx.conf"] # CMD to participate
Copy the code
  • useCMDparameter
Docker run nginx:test: nginx -c /etc/nginx/nginx.confCopy the code
  • runCommand and the cords
Docker run nginx:test -c /config/new.conf Docker run nginx -c /config/new.confCopy the code
CMDENTRYPOINTThe priority of an instruction

When both directives set command line commands, ENTRYPOINT overrides CMD directly if it is a shell, and uses CMD as an argument if it is exec

No ENTRYPOINT ENTRYPOINT exec_entry p1_entry ENTRYPOINT [” exec_entry “, “p1_entry”]
No CMD error, not allowed /bin/sh -c exec_entry p1_entry exec_entry p1_entry
CMD [” exec_cmd “, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry exec_cmd p1_cmd
CMD [” p1_cmd “, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry p1_cmd p2_cmd
CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
LABELinstruction

Add a label to the image

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

Just declare the ports, and when random port mappings are used at runtime, that is, docker run -p, they automatically map randomly to EXPOSE ports.

EXPOSE < Port 1> [< Port 2>...]Copy the code
ENVinstruction

Defines environment variables that can be retrieved by subsequent directives as well as by the running container


ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2> ...

#For example, set version to 0.1.0ENV version=0.1.0 RUN echo $version In the container, RUN echo $versionCopy the code
ARGinstruction

The ARG directive is also used to set environment variables in the same way as the ENV directive, but the variables set by the ARG directive can only be used in build (i.e. Dockerfile)

VOLUMEinstruction

Define a default directory for mounting data volumes. If no directory is specified, the default directory is mounted to the data volume to avoid data loss

When starting the container Docker run, we can change the mount point with the -v argument

VOLUME ["< path 1>", "< path 2>"... VOLUME < path >Copy the code
USERinstruction

The command is used to specify the user and user group that execute the subsequent command. The user and user group must exist in advance.

WORKDIRinstruction

Specify the working directory (execution context, build’s execution directory). The working directory specified with WORKDIR is present at each layer of the build image. (WORKDIR specifies the working directory, which must be created in advance)

Each RUN command in docker build is a new layer. Only directories created by WORKDIR will always exist.

ONBUILDinstruction

Used to delay the execution of build commands. The ONBUILD command in Dockerfile will not be executed during the build process (assuming the image is test-build). When a new Dockerfile is built using the previously built image FROM test-build, the command ONBUILD specified in the Dockerfile of test-build will be executed

STOPSIGNALinstruction

The STOPSIGNAL directive sets the system call signal that will be sent to the container to exit. The signal can be a valid unsigned number that matches a location in the kernel syscall table (for example, 9) or a signal name in the format SIGNAME (for example, SIGKILL)

STOPSIGNAL signal
Copy the code
HEALTHCHECKinstruction

Specifies a program or directive that monitors the running status of the Docker container service

HEALTHCHECK [options] CMD < command > : sets the command to check the container health. HEALTHCHECK NONE: if the underlying image has a HEALTHCHECK, use this line to mask its HEALTHCHECK. HEALTHCHECK [options] CMD < command > : --interval=DURATION (default: 30s) --timeout=DURATION (default: 30s) --start-period=DURATION (default: 30s) 0s) --retries=N (default: 3)Copy the code
SHELLinstruction

Sets the default shell for the container to run

SHELL ["executable", "parameters"]

#Using a shell(Linux default)
SHELL ["/bin/sh", "-c"]

#Using powershell
SHELL ["powershell", "-command"]

#Using CMD (Windows default)
SHELL ["cmd", "/S", "/C"]
Copy the code

DockerfileMatters needing attention

Multistage construction

When building an image, if all content is in a Dockerfile content, the resulting image may be very large, but if scattered to multiple Dockerfiles, management and deployment will become very troublesome, after Docker 17.05 can use multi-stage build to deal with this situation

Multi-phase builds are implemented through the FROM directive, and you can use multiple FROM statements in a Dockerfile. Each FROM directive can use a different base, and each directive starts a new build. You can selectively copy artifacts from one stage to another, leaving only what you want in the final image

Docker build --target Builder # You can use --target to specify the build phase of the image

# Split the mirror build into two phases by using FROM multiple times
FROM Golang: 1.11 - alpine AS build
RUN apk add --no-cache git
RUN go get github.com/golang/dep/cmd/dep
COPY Gopkg.lock Gopkg.toml /go/src/project/
WORKDIR /go/src/project/
RUN dep ensure -vendor-only
COPY . /go/src/project/
RUN go build -o /bin/project

# COPY the mirror from phase 1 to phase 2 with the COPY --from= XXXX command, leaving only the required parts
FROM scratch
COPY --from=build /bin/project /bin/project
ENTRYPOINT ["/bin/project"]
CMD ["--help"]
Copy the code
Avoid meaningless levels

Each execution of the Dockerfile instruction creates a new layer on top of the Docker. So too many meaningless layers will cause the image to expand too much

Through the RUN

The FROM centos RUN yum install wget RUN wget - O redis. Tar. Gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" RUN tar  -xvf redis.tar.gz#The above execution creates a layer 3 image. It can be simplified into the following format:
#For readability, use \ && to separate lines as much as possibleThe FROM centos RUN yum install wget \ && wget - O redis. Tar. Gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && tar -xvf redis.tar.gzCopy the code
Other optimization Settings
  • Set up the.dockerignoreFiles, avoid the impact of useless large files
  • Try to useCOPYRather thanADD

Although ADD and COPY are similar in function, COPY is simpler than ADD. COPY only supports basic copying of local files to the container, while ADD has some unnecessary functions (such as decompressing tar files and supporting URL retrieval). Therefore, use ADD except for special situations where you need to extract files

  • Cache Settings

When docker executes Dockerfile instruction by line, if there is a cache, it will directly use the cache result. If there is no cache, you can set –no-cache=true during build to avoid too much cache slowing down the speed

  • Reasonable adjustmentCOPYRUNThe order of

Once COPY and ADD are executed, the previous cache will be invalidated, and the images built after this command will not use the cache. Therefore, commands such as COPY WORKDIR ENV LABEL can be moved backward, and instructions with less cache changes can be moved forward

  • addHEALTHCHECKHealth check

Reference documentation

  • Understanding image generation
  • Dockerfile document
  • Dockerfile best practices
  • Multistage construction