如何防止 Dockerfile 缓存 git clone

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36996046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 11:59:26  来源:igfitidea点击:

How to prevent Dockerfile caching git clone

gitdockerdockerfile

提问by Raindy

I have a Dockerfile trying to package and deploy a web app to a container. The code of app fetches from git repository during Docker image building. Here's the Dockerfile snapshot:

我有一个 Dockerfile 试图将 Web 应用程序打包并部署到容器中。应用程序的代码在 Docker 镜像构建期间从 git 存储库中获取。这是 Dockerfile 快照:

........
RUN git clone --depth=1 git-repository-url $GIT_HOME/
RUN mvn package -Dmaven.test.skip
........

I want the docker do not cache the step of RUN git clone --depth=1 git-repository-url $GIT_HOME/so that the on-going updated on the the repository can be reflected on the Docker image building. Is it possible to a achieve that?

我希望 docker 不缓存步骤,RUN git clone --depth=1 git-repository-url $GIT_HOME/以便存储库上正在进行的更新可以反映在 Docker 镜像构建上。有可能实现吗?

回答by anq

Another workaround:

另一种解决方法:

If you use GitHub (or gitlab or bitbucket too most likely) you can ADD the GitHub API's representation of your repo to a dummy location.

如果您使用 GitHub(或 gitlab 或 bitbucket 也很可能),您可以将 GitHub API 的存储库表示添加到虚拟位置。

ADD https://api.github.com/repos/$USER/$REPO/git/refs/heads/$BRANCH version.json
RUN git clone -b $BRANCH https://github.com/$USER/$REPO.git $GIT_HOME/

The API call will return different results when the head changes, invalidating the docker's cache.

API 调用会在 head 发生变化时返回不同的结果,从而使 docker 的缓存失效。

If you're dealing with private repos you can use github's x-oauth-basicauthentication schemewith a personal access tokenlike so:

如果您正在处理私有存储库,您可以将github 的x-oauth-basic身份验证方案个人访问令牌一起使用,如下所示:

ADD https://$ACCESS_TOKEN:[email protected]/repos/$USER/$REPO/git/refs/heads/$BRANCH version.json

(thx @captnolimar for a suggested edit to clarify authentication)

(感谢@captnolimar 的建议编辑以澄清身份验证)

回答by VonC

Issue 1996is not yet available, but you have the following workaround:

问题 1996尚不可用,但您有以下解决方法

FROM foo
ARG CACHE_DATE=2016-01-01
RUN git clone ...

docker build --build-arg CACHE_DATE=$(date) ....

That would invalidate cache after the ARG CACHE_DATEline for every build.

这将使ARG CACHE_DATE每次构建的行之后的缓存无效。

Or:

或者:

ADD http://www.convert-unix-time.com/api?timestamp=now /tmp/bustcache
RUN git pull

That would also invalidate cache after this ADD line.

在此 ADD 行之后,这也会使缓存无效。

Similar idea:

类似的想法

Add ARGcommand to your Dockerfile:

# Dockerfile
# add this and below command will run without cache
ARG CACHEBUST=1

When you need to rebuild with selected cache, run it with --build-argoption

$ docker build -t your-image --build-arg CACHEBUST=$(date +%s) .

then only layer below ARGcommand in Dockerfile will rebuild.

ARG命令添加到您的 Dockerfile:

# Dockerfile
# add this and below command will run without cache
ARG CACHEBUST=1

当您需要使用选定的缓存重建时,请使用--build-arg选项运行它

$ docker build -t your-image --build-arg CACHEBUST=$(date +%s) .

那么只有ARGDockerfile中的命令下面的层才会重建。

回答by tomgsmith99

I ran into this same issue myself, and I just decided to use the --no-cacheoption when I build the image, rather than trying to single out the git repo.

我自己也遇到了同样的问题,我只是决定--no-cache在构建映像时使用该选项,而不是尝试挑出 git repo。

docker build --no-cache -t my_image .

回答by Michal Z m u d a

If you use github you can use github API to not cache specific RUN command. You need to have jq installed to parse JSON: apt-get install -y jq

如果您使用 github,您可以使用 github API 来不缓存特定的 RUN 命令。您需要安装 jq 来解析 JSON: apt-get install -y jq

Example:

例子:

docker build --build-arg SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | jq -r '.[0].sha') -t imageName .

In Dockerfile (ARG command should be right before RUN):

在 Dockerfile 中(ARG 命令应该在 RUN 之前):

ARG SHA=LATEST
RUN SHA=${SHA} \
    git clone https://github.com/Tencent/mars.git

or if you don't want to install jq

或者如果你不想安装 jq

SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | grep sha | head -1)

If repository has new commits, git clone will be executed.

如果存储库有新的提交, git clone 将被执行。

回答by Wazime

for anyone who has this problem with Gitlab repositories:

对于任何在 Gitlab 存储库中遇到此问题的人:

Gitlab has this annoying branch id method when calling their API, the ID will appear under your repository name enter image description here

Gitlab 在调用 API 时有这个烦人的分支 id 方法,该 ID 将出现在您的存储库名称下 在此处输入图片说明

# this will copy the last change from your brach and it'll invalidate the cache if there was a new change
ADD "https://gitlab.com/api/v4/projects/${PROJECT_ID}/repository/branches/master?private_token=${GIT_TOKEN}" /tmp/devalidateCache

# the actual clone
RUN git clone --depth=1 https://${GIT_USER}:${GIT_TOKEN}@gitlab.com/${git_file_uri} ${BASE_BUILD_PATH}

回答by manymoons

For github private repos, you could also pass in your username and password:

对于 github 私有仓库,您还可以传入您的用户名和密码:

RUN git clone -b$BRANCH https://$USER:[email protected]/$USER/$REPO.git $GIT_HOME/

RUN git clone -b$BRANCH https://$USER:[email protected]/$USER/$REPO.git $GIT_HOME/