Dockerfile文件构建镜像:
Dockerfile是一个文本格式的配置文件,可以使用Dockerfile来快速创建自定义的镜像。
Dockerfile:一行行命令语句+以#开头的注释行。
Dockefile主体内容:
简单示例:
首行通过注释来指定解析器指令,后续通过注释说明镜像的相关信息。
主体部分首先用FROM指令来指明所基于的镜像名称。接下来是使用LABEL指令说明维护者信息。接下来是镜像的操作指令。没运行一条RUN指令,镜像添加新的一层,最后是CMD指令,指定运行容器时的操作命令。
可查看更多官方镜像的Dockerfile写法。
Dockerfile中的指令一般格式:INSTRUCTION arguments.包括”配置指令(配置镜像信息)“、”操作指令(具体执行操作)“
分类 | 指令 | 说明 |
配置指令 | ARG FROM LABEL EXPOSE ENV ENTRYPOINT VOLUME USER WORKDIR ONBUILD STOPSIGNAL HEALTHCHECK SHELL |
定义创建镜像过程中使用的变量 指定所创建镜像的基础镜像 为生成的镜像添加元数据标签信息 声明镜像内服务监听的端口 指定环境变量 指定镜像的默认入口命令 创建一个数据卷挂载点 指定运行容器时的用户名或UID 配置工作目录 创建子镜像时指定自动执行的操作指令 指定退出的信号值 配置所启动容器如何进行健康检查 指定默认shell类型 |
操作指令 | RUN CMD ADD COPY |
运行指定命令。 启动容器时指定默认执行的命令。 添加镜像 复制内容到镜像 |
上述指令的具体说明:
1.1 ARG:定义创建镜像过程中使用的变量。
格式:ARG
执行docker build时,通过-build--arg[=]来为变量复制。当镜像编译成功后,ARG指定的变量将不再存在。(ENV指定的变量将在镜像中保留)。
docker内置了一些镜像创建变量(直接使用不需要声明):HTTP_PROXY HTTPS_PROXY FTP_PROXY NO_PROXY
1.2 FROM:指定所创建镜像的基础镜像。
格式:FROM
或 FROM
或 FROM
任何Dockerfile中第一条指令必须是FROM指令。如果在同一个Dockerfile创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。
示例:
ARG VERSION = 3
FROM nginx:${VERSION}
1.3 LABEL:可以为生成的镜像添加元数据标签信息。用来辅助过滤出特定镜像。
格式:LABEL
示例:
LABEL version = "1.0.0"
LABEL author = "yinlei" data = "2020-01-16"
LABEL description = "This text is the test"
1.4 EXPOSE:声明镜像内服务监听的端口。
格式:EXPOSE
EXPOSE指令只是声明作用,并不会自动完成端口映射。
如果要映射端口出来,在启动容器的时候应该使用-p参数。
示例:‘
EXPOSE 22 80 443
1.5 ENV: 指定环境变量,在镜像生成过程中hi被后续的RUN指令使用,在镜像启动的容器中也会存在。
格式: ENV 或 ENV 指定的环境变量在运行时候可以被覆盖掉。如docker run --env=xxxx built_image 示例: ENV APP_VERSION = 1.0.0 ENV APP_HOME=/usr/local/app ENV PATH $PATH:/usr/local/bin 当一条ENV指令中同时为多i个环境变量复制并且值也是从环境变量读取时,会为变量都赋值后再更新: ENV key1 = value2 ENV key1 = value1 key2 = ${key1} 最终结果是key1=value1 key2 =value2 1.6 ENTRYPOINT:指定镜像的默认入口命令,该入口命令会再在启动容器时作为根命令执行,所i有传入值作为该命令的参数。 2种格式: 此时,CMD指令指定值将作为根命令的参数 每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效。 在运行时,可以被--entrypoint参数覆盖掉。 1.7 VOLUME:创建一个数据卷挂载点。 格式: VOLUME ["/data"] 运行容器时候可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保持的数据等。 1.8 USER:指定运行容器时的用户名或UID。后续的RUN等指令也会使用指定的用户身份。 格式: USER daemon 当服务不再需要管理员权限时,可以通过该命令执行运行用户,并在dockerfile中创建所需要的用户: RUYN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres 要临时获取管理员权限可以使用gosu命令。 1.9 WORKDIR:为后续的RUN CMD ENTRYPOINT指定配置工作目录。 格式:WORKDIR /path/to/workdir 可以使用多个WORKDIR命令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。 例如: WORKDIR /a WORKDIR /b WORKDIR /c 最终路径:/a/b/c 推荐只使用绝对路径 1.10 ONBUILD:指定基于所生成镜像创建子镜像时自动执行的操作指令。 格式:ONBUILD [INSTRUCTION] 示例:使用dockerfile构建父镜像ParentImage,指定ONBUILD指令 # Docker for parentImage ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src 使用docker build 创建子镜像childImage时,会首先执行ParentImage中配置的ONBUILD指令: FROM parentImage 等价于在ChildImage的dockerfile中添加了: ADD . /app/src RUN /usr/local/bin/python-build --dir /app/src 由于 ONBUILD是隐式执行的,推荐在使用它的镜像标签中进行标注:如ruby:2.1-onbuild ONBUILD在创建专门用于自动编译、检查等操作的基础镜像的时候非常有用。 1.11 STOPSIGNAL:指定所创建镜像启动的容器接收退出的信号值。 STOPSIGNAL signal 1.12 HEALTHCHECK:配置所启动容器如何进行健康检查。(dockjer 1.12+支持) 2种格式: OPTIONS支持的参数: 1.13 SHELL: 指定其他命令使用shell时的默认shell类型: SHELL ["executable","parameters"] 默认值:["/bin/sh","-c"] windows: shell路径使用了 \ 做为分隔符,一般在dockerfile开头加#eccape=' 来指定转义符。 2.1 RUN : 运行指定命令。 格式: RUN 或 RUN ["executable","parameter1",""parameter2"] RUN ["executable","parameter1",""parameter2"]这种方式的指令会被解析为json数组,所以需用双引号。且使用exec执行,不会启动shell环境。 RUN 指定使用其他终端类型可以使用第2个方式: 例如 RUN["/bin/bash","-c","echo yinlei"] 每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像层。 命令较长使用 \ 来换行。 2.2 CMD: 用来指定启动容器时默认执行的命令。 支持3种格式: 每个dockerfile只能有一条CMD命令。 指定多条命令,只有最后一条生效。 用户启动容器时候手动指定了运行的命令参数,则会覆盖掉dockerfile中指定的命令。 2.3 ADD:添加内容到镜像。 格式:ADD 复制指定的 路径支持正则。 例如:ADD *.c / code/ 2.4 COPY: 复制内容到镜像。 格式: COPY 复制本地主机的 路径支持正则。 编写完dockefile后,通过docker [image] build命令来创建镜像。 格式:docker build [OPTIONS] PATH | URL | - 读取指定路径下(包括子目录)的dockefile.并将该路径下所有数据作为上下文context发送给docker服务端。 dockerf服务端在校验dockefile格式通过后,逐条执行其中定义的命令,碰到ADD COPY RUN指令会生成一层新的镜像。最终如果创建镜像成功会返回镜像的ID。 如果上下文过大,会导致发送大量数据给服务端,延缓创建过程。 除非是生成镜像所必须的文件,不然不要放回到上下文路径下。如果使用非上下文路径下的dockerfile,可以通过-f选项来指定其路径。 要指定生成镜像的标签信息,可通-t选项。可以重复使用-t为镜像一次添加多个名称。 OPTIONS支持的选项: 添加创建时的变量 继承的上层cgroup 创建镜像时不使用缓存 创建成功后自动删除中间过程容器,默认为真 持续获取创建的上下文 大部分情况下,生成的新镜像都需要通过FROM指令来指定父镜像。 父镜像是生成镜像的基础,会直接影响到所生成镜像的带下和功能。 用户可以选择2种镜像作为父镜像: 基础镜像比较特殊,其dockfile中往往不存在FROM指令,或者基于scratch镜像(FROM scratch),意味着其在整个镜像树中处于根的位置。 普通镜像也可以作为父镜像来使用,包括常见的busybox 、debian 、 ubuntu等 Docker不同类型镜像之间的继承关系: 每一行添加一条匹配模式让Docker忽略匹配路径或文件,在创建镜像时不将无关的数据发送到服务器。使用方法和git的.gitignore类似。 Docker支持多步骤镜像创建特性,精简最终生成的镜像大小i。 对于需要编译的应用,通常至少需要准备2个环境的docker镜像: 优点:使用单一的dockefile,降低维护复杂度。 示例: 以go为例: 创建干净目录,并创建main,go 创建dockerfile,使用golang:1.9镜像编译应用2进制文件为app,使用精简的镜像alpine:latest作为运行环境。 执行如下命令创建镜像并运行应用: 尝试从下面几个角度进行思考完善镜像:
2.操作指令:
COPY与ADD指令功能类似,当使用本地目录为源目录时,推荐COPY
创建镜像:
选项
说明
-add-host list
添加自定义的主机名到IP的映射
-build-arg list
-cache-from strings
使用指定镜像作为缓存源
-cgroup-parent string
-compress
使用gzip来压缩创建上下文数据
-cpu-period int
分配的CFS调度器时长
-cpu-quota int
CFS调度器总份额
-c, -cpu-shares int
CPU权重
-cpuset-cpus string
多CPU允许使用的CPU
-cpuset-mems string
多CPU允许使用的内存
-disable-content-trust
不进行镜像校验,默认为真
-f, -file string
dockerfile名称
-force-rm
总是删除中间过程的容器
-iidfile string
将镜像id写入到文件
-isolation string
容器的隔离机制
-label list
配置镜像的元数据
-m,-memory bytes
限制内存和缓存的总量
-memory-swap bytes
k限制内存和缓存的总量
-network string
指定RUN命令时候的网络模式
-no-cache
-platform string
指定平台类型
-pull
总是尝试获取镜像的最新版本
-q,-quiet
不打印创建过程中的日志信息
-rm
-security-opt strings
指定安全相关的选项
-shm-size bytest
/dev/shm的大小
-squash
将新创建的多层挤压放入到一层中
-stream
-t,-tag list
指定镜像的标签列表
-target string
指定创建的目标阶段
-ulimit ulimit
指定ulimit的配置
选择父镜像:
使用.dockerignore文件:
多步骤创建:docker17.05+
package main
import("fmt")
func main(){
fmt.Println("hello world");
}
FROM golang:1.9 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 -cacertificates
WORDIR /root/
COPY --from=builder /go/src/test/app .
CMD ["./app"]
docker build -t yeasy/test-multistage:latest
docker run --rm yeasy/test-multistage:latest
查看成功的镜像大小:
docker images|grep test-multistage
合理的构建镜像: