Dockerfile编写

Dockerfile简介

Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile快速创建自定义的镜像
Dockerfile有一行行命令语句组成,支持以#开头的注释行。
一般,Dockerfile分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令

Dockerfile常用指令

参考:https://docs.docker.com/engine/reference/builder/#usage

FROM

用法:

FROM [--platform=<platform>] <image> [AS <name>]
# 或
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
# 或
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

说明:

  • 中括号[]中的之为可选值

  • Dockerfile必须从FROM指令开始(仅ARG可以先于FROM指令,可以用来指定FROM参数)

  • 如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令

  • AS name 可以给镜像取名字,可以作为多阶段构建的基础镜像给予FROM指令,或者COPY --from=<name>

  • --platform 可以用于指定镜像平台(如linux/amd64,linux/arm64);用于交叉编译构建

RUN

用法:

# shell模式,默认使用 /bin/sh -c 执行命令
RUN <command>
# exec模式,例如 RUN ["/bin/bash", "-c", "echo hello"]
RUN ["executable", "param1", "param2"]

说明:

  • RUN指令在构建时将会生成一个新的镜像层并且执行RUN指令后面的内容

  • 镜像层数会增加镜像大小,因此尽量将多个命令放在一个RUN指令中(使用&&平均多个命令)

  • RUN指令后面跟的内容比较复杂时,建议使用反斜杠(\) 结尾并且换行

  • RUN指令后面的内容尽量按照字母顺序排序,提高可读性。

LABEL

用法:

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

说明:

  • 使用LABEL为镜像添加元数据以标识该镜像

CMD和ENTRYPOINT

用法:

CMD ["executable","param1","param2"]  # exec形式,推荐模式
CMD ["param1","param2"]  # 作为ENTRYPOINT的默认参数
CMD command param1 param2  # shell模式
ENTRYPOINT ["executable", "param1", "param2"]  # exec模式,推荐模式
ENTRYPOINT command param1 param2  # shell模式

说明:

  • CMD用来设置容器启动后默认执行的命令及其参数;ENTRYPOINT 用来配置容器启动时运行的命令。二者都可以作为容器的启动入口
  • 每个Dockerfile只能有一个CMDENTRYPOINT,如果有多个,只有最后一个生效
  • 如果CMD作为ENTRYPOINT的默认参数,则CMD和ENTRYPOINT都必须使用json数组形式(也就是exec形式)
  • 使用 exec 模式启动容器时,容器的 1 号进程就是 CMD/ENTRYPOINT 中指定的命令,而使用 shell 模式启动容器时相当于我们把启动命令放在了 shell 进程中执行,等效于执行 /bin/sh -c “task command” 命令。因此 shell 模式启动的进程在容器中实际上并不是 1 号进程。

二者的区别:

  • Dockerfile 中如果使用了ENTRYPOINT指令,启动 Docker 容器时需要使用 --entrypoint 参数才能覆盖 Dockerfile 中的ENTRYPOINT指令 ,而使用CMD设置的命令则可以被docker run后面的参数直接覆盖。

  • ENTRYPOINT指令可以结合CMD指令使用,也可以单独使用,而CMD指令只能单独使用

ADD和COPY

用法:

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

说明:

  • --chown是可选的,用来修改复制文件的用户和用户组
  • ADD和COPY都是从外部往容器中添加文件。但是COPY只支持基本的文件和文件夹;而ADD支持更多的文件类型,比如可以是URL和压缩包(.tar.gz会自动解压)
  • 尽量使用COPY指令,ADD指令较为复杂。二者区别

USER

用法:

USER <user>[:<group>]
USER <UID>[:<GID>]

说明:

  • 指定运行容器时的用户名/用户组或者UID/GID;后续的 RUN等指令也会使用该用户

WORKDIR

用法:

WORKDIR /path/to/workdir

说明:

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

ARG

用法:

ARG <name>[=<default value>]

说明:

  • ARG指令用来定义了一个变量,用户可以在构建时docker build使用带有--build-arg <varname>=<value>标志的命令将其传递给构建器。如果用户指定了未在Dockerfile中定义的构建参数,则构建会输出警告。[Warning] One or more build-args [foo] were not consumed.

EXPOSE

用法:

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

说明:

  • 指定Docker容器时监听的端口,可以指定协议是TCP还是UDP;默认是TCP
  • EXPOSE并不会真的去启动该端口,容器的实际监听端口是应用的监听端口;EXPOSE主要是用来指导运行容器的人员该容器运行服务的发布的端口。

VOLUME

用法:

VOLUME ["/data"]

说明:

  • 创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放需要持久化保存的数据
  • 容器启动时,该挂载点会自动在宿主机上创建相应的目录(无法指定);可以通过 docker inspect id 查看挂载的目录

Dockerfile最佳实践

参考文档:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#exclude-with-dockerignore

单一职责

由于容器的本质是进程,一个容器代表一个进程,因此不同功能的应用应该尽量拆分为不同的容器,每个容器只负责单一业务进程。

提供注释信息

Dockerfile 也是一种代码,我们应该保持良好的代码编写习惯,晦涩难懂的代码尽量添加注释,让协作者可以一目了然地知道每一行代码的作用,并且方便扩展和使用。

精简容器

1、合理选择基础镜像,减少基础镜像大小(比如java应用只需要jre,而不是jdk)

2、不安装不必要的软件包,如vim,gcc等

3、减少镜像层数

RUNCOPYADD指令会增加镜像层数;其他指令会创建临时镜像,不会增加镜像大小。

​ 可以使用多阶段构建,仅仅将最终的工件复制到最终镜像中。

.dockerignore文件

使用.dockerignore忽略不需要参与构建的文件

这是一个示例.dockerignore文件:

# comment
*/temp*
*/*/temp*
temp?

此文件导致以下生成行为:

规则行为
# comment忽略了。
*/temp*排除名称以temp根的任何直接子目录开头的文件和目录。例如,/somedir/temporary.txt排除了普通文件,也排除了目录/somedir/temp
*/*/temp*排除temp从根以下两个级别的任何子目录开始的文件和目录。例如,/somedir/subdir/temporary.txt被排除。
temp?排除根目录中名称为的一个字符扩展名的文件和目录temp。例如,/tempa/tempb被排除。

使用构建缓存

默认会使用构建缓存加快构建速度

docker build增加参数--no-cache=true可以禁用缓存

正确设置时区

默认从docker.hub中获取的镜像都是UTC时区(世界标准时区),可以通过如下方式设置为东八区

Ubuntu 和Debian 系统可以向 Dockerfile 中添加以下指令:

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" >> /etc/timezone

CentOS 系统则向 Dockerfile 中添加以下指令:

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

Dockerfile参考

官方Dockerfile参考链接

Go

Nginx

Hy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值