Dockerfile设置用于生产和开发环境?

6
我想知道人们如何在生产和开发中使用Docker。在开发中,我希望挂载我的源代码/构建文件以便快速轻松地进行更改。对于生产,我希望将源代码/构建文件包含在镜像中。
这通常是如何完成的?有最佳实践或更常见的做法吗?
在我看来,理想情况下,我会有一个Dockerfile,使用类似标志或环境变量的东西来设置生产或开发镜像,但我找不到任何人这样做的例子,也不确定它应该如何完成。
我还看到了一些项目具有独特的用于生产和开发的Dockerfile的粗略示例,但随着时间的推移,如果我们不小心,可能会出现维护单独Dockerfile的问题。
这两种方法都合理吗?还是我可能误解了什么?我对docker比较新。一个使用类似设置的Dockerfile或项目示例将很好。我担心在开始时使用不良实践来dockerizing我们的某些服务。
编辑:我所有当前的应用程序都是基于Python的,如果有任何影响,请告诉我。
2个回答

5
一种好的方法是使用Docker的多阶段构建,因为它们允许您在包含开发依赖关系的镜像中构建您的构件,并仅在最终镜像中使用您的构件和运行时依赖关系。
我通常建议不要为不同的环境使用不同的Dockerfile,这通常可以使用配置参数(环境变量是一个很好的解决方案)来实现。
拥有更快的开发反馈周期在很大程度上取决于所使用的语言。许多人将使用IDE以更经典的方式进行开发,并仅在集成测试等方面构建映像(例如,在我的经验中,这通常是Java开发人员的情况)。其他解释性语言可能确实受益于将源代码挂载到开发环境映像中。在这种情况下,您可以将此映像合并到您的多阶段构建中。

1
这让我有些放心,因为我也倾向于这样做。您能详细说明一下如何使用配置参数吗?我可能有所误解。所以在dockerfile中,您可以使用环境变量触发不同的阶段? - Shatnerz
通常情况下,您会在基于此镜像创建/启动实际容器时使用环境变量进行运行时配置。另请参见https://docs.docker.com/engine/reference/run/#env-environment-variables。要实际利用环境变量来配置应用程序,您需要将其构建到应用程序中。请参见https://12factor.net/config。 - Kevin Wittek
我想我明白你的意思了。我的根本问题在于创建图像。对于开发,我希望将本地文件系统与源代码挂载在一起,而对于开发,我希望将源代码包含在图像中。我的应用程序目前都是基于Python的,所以我不需要构建任何东西。重新阅读您的解决方案,您建议不要使用多个Dockerfile,但也提到了合并开发图像。这不需要多个Dockerfile吗?一个用于开发,一个用于生产,并将开发图像合并到生产中? - Shatnerz
我不明白,理想情况下,一个 Docker 多阶段构建的所有前置阶段都应该通过 Jenkins 完成,然后再使用 Docker 进行最终构建,是吗? - Technoshaft

4
除了Kevin Wittek提供的优秀答案外,事实证明这可能更多是一个非问题。
我可以使用COPY将文件复制到镜像中,但是我也可以简单地在开发过程中在其上面进行挂载。
如果还有其他需要安装的仅限于开发环境的依赖项,我可以使用ARG来指定类似于ARG APP_ENV=prod的环境,并使用--build-arg=dev或反之亦然进行覆盖。

有一个重要的限制:Dockerfile 必须FROM语句开头。因此,如果你需要使用不同的基础镜像构建,就像我目前正在做的那样,你无法使用这种方法,因为你不能在FROM语句之前运行ARG语句。 - Richard Dunn
@RichardDunn 根据复杂程度,您仍然可以使用args并覆盖基础图像所写的内容。这可能不是非常高效,但我不认为它不起作用。 - Shatnerz
真的。我很好奇你是否可以在同一基础镜像上两次使用FROM命令。假设可以,我想它只会使用相同的缓存版本,所以可能并不太低效。 - Richard Dunn
@RichardDunn 你可以在FROM语句之前使用ARG语句。虽然可能相对较新。https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact - Romain Vincent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接