dwj*_*man 5 git caching docker
当我克隆一个存储库两次时,例如:
git clone <repo_X> --depth 1 clone1
git clone <repo_X> --depth 1 clone2
Run Code Online (Sandbox Code Playgroud)
然后做一个差异
diff -r clone1 clone2
Run Code Online (Sandbox Code Playgroud)
这显示了差异:
Binary files clone1/.git/index and clone2/.git/index differ
...
diff -r clone1/.git/logs/HEAD clone2/.git/logs/HEAD
...
diff -r clone1/.git/logs/refs/remotes/origin/HEAD
...
Run Code Online (Sandbox Code Playgroud)
似乎克隆的时间被记录在一个文件中。
我想向 Docker 映像添加一些存储库。当文件未更改时,Docker 使用其缓存。不幸的是,在克隆 Docker 之后,由于文件更改,总是使缓存无效。
是否有可能以某种方式使 repo 的两个克隆产生完全相同的文件?(注意:我不想删除 .git 目录,因为我希望能够在图像中使用 git 来检查 repo 的版本。)
是否可以让 Docker 在缓存时忽略 .git 文件夹(注意 .git 文件夹仍然必须添加到图像中,所以 .dockerignore 不是一个选项?)
您可以使用新的 Docker 的 BuildKit 功能--mount=cache。Dockerfile 的玩具示例:
FROM ubuntu
RUN --mount=type=cache,target=/var/cache/apt \
apt update && apt upgrade -y && apt install -yq git
RUN echo A00
RUN --mount=type=cache,target=/tmp/git_cache/ \
git clone --depth=1 https://github.com/qtox/qtox/ /tmp/git_cache/qtox/; \
cd /tmp/git_cache/qtox/ && git pull && cp -r ./ /tmp/my_qtox/
RUN echo B00
Run Code Online (Sandbox Code Playgroud)
上面的dockerfile可以通过命令构建:
sudo env DOCKER_BUILDKIT=1 docker build -f Dockerfile .
注意DOCKER_BUILDKIT=1环境变量的存在,有必要在 docker build 中启用所有 BuildKit 的功能。您可以在此处了解 BuildKit 的功能。
例如,我克隆了上面的qTox存储库,因为它非常巨大。
--mount=cache功能会自动创建用于缓存的临时目录并将其安装到/tmp/git_cache/容器内的(目标)中。如果某些先前的层发生更改,例如echo A00更改为echo A01,则此克隆将立即完成,不会延迟,因为它只是从缓存中获取。
此外,正如您所请求的,使用此缓存将使克隆存储库完全相同。只有当新的提交出现在存储库中时,才git pull完成并且存储库发生更改。除非有新的提交,否则此缓存存储库将保持不变。因此,每次再次运行 docker build 时,您都会有相同的 git 存储库。
只有极少数情况下,如果长时间不使用缓存目录或者磁盘可用空间不足,Docker 会自动删除缓存目录。
正如您从上面的 docker-file 中看到的那样,最终的 git 存储库将出现在/tmp/my_qtox/容器的文件夹内。您可以将此路径更改为您的案例所需的任何路径。
另外您可能已经注意到,我在安装 APT 软件包时使用了相同的缓存机制。这非常方便,因为重建映像时,所有包都不会从远程 Ubuntu 服务器重新下载,而是从缓存目录中获取。当 apt install 之前的 docker 层发生更改或者将新的 apt 软件包添加到安装列表时,这很有用,在这两种情况下 apt install 都会非常快地重新运行。
| 归档时间: |
|
| 查看次数: |
179 次 |
| 最近记录: |