Skip to content

使用 Docker 进行开发的最佳实践

原文:https://docs.docker.com/develop/dev-best-practices/

下面的开发模式已被证明对使用 Docker 构建应用的人们非常有帮助。

如何保持你的镜像尺寸小

小尺寸的镜像拉取和加载到内存中的速度更快,无论是启动容器还是服务。以下是一些保持镜像尺寸小的经验法则:

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

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

  • 如果你需要使用不包括多阶段构建的 Docker 版本,尝试通过减少 Dockerfile 中单独 RUN 命令的数量来减少镜像中的层数。你可以通过将多个命令合并到一个 RUN 行并使用你的 shell 的机制将它们组合在一起来实现这一点。考虑以下两个片段。第一个在镜像中创建了两层,而第二个只创建了一层。

dockerfile
RUN apt-get -y update
RUN apt-get install -y python
dockerfile
RUN apt-get -y update && apt-get install -y python
  • 如果你有多个镜像有很多共同点,考虑创建你自己的基础镜像并在此基础上构建你的特定镜像。Docker 只需要一次加载公共层,并且它们被缓存。这意味着你的派生镜像在 Docker 主机上更有效地使用内存并加载得更快。

  • 为了保持你的生产镜像精简同时允许调试,考虑使用生产镜像作为调试镜像的基础镜像。可以在生产镜像的基础上添加额外的测试或调试工具。

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

如何以及在哪里持久化应用数据

  • 避免在容器的可写层中使用存储驱动存储应用数据。这会增加你的容器大小,并且从 I/O 角度来看,使用卷或绑定挂载比较低效。

  • 相反,使用存储数据。

  • 在开发期间可能要使用绑定挂载的一个情况是,当你可能需要将你的源代码目录或刚刚构建的二进制文件挂载到你的容器中。对于生产环境,使用卷替代,将其挂载到开发期间使用绑定挂载的相同位置。

  • 对于生产环境,使用秘密来存储服务使用的敏感应用数据,并使用配置来存储非敏感数据,如配置文件。如果你目前使用独立容器,考虑迁移到使用单副本服务,以便你可以利用这些仅限服务的功能。

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

  • 当你向源代码控制提交更改或创建拉取请求时,使用 Docker Hub 或其他 CI/CD 管道自动构建和标记 Docker 镜像并测试它。

  • 通过要求你的开发、测试和安全团队在将镜像部署到生产环境之前签署镜像来进一步做到这一点。这样,在镜像被部署到生产环境之前,它已经经过了开发、质量和安全团队的测试和签字。

开发环境和生产环境的差异

开发生产
使用绑定挂载让你的容器访问你的源代码。使用卷来存储容器数据。
使用 Docker Desktop for Mac、Linux 或 Windows。使用 Docker Engine,如果可能的话,使用 userns mapping 来增加 Docker 进程与主机进程的隔离。