Docker 开发最佳实践

事实证明,以下开发模式对于使用 Docker 构建应用程序的人们很有帮助。

如果您发现了我们应该添加的内容, 请告诉我们

如何保持图像较小

小镜像在启动容器或服务时可以更快地通过网络拉取并加载到内存中。有一些经验法则可以保持图像尺寸较小:

  • 从适当的基础镜像开始。例如,如果您需要 JDK,请考虑将您的映像基于包含 OpenJDK 的 Docker 官方映像,例如eclipse-temurin,而不是从头开始构建您自己的映像。

  • 使用多阶段构建。例如,您可以使用该maven映像来构建 Java 应用程序,然后重置为该tomcat映像并将 Java 工件复制到正确的位置以部署您的应用程序,所有这些都在同一个 Dockerfile 中。这意味着您的最终映像不包含构建引入的所有库和依赖项,而仅包含运行它们所需的工件和环境。

    • RUN如果您需要使用不包含多阶段构建的 Docker 版本,请尝试通过最小化Dockerfile 中单独命令的数量来减少映像中的层数。您可以通过将多个命令合并到一行中RUN并使用 shell 的机制将它们组合在一起来完成此操作。考虑以下两个片段。第一个在图像中创建两个图层,而第二个仅创建一个图层。

      RUN apt-get -y update
      RUN apt-get install -y python
      RUN apt-get -y update && apt-get install -y python
  • 如果您有多个具有很多共同点的映像,请考虑 使用共享组件创建您自己的基础映像,并在此基础上创建您的独特映像。 Docker 只需要加载公共层一次,并且它们会被缓存。这意味着您的衍生映像可以更有效地使用 Docker 主机上的内存并更快地加载。

  • 为了保持生产映像精简但允许调试,请考虑使用生产映像作为调试映像的基础映像。可以在生产映像之上添加其他测试或调试工具。

  • 构建映像时,请始终使用有用的标签来标记它们,这些标签可编码版本信息、预期目标(例如prodtest)、稳定性或在不同环境中部署应用程序时有用的其他信息。不要依赖自动创建的latest标签。

在何处以及如何保存应用程序数据

  • 避免使用存储驱动程序将应用程序数据存储在容器的可写层中 。这会增加容器的大小,并且从 I/O 角度来看,与使用卷或绑定挂载相比效率较低。
  • 相反,使用卷存储数据 。
  • 适合使用 绑定挂载的一种情况是在开发过程中,当您可能想要挂载源目录或刚刚构建到容器中的二进制文件时。对于生产,请使用卷,将其安装到与开发期间安装绑定安装相同的位置。
  • 对于生产,使用 机密来存储服务使用的敏感应用程序数据,并使用 配置 来存储非敏感数据(例如配置文件)。如果您当前使用独立容器,请考虑迁移到使用单副本服务,以便您可以利用这些仅服务功能。

使用 CI/CD 进行测试和部署

  • 当您签入对源代码管理的更改或创建拉取请求时,请使用 Docker Hub或其他 CI/CD 管道自动构建和标记 Docker 映像并对其进行测试。

  • 更进一步,要求您的开发、测试和安全团队 在将映像部署到生产环境之前对映像进行签名。这样,在将映像部署到生产中之前,它已经由开发、质量和安全团队等团队进行了测试和签署。

开发和生产环境的差异

发展生产
使用绑定挂载让容器能够访问源代码。使用卷来存储容器数据。
使用适用于 Mac、Linux 或 Windows 的 Docker Desktop。使用 Docker 引擎,如果可能的话,与 用户映射一起使用,以更好地隔离 Docker 进程与主机进程。