对Dockerfile代码片段进行审核,并总结Dockerfile的最佳实践

本教程旨在重点介绍如何在阿里巴巴云上使用Dockerfile进行实践性经验积累。

此博客为英文版翻译而来。您可以在此处查看原文。部分内容使用机器翻译。若有翻译错误之处,请指出,不胜感激。

阿尔温·博塔,阿里巴巴云科技共享作者。Tech Share是阿里巴巴云的激励计划,鼓励在云社区内共享技术知识和最佳实践。

这个教程与前三个教程不同,因为它没有复制粘贴、使用shell或执行命令的步骤。

请确保您安装了最新版本的Docker,并可访问阿里巴巴云弹性计算服务实例,以便按照本教程的步骤进行操作。关于在Linux服务器上安装Docker的方法,请参考本教程。

这个教程包括以下几个部分。

1、一些Dockerfiles片段的审查可以在https://hub.docker.com找到。
2、我们将构建一个汇总了这些片段洞察的演示Dockerfile。
3、Dockerfile术语汇编文本
4、Dockerfile成功案例总结
Dockerfiles片段的审查是无特定顺序的。

请注意,其中一些代码片段只包含非常基本的信息 – 不必担心。将这些基本概念结合起来,您可以创建出高质量的Dockerfile。

Dockerfile 的片段- 对 EXPOSE 进行审查

请以汉语本地化方式重新述说以下内容,只需一种选择:
https://github.com/docker-library/cassandra/blob/0e270a93b53119818f9c71fa273cda3a07d0bf5c/2.1/Dockerfile

# 7000: intra-node communication
# 7001: TLS intra-node communication
# 7199: JMX
# 9042: CQL
# 9160: thrift service
EXPOSE 7000 7001 7199 9042 9160
CMD ["cassandra", "-f"]

这个片段位于Dockerfile的右下方。

不必阅读整个Dockerfile,就能像其他人一样找到分散在其中的随机散列命令。

所有的端口号按顺序排列整齐。所有的端口号都简洁地写出来了。简洁而完美-只需用一个词记住每个端口的功能。

#docline的端口号和EXPOSE行的端口号匹配,是正确且完整的。没有矛盾。

你的展示必须既专业又友善,即使对于新手也要显得亲切。

Cassandra是什么?

请从https://zh.wikipedia.org/wiki/Apache_Cassandra进行参考。

Apache Cassandra是一个免费且开源的分布式宽列存储的NoSQL数据库管理系统,它被设计用于处理跨越多个商业服务器的大量数据,并提供无单点故障的高可用性。

Cassandra为跨多个数据中心的集群提供强大的支持,并通过异步无主复制实现为所有客户端提供低延迟的操作。

Dockerfiles的代码片段-用户ID的评论

以下是使用中文本地化的翻译选项(只提供一种版本):
https://github.com/docker-library/cassandra/blob/0e270a93b53119818f9c71fa273cda3a07d0bf5c/2.1/Dockerfile

# explicitly set user/group IDs
RUN groupadd -r cassandra --gid=999 && useradd -r -g cassandra --uid=999 cassandra

RUN groupadd -r sonarqube && useradd -r -g sonarqube sonarqube

Neo4j是一种高度可扩展且结构稳固的本地图形数据库。

RUN addgroup -S neo4j && adduser -S -H -h /var/lib/neo4j -G neo4j neo4j

我还找到了几个Dockerfile,但它们都以相同的方式编写:将addgroup和adduser合并到一行中。

以下、我对neo4j进行了修改,使其分成了两行:看起来很完美。

RUN addgroup -S neo4j \
  && adduser -S -H -h /var/lib/neo4j -G neo4j neo4j

Dockerfile代码片段的审查 – apt-get安装

请将以下内容在中文以一种方式进行改述:
https://github.com/nextcloud/docker/blob/424364e2e10a9d6e1a31e6659e2149aac1f1c772/12.0/apache/Dockerfile

请把这个链接中的内容以中文重新描述:
https://github.com/nextcloud/docker/blob/424364e2e10a9d6e1a31e6659e2149aac1f1c772/12.0/apache/Dockerfile

下一代的云端:可以安全存储所有数据。可以从任何设备访问和共享文件、日历、联系人、邮件等。

 RUN set -ex; \
    \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        rsync \
        bzip2 \
        busybox-static \
    ; \
    rm -rf /var/lib/apt/lists/*; \

这是我找到的最易读的apt-get说明书。

请将上面的文本与下面的其他例子进行比较,以确认它的优势何在。

https://github.com/carlossg/docker-maven/blob/f581ea002e5d067deb6213c00a4d217297cad469/jdk-10-slim/Dockerfile 的原生中文意思是:

Apache Maven是一种用于软件项目管理和理解的工具。

RUN apt-get update && \
    apt-get install -y \
      curl procps \
  && rm -rf /var/lib/apt/lists/*   

不一致且未对齐的缩进。

请问你需要对以下内容进行中文本地化重述吗?

https://github.com/docker-library/logstash/blob/606dfc2ead6902c11a0d809d7d66b192b87177e6/5/Dockerfile

Logstash是一种用于收集、处理和传输事件和日志消息的工具。

# install plugin dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
        apt-transport-https \
        libzmq5 \
    && rm -rf /var/lib/apt/lists/*

运行 “apt-get update && apt-get install” 命令可以一次性完成。Neo4j(下面的20行)每行只有一个命令。请看看它有多简单易读。

请用中文将以下内容进行释义: https://github.com/docker-library/openjdk/blob/89851f0abc3a83cfad5248102f379d6a0bd3951a/6-jdk/Dockerfile

Java是一种并发性的、基于类的、面向对象的语言。

RUN apt-get update && apt-get install -y --no-install-recommends \
        bzip2 \
        unzip \
        xz-utils \
    && rm -rf /var/lib/apt/lists/*

apt-get update && apt-get install 可以在一行命令中完成。还有一些命令是每行只有一个的。请看下面的例子,可以看出它有多容易阅读。

请给出以下中文表达的同义短语,只需要一种选择:
https://github.com/neo4j/docker-neo4j-publish/blob/94477399f63ab99c035e50b46f642e791413dcaa/3.4.9/community/Dockerfile

Neo4j是一款具有高度可扩展性和强大的本地图形数据库。

RUN apk add --no-cache --quiet \
    bash \
    curl \
    tini \
    su-exec \
    && curl --fail --silent --show-error --location --remote-name ${NEO4J_URI} \
    && echo "${NEO4J_SHA256}  ${NEO4J_TARBALL}" | sha256sum -csw - \
    && tar --extract --file ${NEO4J_TARBALL} --directory /var/lib \
    && mv /var/lib/neo4j-* /var/lib/neo4j \
    && rm ${NEO4J_TARBALL} \
    && mv /var/lib/neo4j/data /data \
    && chown -R neo4j:neo4j /data \
    && chmod -R 777 /data \
    && chown -R neo4j:neo4j /var/lib/neo4j \
    && chmod -R 777 /var/lib/neo4j \
    && ln -s /data /var/lib/neo4j/data \
    && apk del curl

由于每行只有一个命令,所以非常容易阅读。

以字母顺序显示已安装的APK包列表。

Curl 以第6行调用,并在最后一行被删除。因为不再需要,所以删除了它。

在第10行中提取了NEO4J_TARBALL,并在第12行中将其删除。

Dockerfiles代码片段的评论 – ini文件。 (Dockerfiles de suǒ de lù comment – ini

https://github.com/nextcloud/docker/blob/424364e2e10a9d6e1a31e6659e2149aac1f1c772/12.0/apache/Dockerfile 的内容请用中文进行重述。

什么是Nextcloud?

我们会安全保存所有数据。您可以从任何设备按照您喜欢的条件访问并共享文件、日历、联系人和邮件等各种内容。

RUN { \
        echo 'opcache.enable=1'; \
        echo 'opcache.enable_cli=1'; \
        echo 'opcache.interned_strings_buffer=8'; \
        echo 'opcache.max_accelerated_files=10000'; \
        echo 'opcache.memory_consumption=128'; \
        echo 'opcache.save_comments=1'; \
        echo 'opcache.revalidate_freq=1'; \
    } > /usr/local/etc/php/conf.d/opcache-recommended.ini; \
    \
    echo 'apc.enable_cli=1' >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini; \
    \
    echo 'memory_limit=512M' > /usr/local/etc/php/conf.d/memory-limit.ini; \
    \
    mkdir /var/www/data; \
    chown -R www-data:root /var/www; \
    chmod -R g=u /var/www

在opcache-recommended.ini文件中添加了前7行的回音设置,使其非常整洁。
通过四个干净的空行清晰地分隔了四个不同的目的。

关于Dockerfiles代码片段的审查。

请原生汉语重述以下链接中的内容,只需一种选项:
https://github.com/jenkinsci/docker/blob/587b2856cd225bb152c4abeeaaa24934c75aa460/Dockerfile

请参考以下链接中的内容:
https://github.com/jenkinsci/docker/blob/587b2856cd225bb152c4abeeaaa24934c75aa460/Dockerfile

Jenkins是一种持续集成和交付服务器。

FROM openjdk:8-jdk

RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*

ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
ARG http_port=8080
ARG agent_port=50000

ENV JENKINS_HOME /var/jenkins_home
ENV JENKINS_SLAVE_AGENT_PORT ${agent_port}

'# Jenkins is run with user `jenkins`, uid = 1000
'# If you bind mount a volume from the host or a data container, 
'# ensure you use the same uid
RUN groupadd -g ${gid} ${group} \
    && useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user}

'# for main web interface:
EXPOSE ${http_port}

'# will be used by attached slave agents:
EXPOSE ${agent_port}

以专业角度看:
1、ARG的名称均为小写字母。
2、在函数中按照 ARG 名称进行排序:用户 + 组;UID + GUID;2个端口。
3、ENV名称均需大写。
4、使用两行代码进行组添加和用户添加。
5、useradd 与groupadd完全匹配。

Dockerfile代码片段-对RUN的审查

请提供一个原生中文版本的释义。以下是一个选项:

https://github.com/docker-library/postgres/blob/88341a435106ea0c9a805ff305bf486f81f56e0c/11/Dockerfile 的内容。

PostgreSQL是一种关系型数据库系统。

ENV PATH $PATH:/usr/lib/postgresql/$PG_MAJOR/bin
ENV PGDATA /var/lib/postgresql/data
RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)
VOLUME /var/lib/postgresql/data

长期经营被夹在其他行业之间并且受到了挤压。

改进版

RUN mkdir -p "$PGDATA" \
    && chown -R postgres:postgres "$PGDATA" \
    && chmod 777 "$PGDATA" \
    # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)

请参考上面的链接,他们Dockerfile的其他部分非常出色。另外,他们还有比大多数人更多的评论。

Dockerfile中片段的审查 – 排序的apt-get安装

从 https://hub.docker.com/_/httpd/ 获取

'# install httpd runtime dependencies
'# https://httpd.apache.org/docs/2.4/install.html#requirements
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        libapr1 \
        libaprutil1 \
        libaprutil1-ldap \
        libapr1-dev \
        libaprutil1-dev \
        liblua5.2-0 \
        libnghttp2-14=$NGHTTP2_VERSION \
        libpcre++0 \
        libssl1.0.0=$OPENSSL_VERSION \
        libxml2 \
    && rm -r /var/lib/apt/lists/*

我已经对安装的apt软件包列表进行了排序。

如果没有排序,情况将如下。

RUN apt-get update 
&& apt-get install -y --no-install-recommends \
        libxml2 \
        libaprutil1 \
            libnghttp2-14=$NGHTTP2_VERSION \
        libapr1-dev \
      liblua5.2-0 \
        libaprutil1-dev \
        libpcre++0 \
        libapr1 \
        libssl1.0.0=$OPENSSL_VERSION \
    libaprutil1-ldap \
  && rm -r /var/lib/apt/lists/*

不需要用手进行排序。在编辑器中,只需将列表高亮显示,并点击“排序”功能即可。

在开发过程中,为了方便找到特定的 libapr,对这样的列表进行排序是很有帮助的。现在,我们必须仔细地从上到下阅读数据,以免遗漏任何信息。如果发生过这样的情况,进行一次点击即可进行排序,这将是一次投资时间的行为。

构建Demo的Dockerfile。

我们已经看到了好的Dockerfile和不好的Dockerfile是如何看起来的,现在让我们尝试创建一个令人自豪的Dockerfile。

您的Dockerfile必须至少使用以下步骤一次。

你的Dockerfile并不必须是一个完美的应用程序。只是在尝试这些命令中的语法和功能。

执行命令,添加文件,创建工作目录,添加环境变量和参数。公开一些端口并为所有内容都添加标签,并准备好ENTRYPOINT。这里的目的是熟悉命令。

请复制在 https://hub.docker.com/explore/ 上找到的文本片段。

如果使用的输入软件不同,学习过程就会变得更有趣。

FROM 
COPY
ADD
RUN
LABEL
EXPOSE
ENVIRONMENT
ENTRYPOINT
VOLUME 
USER
WORKDIR
ARG

Dockerfile的概念是什么?

以下的文本目的是测试您对Dockerfile术语的理解程度。

本文是关于Dockerfile概念的内容。

不是用来教新事物的东西。

如果你能够理解以下大部分内容,那就说明你对Dockerfile的术语已经熟悉了。

以下的句子大约有50%来自以下来源。

请用中文准确解释以下链接的内容:https://docs.docker.com/glossary/

这篇文本经过编辑,加入了更多与Docker相关的术语。

请把以下内容以中国母语进行改述,只需要一种选项:

使用Dockerfile文件,Docker build命令用于构建Docker镜像。

Dockerfile是一个文本文件,通常在Linux命令shell中执行,包含构建Docker镜像所需的所有Linux命令。通过读取Dockerfile中的指令,Docker可以构建镜像。

镜像是将执行所需的所有软件分层化放置在独立的容器内。镜像本身并不执行任何操作。

容器是Docker镜像的运行实例。您可以使用docker run命令从镜像创建容器。

Docker容器包含了用于创建的Docker镜像。容器类似于迷你虚拟机。

Docker Hub – https://hub.docker.com – 是一个用于存储Docker镜像的网站。

“Registry” refers to a web service that contains repositories of Docker images. Docker Hub serves as a registry.

注册表指的是包含Docker镜像仓库的Web服务。Docker Hub就是一个注册表。

您可以使用 Docker Hub 的浏览器或者使用 docker 搜索命令来访问默认的注册表 – https://hub.docker.com。

仓库是Docker镜像的集合。通过将仓库推送到注册服务器,可以共享仓库 – 使用docker push命令。在这五个教程集中,没有使用过这个docker push命令。

还有其他1000人使用docker push向Docker Hub中添加了1000个公共镜像,https://hub.docker.com。

Docker镜像是容器的基础。镜像是在容器运行时使用的根文件系统的修改和相应的执行参数的分层集合。

如果您想要在不指定额外参数的情况下运行Dockerfile,您需要同时指定entrypoint、cmd或两者。

命名卷是指Docker所管理的卷。

在创建带有名称的卷时,可以指定友好文本名称。

匿名卷与具名卷类似,但是在使用匿名卷时,随着时间的推移,可能很难引用相同的卷。

Dockerfile最佳实践摘要

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/的最佳实践

以下是几个Dockerfile最佳实践的一句总结。

1、使用小的构建上下文… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#understand-build-context
2、使用dockerignore… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#exclude-with-dockerignore
3、尽量减少层数… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#minimize-the-number-of-layers
4、整理多行参数… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#sort-multi-line-arguments
5、使用Alpine作为基础镜像… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from
6、添加一个标签-用于练习… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#label
7、将长且复杂的RUN命令拆分为多行-请参考上面的示例… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run
8、暴露任意端口-用于练习… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#expose
9、定义环境变量… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#env
10、使用ADD和COPY展示它们的区别… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy
11、定义卷… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#volume
12、添加演示测试用户-示例在本教程顶部… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
13、创建工作目录… https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#workdir

阶段1:对创建的演示Dockerfile进行审查,纠正错误之处。

第二阶段:访问 https://hub.docker.com/explore/

请点击第一个包名称:nginx。在那里找到列出的第一个Dockerfile。再次点击并确认Dockerfile。然后快速浏览并检查它是否采用了最佳实践或者被滥用了。

另外,请你考虑上述提到的详细的代码片段。检查这些Dockerfile,看看能否找到类似类型的问题或最佳实践。

请尽可能地将此应用于尽量多的官方软件包。

请在该网页的左上方的框中输入您最喜欢的 Linux 软件的名称。尝试查看您的软件是否成功地进行了 Docker 化。

轮到你了。

让我们在工作场所中实践一下在这四个教程中学到的知识。

现在,您已经准备好阅读位于https://docs.docker.com/engine/reference/builder/ 上的Dockerfile参考资料了。

你应该对这里提到的几乎所有概念都非常熟悉。根据前三个教程,你已经通过实际实验理解了大多数Dockerfile的解释。

這樣,應該讓你能夠輕鬆閱讀了。

我方剛才所述的所有內容同樣適用於以下的最佳實踐。

请参阅以下网页以获取有关Dockerfile最佳实践的信息:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/

现在,您可以在阿里巴巴云弹性计算服务(ECS)实例上,使用Docker容器构建酷炫的应用程序。

阿里巴巴云拥有两个数据中心在日本,并拥有超过60个可用区域,是亚太地区排名第一的云基础设施提供商(根据2019年加特纳报告)。欲了解更多阿里巴巴云的详细信息,请点击这里。阿里巴巴云日本官方页面。

广告
将在 10 秒后关闭
bannerAds