天下風雲出我輩
一入江湖歲月催

使用Dockerfile创建镜像

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

基本结构

Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。
一般而言,Dockerfile分为4个部分:
基础镜像信息、维护者信息、镜像操作指令、容器启动时执行指令。
示例:

#This dockerfile uses the centos image
#VERSION 1
#Author:docker_user
#Command format:Instruction [arguments / command] ..

#第一行必须制定基于的基础镜像
FROM centos

#维护者信息
LABEL maintainer docker_user [email protected]

#镜像的操作指令
RUN echo "hello world"
RUN yum update && yum install -y net-tools
RUN yum install -y nginx

#容器启动时执行指令
CMD /usr/sbin/nginx

其中,一开始必须指明所基于的镜像名称,接下来一般会说明维护者信息。后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。最后是CMD指令,来指定运行容器时操作的命令。

 

Dockerfile指令

配置指令

ARG

定义创建镜像过程中使用的变量。

格式为ARG <name> [=<default value>]

在执行docker build时,可以通过-build-arg[=] 来为变量赋值。当镜像编译成功后,ARG指定的环境变量将不存在(ENV指定的变量将在镜像中保留)

FROM

指定所创建镜像的基础镜像,如果本地不存在,则默认会去Docker Hub下载指定镜像。
格式:FROM <image>或 FROM <image>:<tag>
任何Dockerfile中的第一条指令必须为FROM指令。并且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)为了保证镜像的精简,可以选用体积较小的镜像如Alpine或Debian作为基础镜像。例如:

ARG VERSION=9.3

FROM debian:${VERSION}

LABEL

LABEL指令可以为生成的镜像添加元数据标签信息。这些信息可以用来辅助过滤出特定镜像。

格式为:LABEL <key>=<value> <key>=<value>……….

例如:

LABEL version="1.14.1"

LABEL author="[email protected]" date="2020-01-01"

LABEL description="this text ..........."

EXPOST

声明镜像内服务监听的端口

格式:EXPOSE <port> [<port>/<protocol>…..]
比如:EXPOSE 22 80 443

该指令只是起到声明作用,并不会自动完成端口映射。

ENV

指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。

格式为:ENV <key> <value> 或 ENV <key>=<value>…….

例如:

ENV APP_VERSION=1.1
ENV APP_HOME=/usr/local/app
ENV PATH $PATH:/usr/local/bin

ENTRYPOINT

指定镜像的默认入口命令,该入口命令在启动容器时作为根命令执行,所有传入值作为该命令的参数
两种格式:
ENTRYPOINT [“executable”, “param1”, “param2”]  exec调用执行;

ENTRYPOINT command param1 param2 (shell中执行)

此时,CMD指令指定值将作为根命令的参数,配置容器启动后执行的命令,并且不可被docker run 提供的参数覆盖,每个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。

VOLUME

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

USER

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

要临时获取管理员权限可以使用gosu,而不推荐sudo

WORKDIR

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

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为:/a/b/c

ONBUILD

格式为:ONBUILD [INSTRUCTION]

指定当基于所生成镜像创建子镜像时,自动执行的操作指令。

例如,使用如下的Dockerfile创建父镜像ParentImage,指定ONBUILD指令:

#Dockerfile for parentImage

[….]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build –dir /app/src
[….]

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

FROM ParentImage

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

ADD . /app/src
RUN /usr/local/bin/python-build –dir /app/src
……..

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

STOPSIGNAL
指定所创建镜像启动的容器接收退出的信号值。例如:
STOPSIGNAL signal

HEALTHCHECK
配置所启动容器如何进行健康检查(如何判断健康与否),自docker 1.12开始支持
格式有两种:
HEALTHCHECK [OPTIONS] CMD command:根据所执行命令返回值是否为0来判断;
HEALTHCHECK NONE:禁止基础镜像中的健康检查。
OPTION支持:
①–interval=DURATION(默认为:30s):过多久检查一次;
②–timeout=DURATION(默认为:30s):每次检查等待结果的超时;
③–retries=N(默认为:3):如果失败了,重试几次才最终确定失败。

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

操作指令:

RUN
运行指定命令。
格式:RUN <command>或RUN [“executable”,”param1″,”param2″]。注意,后一个指令会被解析为Json数组,因此必须用双引号。
前者默认将在shell终端运行命令,即/bin/sh -c;     后者则使用exec执行,不会启动shell环境。
比如:RUN yum install httpd
RUN [“/bin/bash”,”-c”,”echo hello”]
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新镜像。当命令过长时,可以使用\来换行。

CMD
CMD指令用来指定启动容器时默认执行的命令。
支持3种格式:
•CMD [“executable”, “param1”, “param2”],相当于执行executable param1 param2,推荐方式

•CMD command param1 param2  :在默认的Shell中执行,提供给需要交互的应用;

•CMD [“param1”, “param2”] :   提供给ENTRYPOINT的默认参数。

RUN和CMD看起来很像,但是CMD用来指定容器启动时用到的命令,只能有一条。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时,指定了运行命令(作为run命令的参数),则会覆盖掉CMD指定的命令。
比如:CMD [“/bin/bash”, “/usr/local/nginx/sbin/nginx”, “-c”, “/usr/local/nginx/conf/nginx.conf”]

ADD

添加内容到镜像

格式为:ADD <src> <dest>

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

ADD *.c /code/

COPY

复制内容到镜像

格式为COPY <src> <dest>

复制本地主机的<src>(为Dockerfile所在目录的相对路径,文件或目录)为容器中的<dest>;。目录路径不存在时,会自动创建。COPY与ADD指令类似,当使用本地目录为源目录时,推荐使用COPY。

创建镜像

编写完Dockerfile之后,可以通过docker [image] build命令来创建镜像。
格式:docker build [option] PATH | URL | –
该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下的所有内容发送给Docker服务端; Docker服务端在校验Dockerfile格式通过后,逐条执行其中定义的指令,碰到ADD、COPY和RUN指令会生成一层新的镜像。最终如果创建镜像成功,会返回最终镜像的ID。

①如果使用非上下文路径下的Dockerfile,可以通过-f选项来指定其路径
②要指定生成镜像的标签信息,可以使用-t选项

例如:指定的Dockerfile所在路径为/tmp/docker_builder/,并且希望生成的镜像标签为build_repo/frist_image:1.0,可以使用:
docker build -t build_repo/first_image:1.0 /tmp/docker_builder/ .

docker build 命令选项表   参见官网

选择父镜像:

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

用户可以选择两种镜像作为父镜像,一种是基础镜像,一种是普通的镜像(往往由第三方创建,基于基础镜像)

基础镜像比较特殊,其Dockerfile中往往不存在FROM指令,或者基于scratch镜像(FROM scratch),这意味着其在整个镜像树种处于根的位置。

使用.dockerignore文件:

可以通过.dockerignore文件(每一行添加一条匹配模式)来让Docker忽略路径或文件,在创建镜像时候不将无关数据发送到服务端。

例如:下面的包括了6行忽略的模式(第一行为注释):

#.dockrignore文件中可以定义忽略模式

*/temp*
*/*/temp*
tmp?
~*
Dockerfile
!README.md
  • ” * ” 表示任意多个字符
  • “ ? ”代表单个字符
  • “ ! ”表示不匹配

多步骤创建:

自17.05版本开始,Docker支持多步骤镜像创建(Multi-stage build)特性,可以精简最终生成的镜像大小。对于需要编译的应用(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"]

创建镜像并运行:

docker build -t tomasy/test-multistage:latest .

docker run --rm tomasy/test-multistage
Hello,Docker

#查看镜像
REPOSITORY              TAG        IMAGE ID           CREATED          SIZE
tomasy/test-multistage latest     21ff3414ae2f About a minute ago     6.83MB

赞(4) 打赏
未经允许不得转载:Anonym0x1 » 使用Dockerfile创建镜像

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏