CHAPTER 7 *使用Dockerfile创建镜像

news2025/1/21 0:51:59

dockerfile

    • 7.1 基本结构
    • 7.2 指令说明
      • 7.2.1 ARG
      • 7.2.2 FROM
      • 7.2.3 LABEL
      • 7.2.4 EXPOSE
      • 7.2.5 ENV
      • 7.2.6 ENTRYPOINT
      • 7.2.7 VOLUME
      • 7.2.8 USER
      • 7.2.9 WORKDIR
      • 7.2.10 ONBUILD
      • 7.2.11 STOPSIGNAL
      • 7.2.11 HEALTHCHECK
      • 7.2.12 SHELL
      • 7.2.13 RUN
      • 7.2.14 CMD
      • 7.2.15 ADD
      • 7.2.16 COPY
    • 7.3 创建镜像
      • 7.3.1 指定dockerfile路径(`-f`)
      • 7.3.2 指定镜像名称及标签信息(`-t`)
      • 7.3.3 命令选项
      • 7.3.4 选择父镜像
      • 7.3.5 使用`.dockerignore`文件
    • 7.4 多步骤创建
    • 7.5 最佳实践

Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像。

前几章的基础学习最终都是为了通过dockerfile使用docker,在生产环境中,dockerfile是docker最普遍的使用方式。本章即是重点也是难点,面试官经常通过dockerfile判断面试者是否熟练掌握docker使用。

7.1 基本结构

Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。
一般而言,Dockerfile主体内容分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时执行指令。

简单示例:

[root@dbc-server-554 nginx]# cat dockerfile
FROM ubuntu:18.04

LABEL maintainer docker_user<docker_user@mail.com>

RUN echo "deb http://archive.ubuntu.com/ubuntu/ xeniel main universe" >> /etc/apt/sources.list
RUN apt-get update &&apt-get install nginx -y
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

CMD /usr/sbin/nginx

主体部分首先使用FROM指令指明所基于的镜像名称,接下来一般是使用LABEL指令说明维护者信息。后面则是镜像操作指令,例如RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一,并提交。 最后是CMD指令,来指定运行容器时的操作命令。

7.2 指令说明

Dockerfile中指令的一般格式为INSTRUCTION arguments,包括“配置指令"(配置镜像信息)和“操作指令"(具体执行操作)

  1. Dockerfile中的配置指令
指令说明
ARG定义创建镜像过程中使用的变量
FROM指定所创建镜像的基础镜像
LABEL为生成的镜像添加元数据标签信息
EXPOSE声明镜像内服务监听的端口
ENV指定环境变量
ENTRYPOINT指定镜像的默认入口命令
VOLUME创建一个数据卷挂载点
USER指定运行容器时的用户名或UID
WORKDIR配置工作目录
ONBUILD创建子镜像时指定自动执行的操作指令
STOPSIGNAL指定退出的信号值
HEALTH CHECK配置所启动容器如何进行健康检查
SHELL指定默认shell类型
  1. Dockerfile中的操作指令
指令说明
RUN运行指定命令
CMD启动容器时指定默认执行的命令
ADD添加内容到镜像
COPY复制内容到镜像

配置指令

7.2.1 ARG

定义创建镜像过程中使用的变量。格式为
ARG <name>[=<default value>]
在执行docker build时, 可以通过-build-arg[=]来为变量赋值。当镜像编译成功后,ARG指定的变量将不再存在(ENV指定的变量将在镜像中保留)
Docker内置了一些镜像创建变量,用户可以直接使用而无须声明,包括(不区分大小写)HTTP_PROXYHTTPS_PROXYFTP_PROXYNO_PROXY

[root@dbc-server-554 docker]# cat dockerfile
FROM centos:7
LABEL version="1.0" maintainer="newbee"
ARG vari=123
RUN echo $vari
[root@dbc-server-554 docker]# docker build .
Sending build context to Docker daemon  722.8MB
Step 1/4 : FROM centos:7
 ---> 2d8840b29c99
Step 2/4 : LABEL version="1.0" maintainer="newbee"
 ---> Using cache
 ---> 2f562664134c
Step 3/4 : ARG vari=123
 ---> Using cache
 ---> 896f6fb74c22
Step 4/4 : RUN echo $vari
 ---> Running in dd07e52256bb
123
Removing intermediate container dd07e52256bb
 ---> 5610952caf2c
Successfully built 5610952caf2c

7.2.2 FROM

指定所创建镜像的基础镜像。格式为
FROM <image> [AS <name>]
FROM <image>: <tag> [AS <name>]
FROM <image>@<digest> [AS <name>]
任何Dockerfile中第一条指令必须也应该为FROM指令。 并且, 如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。

7.2.3 LABEL

LABEL指令可以为生成的镜像添加元数据标签信息。这些信息可以用来辅助过滤出特定镜像。格式为
LABEL<key>=<value> <key>=<value> <key>=<value> ...
可以添加多条标签信息
例如:

LABEL version="l.0.0-rc3" 
LABEL author="yeasy@github" date="2020-01-01" 
LABEL description="This text illustrates	\
		that label-values can span multiple lines." 

7.2.4 EXPOSE

声明镜像内服务监听的端口。格式为
EXPOSE <port> [<port>/<protocol>... ]
例如:

EXPOSE 22  80  8443 

注意该指令只是起到声明作用, 并不会自动完成端口映射。
如果要映射端口出来,在启动容器时可以使用-P参数(Docker主机会自动分配一个宿主机的临时端口)或-p HOST_PORT:CONTAINER_PORT参数(具体指定所映射的本地端口)。

7.2.5 ENV

指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。格式为
ENV<key> <value>
ENV<key>=<value>
例如:

ENV APP VERSION=l.0.0
ENV APP_HOME=/usr/local/app 
ENV PATH $PATH:/usr/local/bin 

指令指定的环境变量在运行时可以被覆盖掉,如

docker run --env <key>=<value> built_image

注意当一条ENV指令中同时为多个环境变量赋值并且值也是从环境变量读取时,会为变量都赋值后再更新。
如下面的指令:

ENV key1=value2 
ENV key1=value1 key2=${key1}

最终结果为key1=value1 key2=value2

7.2.6 ENTRYPOINT

指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。支持两种格式:
ENTRYPOINT ["executable", "param1 ", "param2"]: exec调用执行
ENTRYPOINT command param1 param2: shell中执行
此时, CMD指令指定值将作为根命令的参数。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。在运行时,可以被--entrypoint参数覆盖掉, 如
docker run --entrypoint

以上命令示例:

[root@dbc-server-554 docker]# cat dockerfile
ARG version=7
FROM centos:${version}
LABEL version="1.0" maintainer="newbee"
EXPOSE 22 80 443
ENV PATH $PATH:/usr/local/bin

ENTRYPOINT echo $PATH

[root@dbc-server-554 docker]# docker build .
Sending build context to Docker daemon  722.8MB
Step 1/6 : ARG version=7
Step 2/6 : FROM centos:${version}
 ---> 2d8840b29c99
Step 3/6 : LABEL version="1.0" maintainer="newbee"
 ---> Using cache
 ---> 2f562664134c
Step 4/6 : EXPOSE 22 80 443
 ---> Running in 70b7d8fe38a1
Removing intermediate container 70b7d8fe38a1
 ---> 947cc321f358
Step 5/6 : ENV PATH $PATH:/usr/local/bin
 ---> Running in 228b49e05b38
Removing intermediate container 228b49e05b38
 ---> c470eb3734a3
Step 6/6 : ENTRYPOINT echo $PATH
 ---> Running in c1026752684e
Removing intermediate container c1026752684e
 ---> 49753e6ffa38
Successfully built 49753e6ffa38
[root@dbc-server-554 docker]# docker run -it 497 bash
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin

7.2.7 VOLUME

创建一个数据卷挂载点。格式为
VOLUME ["/data"]
运行容器时可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保持的数据等。

7.2.8 USER

指定运行容器时的用户名或UID,后续的RUN等指令也会使用指定的用户身份。格式为
USER daemon
当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在Dockerfile中创建所需要的用户。例如:
RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres
要临时获取管理员权限可以使用gosu命令。

7.2.9 WORKDIR

为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。格式为
WORKDIR /path/to/workdir
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如

WORKDIR /a 
WORKDIR b 
WORKDIR c 
RUN pwd 

则最终路径为/a/b/c
因此,为了避免出错,推荐WORKDIR指令中只使用绝对路径。

7.2.10 ONBUILD

指定当基于所生成镜像创建子镜像时,自动执行的操作指令。格式为
ONBUILD [INSTRUCTION]
例如,使用如下的Dockerfile创建父镜像ParentImage,指定ONBUILD指令:

# Dockerfile for Parentimage 
[...] 
ONBUILD ADD . /app/src 
ONBUILD RUN /usr /local/bin/python build --dir /app/src 
[...] 

使用dockerbuild命令创建子镜像ChildImage时(FROMParentimage),会首先执行ParentImage中配置的ONBUILD指令

# Dockerfile for Childimage 
FROM ParentImage 

等价于在Childimage的Dockerfile中添加了如下指令:

#Automatically run the following when building Childimage
ADD. /app/src 
RUN /usr/local/bin/python-build--dir /app/src
...

由于ONBUILD指令是隐式执行的,推荐在使用它的镜像标签中进行标注,例如ruby:2.1-onbuild。
ONBUILD指令在创建专门用于自动编译、检查等操作的基础镜像时,十分有用

[root@dbc-server-554 onbuild]# cat dockerfile
#parentimage
ARG version=7
FROM centos:${version} AS ParentImage
LABEL version="1.0" maintainer="newbee"
ONBUILD ADD . /app/src
ENTRYPOINT ls /app/src
[root@dbc-server-554 onbuild]# cat dockerfile2
FROM parentimage:0.1
[root@dbc-server-554 onbuild]# docker build -t "parentimage:0.1" .
Sending build context to Docker daemon  3.072kB
Step 1/5 : ARG version=7
Step 2/5 : FROM centos:${version} AS ParentImage
 ---> 2d8840b29c99
Step 3/5 : LABEL version="1.0" maintainer="newbee"
 ---> Using cache
 ---> 2f562664134c
Step 4/5 : ONBUILD ADD . /app/src
 ---> Using cache
 ---> 4dceda702c38
Step 5/5 : ENTRYPOINT ls /app/src
 ---> Using cache
 ---> 5fa178a9f537
Successfully built 5fa178a9f537
Successfully tagged parentimage:0.1
[root@dbc-server-554 onbuild]# docker build -f dockerfile2 .
Sending build context to Docker daemon  3.072kB
Step 1/1 : FROM parentimage:0.1
# Executing 1 build trigger
 ---> bcf2fec06ec7
Successfully built bcf2fec06ec7
[root@dbc-server-554 onbuild]# docker run -it bcf bash
dockerfile  dockerfile2
[root@dbc-server-554 onbuild]# ls
dockerfile  dockerfile2

注意docker build -t "parentimage:0.1" .使用-t给镜像起名字的时候,不能有大写字母,必须是小写

invalid argument "ParentImage:0.1" for "-t, --tag" flag: invalid reference format: repository name must be lowercase

7.2.11 STOPSIGNAL

指定所创建镜像启动的容器接收退出的信号值:
STOPSIGNAL signal
默认情况下 docker stop 命令会向容器发送15号信号SIGTERM,然后等待 10s,如果容器没停止再发送 SIGKILL 信号,即优雅的退出。
如果设置STOPSIGNAL SIGKILL将退出信号设置为 SIGKILL,或者在 docker run 是通过 --stop-signal 参数来覆盖镜像中的 STOPSIGNAL 设置,则会直接退出。

[root@dbc-server-554 docker]# cat dockerfile
#parentimage
ARG version=7
FROM training/webapp
LABEL version="1.0" maintainer="newbee"
STOPSIGNAL SIGKILL
cmd python app.py
[root@dbc-server-554 docker]# docker build .
Sending build context to Docker daemon  722.8MB
Step 1/5 : ARG version=7
Step 2/5 : FROM training/webapp
 ---> 6fae60ef3446
Step 3/5 : LABEL version="1.0" maintainer="newbee"
 ---> Running in e75c4cac5fd7
Removing intermediate container e75c4cac5fd7
 ---> 915fd4862496
Step 4/5 : STOPSIGNAL SIGKILL
 ---> Running in b81a8a61cf1c
Removing intermediate container b81a8a61cf1c
 ---> 8f7a7f7cc51f
Step 5/5 : cmd python app.py
 ---> Running in 4a6343d0248b
Removing intermediate container 4a6343d0248b
 ---> 9250e0680b0d
Successfully built 9250e0680b0d
[root@dbc-server-554 docker]# docker run -d 925
58a31b6f88ad47388a16376fa4e48ae69ba360b9253fa385cdd489143e33c964
[root@dbc-server-554 docker]# docker ps
CONTAINER ID   IMAGE               COMMAND                  CREATED         STATUS         PORTS                                         NAMES
58a31b6f88ad   925                 "/bin/sh -c 'python …"   3 seconds ago   Up 2 seconds   5000/tcp                                      modest_chatelet
7bbdfbbc7e94   training/webapp     "python app.py"          18 hours ago    Up 18 hours    0.0.0.0:32781->5000/tcp, :::32781->5000/tcp   web
bd3d0e5acb9c   training/postgres   "su postgres -c '/us…"   18 hours ago    Up 18 hours    5432/tcp                                      db
[root@dbc-server-554 docker]# docker stop 58a
58a

7.2.11 HEALTHCHECK

配置所启动容器如何进行健康检查(如何判断健康与否),自Docker1.12开始支持。格式有两种
HEALTHCHECK [OPTIONS] CMD command :根据所执行命令返回值是否为0来判断;
HEALTHCHECK NONE :禁止基础镜像中的健康检查
OPTION支持如下参数:

--interval=DURATION(default: 30s):过多久检查一次;
--timeout=DURATION(default: 30s) :每次检查等待结果的超时;
--retries=N(default: 3):如果失败了,重试几次才最终确定失败。

7.2.12 SHELL

指定其他命令使用shell时的默认shell类型:
SHELL [”executable”,”parameters”]
默认值为[“/bin/sh”,“-c”]。

注意:对于Windows系统,Shell路径中使用了“\”作为分隔符,建议在Dockerfile开头添加#escape=\来指定转义符
操作指令

7.2.13 RUN

运行指定命令。格式为
RUN <command>
RUN ["executable" , ”param1” , "param2"]
注意:后者指令会被解析为JSON数组,因此必须用双引号。前者默认将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行,不会启动shell环境。

指定使用其他终端类型可以通过第二种方式实现,例如
RUN ["/bin/bash", "-c", "echo hello "
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像层。当命令较长时可以使用\来换行。例如:

RUN apt-get update \ 
	&& apt-get install -y libsnappy-dev zliblg-dev libbz2-dev \ 
	&& rm -rf /var/cache/apt \
	&& rm rf /var/lib/apt/lists/* 

7.2.14 CMD

CMD指令用来指定启动容器时默认执行的命令。支持三种格式:
CMD["executable","param1","param2"]:相当于执行executable param1 param2推荐方式
CMD command param1 param2:在默认的Shell中执行,提供给需要交互的应用;
CMD["param1","param2"]:提供给ENTRYPOINT的默认参数。
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候手动指定了运行的命令(作为run命令的参数),则会覆盖掉CMD指定的命令。

7.2.15 ADD

添加内容到镜像。格式为
ADD <src> <dest>
该命令将复制指定的<src>路径下内容到容器中的<dest>路径下。
其中<src>可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL;还可以是一个tar文件(自动解压为目录)<dest>可以是镜像内绝对路径,或者相对于工作目录(WORKDIR)的相对路径。

路径支持正则格式,例如:

ADD *.c /code/ 

7.2.16 COPY

复制内容到镜像。格式为
COPY <src> <dest>
复制本地主机的<src>(为Dockerfile所在目录的相对路径,文件或目录)下内容到镜像中的<dest>。目标路径不存在时,会自动创建。
路径同样支持正则格式。
COPY与ADD指令功能类似,当使用本地目录为源目录时,推荐使用COPY

7.3 创建镜像

编写完成Dockerfile之后,可以通过docker [image] build命令来创建镜像,基本的格式为
docker build [OPTIONS] PATH | URL | -

该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下所有数据作为上下文(Context)发送给Docker服务端。Docker服务端在校验Dockerfile格式通过后,逐条执行其中定义的指令,碰到ADD、COPY和RUN指令会生成一层新的镜像。最终如果创建镜像成功,会返回最终镜像的ID

7.3.1 指定dockerfile路径(-f)

如果上下文过大,会导致发送大量数据给服务端,延缓创建过程。因此除非是生成镜像所必需的文件,不然不要放到上下文路径下。如果使用非上下文路径下的Dockerfile,可以通过-f选项来指定其路径。

7.3.2 指定镜像名称及标签信息(-t)

要指定生成镜像的标签信息,可以通过-t选项。该选项可以重复使用多次为镜像一次添加多个名称。例如,上下文路径为/tmp/docker_builder/,并且希望生成镜像标签为builder/first_image:1.0.0, 可以使用下面的命令:

$ docker build -t builder/first_image:l.0.0 /tmp/docker_builder/ 

7.3.3 命令选项

docker [image] build命令支持一系列的选项,可以调整创建镜像过程的行为

选项说明
--add-host list添加自定义的主机名到IP的映射
--build-arg list添加创建时的变量
--cache from strings使用指定镜像作为缓存源
--cgroup parent string继承的上层cgroup
--compress使用gzip来压缩创建上下文数据
--cpu-period int分配的CFS调度器时长
--cpu-quota intCFS调度都总份额
-c, --cpu-shares intCPU权重
--cpuset-cpus string多CPU允许使用的CPU
--cpuset mems string多CPU允许使用的内存
--disable-content-trust不进行镜像校验,默认为真
-f, --file stringDockerfile名称
--force-rm总是删除中间过程的容器
--iidfile string将镜像ID写入到文件
--isolation string容器的隔离机制
--label list配置镜像的元数据
-m, --memory bytes限制使用内存量
--memory swap bytes限制内存和缓存的总量
--network string指定RUN命令时的网络模式
--no-cache创建镜像时不适用缓存
--platform string指定平台类型
--pull总是尝试获取镜像的最新版本
-q, --quiet不打印创建过程中的日志信息
-rm创建成功后自动删除中间过程容器,默认为真
--security-opt strings指定安全相关的选项
--shm-size bytes/dev/shm的大小
--squash将新创建的多层挤压放入到一层中
--stream持续获取创建的上下文
-t, --tag list指定镜像的标签列表
--target string指定创建的目标阶段
--ulimit ulimit指定ulimit的配置

7.3.4 选择父镜像

大部分情况下,生成新的镜像都需要通过FROM指令来指定父镜像。父镜像是生成镜像的基础,会直接影响到所生成镜像的大小和功能。

用户可以选择两种镜像作为父镜像,一种是所谓的基础镜像(baseimage),另外一种是普通的镜像(往往由第三方创建,基于基础镜像)。基础镜像比较特殊,其Dockerfile中往往不存在FROM指令,或者基于scratch镜像(FROM scratch),这意味着其在整个镜像树中处于根的位置。

下面的Dockerfile定义了一个简单的基础镜像,将用户提前编译好的二进制可执行文件binary复制到镜像中,运行容器时执行binary命令:

FROM scratch 
ADD binary / 
CMD ["/binary"]

普通镜像也可以作为父镜像来使用,包括常见的busybox、debian、ubuntu等。继承关系如下图
在这里插入图片描述

7.3.5 使用.dockerignore文件

可以通过.dockerignore文件(每一行添加一条匹配模式)来让Docker忽略匹配路径或文件,在创建镜像时候不将无关数据发送到服务端。
例如下面的例子中包括了6行忽略的模式(第一行为注释):

# .dockerignore文件中可以定义忽略模式
*/temp* 
*/*/temp* 
tmp? 
~* 
Dockerfile 
!README.md 
  • dockerignore文件中模式语法支持Golang风格的路径正则格式
  • “*”表示任意多个字符;
  • “?”代表单个字符;
  • “!”表示不匹配(即不忽略指定的路径或文件)。

7.4 多步骤创建

自17.05版本开始,Docker支持多步骤镜像创建(Multi-stagebuild)特性,可以精简最终生成的镜像大小。
对于需要编译的应用(如C、Go或Java语言等)来说,通常情况下至少需要准备两个环境的Docker镜像:

  • 编译环境镜像:包括完整的编译引擎、依赖库等,往往比较庞大。作用是编译应用为二进制文件
  • 运行环境镜像:利用编译好的二进制文件,运行应用,由于不需要编译环境,体积比较小

使用多步骤创建,可以在保证最终生成的运行环境镜像保持精筒的情况下,使用单一的Dockerfile,降低维护复杂度

以Go语言应用为例。创建干净目录,进入到目录中,创建main.go文件,内容为:

// main.go will output”Hello, Docker" 
package main 
import ("fmt")
func main(){ 
	fmt.Println("Hello, Docker" ) 
}

创建Dockerfile,使用golang:1.9镜像编译应用二进制文件为app,使用精简的镜像alpine:latest作为运行环境。Dockerfile完整内容为:

FROM golang:1.9 as builder #define stage name as builder
RUN mkdir -p /go/src/test 
WORKDIR /go/src/test 
COPY main.go .
RUN CGO_ENABLED=0 GOOS=linux go build -o app .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/ 
COPY --from=builder /go/src/test/app . # copy file from the builder stage 
CMD [". /app"] 

执行如下命令创建镜像,并运行应用:

[root@dbc-server-554 golang]# docker build -t yeasy/test-multistage:latest .
Sending build context to Docker daemon  3.072kB
Step 1/10 : FROM golang:1.9 as builder
 ---> ef89ef5c42a9
...
Step 10/10 : CMD [". /app"]
 ---> Running in 4e99f6a0fd0c
Removing intermediate container 4e99f6a0fd0c
 ---> 52da5f925c8c
Successfully built 52da5f925c8c
Successfully tagged yeasy/test-multistage:latest
[root@dbc-server-554 golang]# docker images |grep test-multi
yeasy/test-multistage                               latest          52da5f925c8c   28 seconds ago   7.96MB

7.5 最佳实践

所谓最佳实践,就是从需求出发,来定制适合自己、高效方便的镜像。
首先,要尽量吃透每个指令的含义和执行效果,多编写一些简单的例子进行测试,弄清楚了再撰写正式的Dockerfile。
此外,DockerHub官方仓库中提供了大量的优秀镜像和对应的Dockefile,可以通过阅读它们来学习如何撰写高效的Dockerfile。

建议读者在生成镜像过程中,尝试从如下角度进行思考,完善所生成镜像:

  • 精简镜像用途:尽量让每个镜像的用途都比较集中单一,避免构造大而复杂、多功能的镜像;
  • 选用合适的基础镜像:容器的核心是应用。选择过大的父镜像(如Ubuntu系统镜像)会造成最终生成应用镜像的膝肿,推荐选用瘦身过的应用镜像(如node:slim),或者较为小巧的系统镜像(如alpine、busybox或debian)
  • 提供注释和维护者信息:Dockerfile也是一种代码,需要考虑方便后续的扩展和他人的使用;
  • 正确使用版本号:使用明确的版本号信息,如1.0,2.0,而非依赖于默认的latest。通过版本号可以避免环境不一致导致的问题;
  • 减少镜像层数:如果希望所生成镜像的层数尽量少,则要尽量合并RUN、ADD和COPY指令。通常情况下,多个RUN指令可以合并为一条RUN指令
  • 恰当使用多步骤创建(17.05+版本支持):通过多步骤创建,可以将编译和运行等过程分开,保证最终生成的镜像只包括运行应用所需要的最小化环境。当然,用户也可以通过分别构造编译镜像和运行镜像来达到类似的结果,但这种方式需要维护多个Dockerfile
  • 使用.dockerignore文件:使用它可以标记在执行dockerbuild时忽略的路径和文件,避免发送不必要的数据内容,从而加快整个镜像创建过程
  • 及时删除临时文件和缓存文件:特别是在执行apt-get指令后,/var/cache/apt下面会缓存了一些安装包
  • 提高生成速度:如合理使用cache,减少内容目录下的文件,或使用.dockerignore文件指定等;
  • 调整合理的指令顺序:在开启cache的情况下,内容不变的指令尽量放在前面,这样可以尽量复用;
  • 少外部源的干扰:如果确实要从外部引入数据,需要指定持久的地址,并带版本信息等,让他人可以复用而不出错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/161258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

版本控制 | 设计师和美术人员的理想版本控制软件是?

版本控制对于开发人员来说是必不可少的工具。但今天&#xff0c;开发已经不仅仅包括代码。让美术人员和设计师使用版本控制能够集中协作&#xff0c;并保护宝贵的数字资产。 本篇文章将分析为什么版本控制对设计师也如此重要&#xff0c;并且回答一个重要的问题——对于设计师…

HTML实现闪电打字效果

演示 完整HTML <!doctype html> <html> <head> <meta charset"utf-8"> <title>H5 Canvas雷电打出文字特效</title><style> .page-thunder-to-text {position: relative;overflow: hidden; } .page-thunder-to-text canv…

每日坚果“鼻祖”,沃隆再闯IPO

成于坚果&#xff0c;困于坚果&#xff1f;“坚果大队长”沃隆再次闯关IPO。“每日坚果鼻祖”青岛沃隆食品股份有限公司&#xff08;下称“沃隆”&#xff09;于1月6日更新招股书&#xff0c;拟登陆上交所主板。沃隆是一家以坚果相关产品为核心的休闲食品生产商&#xff0c;主要…

SAP PP 生产版本主数据维护

PP生产版本主数据 生产版本&#xff08;Production Version&#xff09;主数据是执行生产业务过程中最主要的基础数据之一&#xff0c;包含了产品的数量结构信息&#xff0c;同时也包含了产品的工艺路线&#xff0c;工作中心等信息。生产版本主记录里包含了产品代码、工艺路线、…

三,Spring AOP

Spring AOP 1 代理设计模式 1.1 解决的问题 Service层中除了核心代码&#xff08;调用dao逻辑判断&#xff09;外&#xff0c;还有事务控制这种额外的增强功能。现在我们将核心业务代码和事务控制增强编码在一起直接定义在service层&#xff0c;日后还可能会新增其它的额外功…

docker安装与基本介绍使用

Docker 一、初识Docker 1、安装Docker # 1.yum包更新到最新 yum update # 2.安装需要的软件包&#xff0c;yum-util提供的yum-config-manager&#xff0c;例外两个是devicemapper驱动依赖的 yum install -y yum-utils device-mapper-persistent-data lvm2 # 3.设置yum源 yum…

hololens2开发环境配置,游戏引擎的全流程安装部署

要进行hololens 2的项目开发&#xff0c;进行基础环境搭建和软件安装部署的记录。 软件安装 UE ue2.6x(安装hololens平台)openxr插件&#xff0c;ux插件&#xff08;可选&#xff09; unity3d unity3d 2020&#xff08;unity3d 2021在打包时&#xff0c;在universal windo…

预测2023:智算中心将人工智能产业推上发展的“拐点”?

文|智能相对论作者|沈浪回顾过去的2022年&#xff0c;人工智能产业继续在巨变中迎来突破性成长。一方面&#xff0c;人工智能产业相关的应用越来越丰富、创新&#xff0c;比如元宇宙的出现和走红&#xff0c;为市场创造的一个全新的业态&#xff0c;也为用户带来了诸多新奇的体…

RabbitMQ 部署及配置详解

一、RabbitMQ 核心概念1. 生产者和消费者Producer: 消息的生产者,用于发布消息&#xff1b;Consumer: 消息的消费者&#xff0c;用于从队列中获取消息.消费者只需关注队列即可&#xff0c;不需要关注交换机和路由键。消费者可以通过basicConsume(订阅模式可以从队列中一直持续的…

【PCB专题】案例:PCB设计失误导致无法正常贴片

案例情况说明 本案例是新人画PCB的时候遇到的,但是遇到的时间已经比较晚了,在生产的时候报的异常。一部分原因也是前期我没有审查出来这个问题。 要生产的时候,工厂报了异常。新人转给我看的时候,我才发现PCB上是没有设计MARK点。这将导致SMT时没有Mark点对位,需要看看有没…

一篇搞定JS的位运算(公式+力扣真题)--- 持续更新

摘要 位操作&#xff08;Bit Manipulation&#xff09;是程序设计中对位模式或二进制数的一元和二元操作。在许多古老的微处理器上&#xff0c;位运算比加减运算略快&#xff0c;通常位运算比乘除法运算要快很多。在现代编程语言中&#xff0c;情况并非如此&#xff0c;很多编程…

Java项目:酒店管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要技术:java springmvc mybatis mysql tomcat js jauery jsp log4j等一些常见基本技术适用于Java毕设和学习使用 主要实现&#xff1a; 前台&#xff1a;登录、注册、酒店信息浏览、搜索酒店信息、查看房…

游戏开发 帧同步

帧同步技术是一个古老的技术&#xff0c;没有特别固定的招式&#xff0c;优化方向也是根据实际情况各有不同&#xff0c;但是其核心思想都是一样的。1.为什么需要帧同步技术帧同步主要是为了保证某些类型的游戏在同步时&#xff0c;可以保证很好的游戏体验。游戏类型通常包括&a…

无线wifi的参数即含义

WiFi属性信息 参考&#xff1a;WiFi发展史&#xff1a;https://zhuanlan.zhihu.com/p/74348591&#xff0c;WiFi2.4和5G简述&#xff1a;https://zhuanlan.zhihu.com/p/344652613 下面图中的WiFi4和WiFi5是根据协议的另一个名字。&#xff08;图片来自参考链接&#xff09; …

vue3 antd项目实战——Modal弹窗自定义遮罩 (利用maskStyle属性自定义遮罩样式)

vue3 antd项目实战——Modal弹窗自定义遮罩 maskStyle知识回调场景复现关于mask遮罩的API属性利用maskStyle属性自定义遮罩样式知识回调 文章内容文章链接vue3 antd ts实战——ant-design-vue组件库引入https://blog.csdn.net/XSL_HR/article/details/127396384?spm1001.2014…

随手查——Multisim

关于电路仿真软件Multisim的一些记录&#xff0c;基于Multisim14.0。 Multisim1、Multisim中元器件的颜色2、快速创建一个放大器电路3、如何进行参数扫描&#x1f680;参数扫描数据点导出为Excel&#x1f680;退出参数扫描模式4、交流分析1、Multisim中元器件的颜色 Multisim中…

YOLOV8 | 最先进的 YOLO 模型训练自己的数据集(持续更新中)

本文实现了俩种环境的设置&#xff0c;一种是windows的CPU版本&#xff0c;还有服务器上的GPU版本。CPU版本仅用来实现检测&#xff0c;而GPU版本用来训练自己的数据集&#xff01;&#xff08;选择其中一个环境运行后&#xff0c;训练自己的数据集&#xff09;1.环境1&#xf…

C#,图像二值化(22)——局部阈值的伯恩森算法(Bernsen Thresholding)及源程序

1、局部阈值的伯恩森算法&#xff08;Bernsen Thresholding&#xff09;Bernsen方法是为图像分割开发的局部自适应二值化方法之一。在这项研究中&#xff0c;实现了Bernsen的局部自适应二值化方法&#xff0c;并对不同灰度图像进行了测试。Bernsen’s method is one of locally…

04_FreeRTOS任务挂起和恢复函数

目录 任务的挂起与恢复的API函数 任务挂起函数介绍 任务恢复函数介绍 中断中恢复函数 vTaskSuspend()任务挂起函数 vTaskResume()任务中恢复函数 xTaskResumeFromISR()中断中恢复函数 任务的挂起与恢复的API函数 挂起:挂起任务类似暂停,可恢复;删除任务,无法恢复,类似“…

公务员行测常识积累(持续更新中)

公务员行测常识积累政治天文地理人文戏曲历史经济物理生物医学政治 区域协调发展战略&#xff1a;以城市群为主体构建大中小城市和小城镇协调发展的城镇格局&#xff1b;以疏解北京非首都功能为“牛鼻子”推动京津冀协同发展&#xff1b;以共抓大保护、不搞大开发为导向推动长…