Docker多阶段构建 - 排除.git文件夹

3
我想进行一个docker多阶段构建,但是要删除/忽略.git文件夹,以节省docker镜像的空间。
FROM ubuntu as first
WORKDIR /app
RUN git clone <repo>

FROM golang as second
WORKDIR app
COPY --from=first /app .

是否有一些--exclude选项可用于COPY命令?这里有一个相关的问题:https://forums.docker.com/t/dockerignore-in-multi-stage-builds/57169

另外一个可能的解决方法是手动删除.git文件夹:

FROM ubuntu as first
WORKDIR /app
RUN git clone <repo>
RUN rm -rf .git

我理解多阶段构建会从其他阶段复制“最终层”,是这样吗?

2
在运行docker build之前,你可能会发现在主机上运行git clone更容易:你不需要禁用Docker层缓存来获取更新的代码库,你可以轻松构建非当前提交或分支,并且你不需要尝试将凭据传递到Docker空间以克隆私有代码库。这样就避免了这个问题,因为你可以在.dockerignore中包含.git - undefined
2个回答

2

从构建中排除文件的一种方法是使用.dockerignore文件。然而,由于在镜像准备期间正在运行git clone命令,因此您实际上需要的是.git文件夹,而不是.dockeringore文件。

如果您想使用多阶段构建,则需要复制先前构建的构件,而不是层次结构到下一个构建中。

另一个想法是运行浅克隆 - git clone --depth=1 - 这应该可以显著减少存储库的大小。


我觉得在第一阶段的最后使用rm -rf也可以吗?想知道这是否正确。 - user12211419
取决于您构建最终的Dockerfile的位置。一般来说,如果您执行RUN git clone然后执行RUN rm -rf .git - 第一个RUN命令将创建一个单独的层,所以为了节省空间,您可以将它放在一个命令中RUN git clone && rm -rf .git。这有点违背了初衷 ;) 在此处阅读更多信息:链接 - undefined
根据我的理解,.dockerignore 文件仅影响本地目录的内容,并不会对 COPY --from 产生影响。 - undefined

0

我意识到我在原帖中尝试的这种技术行不通。大多数人需要.git文件夹来检出正确的提交。克隆整个仓库的目的是为了缓存,以便我们下次构建时可以检出所需的提交。

所以,与其按照我在原帖中尝试的方式去做,我过去使用的一种技术可以实现良好的缓存和生成小图片,大致如下:

WORKDIR /app
ADD  's3://url/to/just/package.json' /app/package.json
RUN npm install --production

ARG commit_id
RUN aws s3 cp -c . 's3://url/to/whole/tarball'

所以,如果package.json没有改变,你可以缓存依赖项,当你进行构建时,将一个精简的tarball推送到s3,并设置一个TTL,然后构建系统可以从镜像中拉取tarball。这个tarball没有git文件夹,并且可以根据需要排除一些其他通常由版本控制跟踪的文件。

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