阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Dockerfile注意事项

199次阅读
没有评论

共计 4485 个字符,预计需要花费 12 分钟才能阅读完成。

准则

  1. 尽量将 Dockerfile 放在空目录中,如果目录中必须有其他文件,则使用.dockerignore 文件。
  2. 避免安装不必须的包。
  3. 每个容器应该只关注一个功能点。
  4. 最小化镜像的层数。
  5. 多行参数时应该分类。这样更清晰直白,便于阅读和 review,另外,在每个换行符 \ 前都增加一个空格。
  6. 对构建缓存要有清楚的认识。

指令注意事项

FROM

Dockerfile reference for the FROM instruction
任何时候,尽量使用官方镜像源作为你镜像的基础镜像。我们建议使用 Debian Image,因为其被很好地管理着,并且作为一个完整的发布包,但体积却保持着最小化(当前不足 150MB)。
1. FROM 必须是除了注释以外的第一行;
2. 可以有多个 FROM 语句,来创建多个 image;
3.

LABEL

Dockerfile reference for the LABEL instruction

RUN

Dockerfile reference for the RUN instruction
RUN 语句有两种格式:
1. RUN

apt-get

尽量避免使用 RUN apt-get upgrade 或者 dist-upgrade,因为基础镜像的很多核心包不会再未授权的容器中升级。
要结合 RUN apt-get update 和 apt-get install 在同一个 RUN 语句下一起使用。如:

    RUN apt-get update && apt-get install -y \
        package-bar \
        package-baz \
        package-foo

如果将 update 和 install 分开使用,执行多个 Dockerfile 时,会引起缓存问题,导致后面执行的 install 语句会失败。
另外,执行完 apt-get 语句后,最后最好加上删除安装包的语句,以减小镜像的体积。如:

RUN apt-get update && apt-get install -y \
    aufs-tools \
    automake \
    build-essential \
 && rm -rf /var/lib/apt/lists/*

注意:官方的 Debian 和 Ubuntu 镜像会自动执行“RUN apt-get clean”,所以不需要明确地删除指令。

管道使用

很多 RUN 命令都需要使用到管道,如:

RUN wget -O - https://some.site | wc -l > /number

Docker 使用 /bin/sh - c 解释器来执行这些命令,该解释器只评估管道最后一个操作的返回值来判断整个命令是否成功。在上面的例子中,只要 wc - l 命令成功了,即使 wget 命令失败了,也会创建一个新镜像。为了避免上述情况,可以在语句首部加上 set -o pipefail &&。比如:

RUN set -o pipefail && wget -O - https://some.site | wc -l > /number

注意:并非所有的 shell 都支持 -o pipefail 选项,比如说基于 Debian 的镜像下的模式 shell:dash shell。这种情况下,我们可以使用 exec 格式的 RUN 命令来显示地选择 shell 来支持 pipefail 选项。如:

RUN ["/bin/bash", "-c", "set -o pipefail && wget -O - https://some.site | wc -l > /number"]

CMD

Dockerfile reference for the CMD instruction
CMD 语句与 RUN 不同,RUN 是在 build 镜像的时候运行,而 CMD 语句是在 build 结束后运行。一个 Dockerfile 钟可以有多个 RUN 语句,虽然也可以有多个 CMD 语句,但是却只有最后一条 CMD 语句会执行。CMD 语句格式为:

CMD [“executable”,“param1”,“param2”…]

EXPOSE

Dockerfile reference for the EXPOSE instruction
EXPOSE 指令指明容器会监听链接的端口。因此,最好使用常用的、传统的应用端口。比如,Apache web 服务器使用 EXPOSE 80 等。
为了给外部链接使用,你需要使用 docker run 命令来制定容器端口和 host 端口的映射。

ENV

Dockerfile reference for the ENV instruction
用于设置环境变量,设置后,后面的 RUM 指令就可以使用之前的环境变量了。同时,还可以通过 docker run –env key=value,在容器启动时设置环境变量。如:

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

ADD 和 COPY

Dockerfile reference for the ADD instruction
Dockerfile reference for the COPY instruction
虽然 ADD 和 COPY 功能相似,但一般来讲,更建议使用 COPY。因为 COPY 比 ADD 更透明,COPY 只支持从本地文件到容器的拷贝,但是 ADD 还有一些其他不明显的特性(比如本地 tar 包解压缩和远程 URL 支持)。因此,ADD 的最优用处是本地 tar 包自动解压缩到镜像中。如:ADD rootfs.tar.xz /。
如果有多个 Dockerfile 步骤用于处理不同的文件,建议分开 COPY 它们,而不是一次性拷贝。这可以保证每个步骤的 build 缓存只在对应的文件改变时才无效。比如:

COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/

镜像的大小很重要,因此不鼓励使用 ADD 从远端 URL 获取包;可以使用 curl 或者 wget 来代替。这种方式你可以删除不再需要的文件,如解压缩后的 tar 包,从而不需要再添加额外的 layer 到镜像中。比如,你应该避免这样使用:

ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all

而应该如此:

RUN mkdir -p /usr/src/things \
    && curl -SL http://example.com/big.tar.xz \
    | tar -xJC /usr/src/things \
    && make -C /usr/src/things all

对于不需要使用 ADD 命令 tar 包自动解压缩功能的文件和目录,你应该总是使用 COPY。

ENTRYPOINT

Dockerfile reference for the ENTRYPOINT instruction
使用 ENTRYPOINT 来设置镜像的主命令,就像这个镜像运行时就是这条命令一样(然后再使用 CMD 作为默认的 flag)。
我们使用 s3cmd 命令作为镜像的主命令。

ENTRYPOINT ["s3cmd"]
CMD ["--help"]

VOLUME

Dockerfile reference for the VOLUME instruction
VOLUME 指令一般用于数据库的存储区域,配置存储,或者 docker 容器创建的文件和目录。

USER

Dockerfile reference for the USER instruction
如果服务可以在不需要特权的情况下运行,那么就应该使用 USER 来切换用户至非 root 用户。可以用 RUN 命令创建用户组和用户如:

RUN groupadd -r postgres && useradd -r -g postgres postgres

应该避免安装和使用 sudo,因为它有不可预知的 TTY 和信号转移特性,会产生很多问题。如果的确一定要使用类似 sudo 的功能(如 root 下初始化 daemon,非 root 下运行),可以使用“gosu”。

WORKDIR

Dockerfile reference for the WORKDIR instruction
为了 Dockerfile 内容更加清晰和可靠,最好总是使用绝对路径。同样地,应该使用 WORKDIR,而不是使用类似“cd … && do-something”这样的指令,因为那样会导致难以阅读、查找错误和维护。

ONBUILD

Dockerfile reference for the ONBUILD instruction

其他资源

Dockerfile Best Practices
Dockerfile Reference
https://github.com/docker-library/buildpack-deps/blob/master/jessie/Dockerfile
.dockerignore file
http://dockone.io/article/2034
https://docs.resin.io/deployment/build-optimisation/

更多 Docker 相关教程见以下内容

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm

Ubuntu 使用 VNC 运行基于 Docker 的桌面系统  http://www.linuxidc.com/Linux/2015-08/121170.htm

阿里云 CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm

Ubuntu 15.04 下安装 Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm

在 Ubuntu Trusty 14.04 (LTS) (64-bit)安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm

在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm

Ubuntu 16.04 上 Docker 使用手记 http://www.linuxidc.com/Linux/2016-12/138490.htm

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-03/141582.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计4485字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中