Dockerfile使用

在 Docker 中,可以通过 docker build 命令和 Dockerfile 文件来构造自己的 Docker 镜像。

值得注意的是,docker build 命令会递归地将构建整个上下文(如,通常是某个本地目录)发送给 docker daemon,所以不要将根目录 / 作为构建上下文。

1. 常用指令

需要注意的是,RUN, COPY, ADD 指令会创建新的层。

FROM

FROM 指令用于初始化一个新的构建阶段,并为后续指令指定一个基础镜像。

FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

如果基础镜像有多个平台版本,可以通过 --platform 来指定要使用哪个版本,如,linux/amd64

可以通过 AS <name> 为当前构建阶段指定一个名字,后续可通过 COPY --from=<name> 来引用此阶段所构建的镜像。

如,

FROM busybox

LABEL

LABEL 指令用于为镜像添加元数据,可以通过 docker image inspect 命令来查看。

LABEL <key>=<value> <key>=<value> <key>=<value> ...

如,

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL description="This text illustrates \
that label-values can span multiple lines."

ENV

ENV 指令用于设置环境变量,其设置的环境变量可以被后续指令,且会持久地存储,容器运行时依旧存在;可以被 docker run 命令覆盖。

ENV <key>=<value> ...

如,

ENV DIRPATH=/path
WORKDIR $DIRPATH/a

ARG

ARG 指令用于定义变量,用户可以在构造镜像是传递相应的变量值。不同于 ENVARG 不会将变量持久化至容器运行时。

ARG <name>[=<default value>]

如,

FROM ubuntu
ARG CONT_IMG_VER
RUN echo $CONT_IMG_VER
$ sudo docker build --build-arg CONT_IMG_VER=2.3 .

WORKDIR

WORKDIR 指令用于为后续的 RUN, CMD, ENTRYPOINT, ADD, COPY 指令指定工作路径。如果后面的 WORKDIR 指令的参数是一个相对路径,则它是相对于上一个 WORKDIR 指令指定的工作路径的。

WORKDIR /path/to/workdir

如,

WORKDIR /a
WORKDIR b
WORKDIR c

RUN

RUN 指令会在当前镜像之上执行给定的命令,并将执行结果作为一个新的层。

RUN <command>
RUN ["executable", "param1", "param2", ...]
  • 第一种形式是在 shell 中执行命令,也就是说基础镜像需要包含指定的 shell 才行;
  • 第二种形式是 exec 形式,不会调用 shell(也就不会执行环境变量替换),可以执行任意可执行文件,其参数会被解析成 JSON 数组,所以需要使用双引号!

如,

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
RUN ["/bin/bash", "-c", "echo hello"]

ADD

ADD 指令用于拷贝本地文件、目录、远程文件至镜像中。

ADD [--chown=<user>[:<group>]] <src>... <dest>
ADD [--chown=<user>[:<group>]] ["<src>",... "<dest>"]

<src> 中可以包含通配符;如果 <dest> 不存在,则它会被自动创建(包括缺失的父目录)。

文件的默认属主/属组为 root,可以通过 --chown 来修改。

一些注意事项:

  • <src> 必须在构建上下文中;
  • 如果 <src> 是一个本地 tar 文件(被压缩为 gzip、bzip2、xz),则它会被解包为一个目录;
  • 如果 <dest> 表示一个目录,则它需要以 / 开始,以 / 结束。

如,

ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/

COPY

ADD 指令类似,但不支持从远程拷贝文件,此外它也不会自动解包 tar 文件。

COPY [--chown=<user>[:<group>]] <src>... <dest>
COPY [--chown=<user>[:<group>]] ["<src>",... "<dest>"]

如,

COPY --chown=55:mygroup files* /somedir/
COPY --chown=bin files* /somedir/
COPY --chown=1 files* /somedir/
COPY --chown=10:11 files* /somedir/

VOLUME

VOLUME 指令用于将容器中指定的目录挂载为匿名卷,可以通过 docker inspect 命令来查看其挂载到了主机哪个位置。

VOLUME path
VOLUME ["path1", "path2", ...]

如,

VOLUME ["/data1","/data2"]

EXPOSE

EXPOSE 指令用于指明容器应当在运行时监听指定的端口,而实际上,EXPOSE 指令并没有开放端口的功能,这需要通过 docker run 命令的 -p 选项来实现。

EXPOSE <port>[/protocol] [<port>[/<protocol>]...]

如,

EXPOSE 80/tcp
EXPOSE 80/udp
$ sudo docker run -p 80:80/tcp -p 80:80/udp ...

CMD

CMD 指令有3种形式,前两种和 RUN 指令类似,但不同于 RUNCMD 指令指定的命令是在容器运行时执行的(和 ENTRYPOINT 指令功能相同),而不是构建容器时;第三种形式的作用是给 ENTRYPOINT 指令提供默认参数(可以被 docker run 命令指定的参数给覆盖掉)。

CMD command param1 param2 ...
CMD ["executable", "param1", "param2", ...]
CMD ["param1","param2", ...]

如,

FROM ubuntu
CMD echo "This is a test." | wc -

FROM ubuntu
CMD ["/usr/bin/wc", "--help"]

ENTRYPOINT

ENTRYPOINT 指令用于指定容器启动(执行 docker run <image>)时的默认动作。 类似于 RUN 指令,ENTRYPOINT 指令也有 shell 和 exec 两种形式。

ENTRYPOINT command param1 param2 ...
ENTRYPOINT ["executable", "param1", "param2", ...]

当使用 shell 形式时,需要以 exec 开始,以保证 docker stop 命令能够正确地终止容器。

如,

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

FROM ubuntu
ENTRYPOINT exec top -b

2. 多阶段构建

多阶段构建可以有效地减小镜像的大小。它是通过为每个构建阶段提供一个名字,并结合 COPY --from=<build-stage-name> 来实现的,即,从其它构建阶段构建的镜像中拷贝需要的内容至当前镜像,如此可以大大减小最终镜像的体积。

如,

FROM golang:1.16-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

FROM scratch
COPY --from=build /bin/project /bin/project
ENTRYPOINT ["/bin/project"]
CMD ["--help"]

3. 构建镜像

默认情况下,docker build 使用构建上下文中的 Dockerfile 文件来构建镜像:

$ sudo docker build .

当然也可以通过 -f 选项来自定义 Dockerfile 文件:

$ sudo build -f /path/to/a/Dockerfile .

此外,也可以通过 -t 选项为生成的镜像打上(一个或多个)标签:

$ sudo docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .

最后,可以在构建上下文中添加 .dockerignore 文件来排除掉与构建无关的文件,格式类似于 .gitignore 文件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值