1 回答
这两种方法同样有效。如果您查看其他 SO 问题,您可能会注意到一件事是 Java/Docker 映像几乎普遍在其主机上构建一个 jar 文件,然后COPY
将其转换为映像,但 Go/Docker 映像倾向于使用多阶段 Dockerfile从源头开始。
.gitlab.yml
如果您已经拥有相当成熟的构建系统并且您的开发人员已经拥有非常一致的设置,那么在 CI 环境中(在您的文件中)做更多的工作是有意义的。以与您相同的方式构建您的应用程序,然后COPY
将其构建为最小的 Docker 映像。如果您需要同时发布 Docker 和非 Docker 工件,这种方法也很有帮助。如果你有一个make dist
风格的 tar 文件并想从中获取一个 Docker 映像,你可以使用一个非常简单的 Dockerfile,比如
FROM ubuntu
RUN apt-get update && apt-get install ...
ADD dist/myapp.tar.gz /usr/local # unpacking it
EXPOSE 12345
CMD ["myapp"] # /usr/local/bin/myapp
另一方面,如果您的开发人员有多种桌面环境,并且您确实在尝试标准化事物,并且您只需要发布 Docker 映像,那么将大部分内容集中在 Dockerfile 中可能是有意义的。这样做的好处是每个开发人员都可以自己在本地运行确切的构建序列,而不是依赖 CI 系统来尝试简单的更改。围绕 GNU Autoconf 构建的东西可能看起来更像
FROM ubuntu AS build
RUN apt-get update \
&& apt-get install --no-install-recommends --assume-yes \
build-essential \
lib...-dev
WORKDIR /app
COPY . .
RUN ./configure --prefix=/usr/local \
&& make \
&& make install
FROM ubuntu
RUN apt-get update \
&& apt-get install --no-install-recommends --assume-yes \
lib...
COPY --from=build /usr/local /usr/local
CMD ["myapp"]
如果您在 Dockerfile 中进行主要构建,则需要COPY
将源代码放入其中。卷安装在序列中的这一点上不起作用。CI 系统在任何情况下都应该避免将源代码绑定到容器中:您希望针对您构建的实际工件运行测试,而不是构建的 Docker 映像的混合体,而是替换其所有源代码。