git - 当 git checkout 相同的文件时,docker 添加缓存

标签 git docker

我需要在我的 CI 服务器构建镜像中重用 docker 缓存的 checkout 项目。

Docker ADD 在 check out 同一个文件时不使用缓存。

我在 git branch A 执行 docker build -t somename . 它正常使用 docker 缓存,但是如果我去分支 B通过 git checkout B,什么都不做,通过 git checkout A 转到分支 A 并再次运行 docker build -t somename 。 docker 缓存仅在第一个 ADD 之前使用。

这里的例子:

Dockerfile

# DOCKER-VERSION 0.10.0
FROM myregistry:5000/ruby:2.1.2-1
MAINTAINER ME

# Gem sources
RUN gem source -r https://rubygems.org/
RUN gem source -a http://gems.mydomain

# Never install a ruby gem docs
RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc

# gems install
RUN mkdir /foo
WORKDIR /foo

RUN gem install bundler
ADD Gemfile /foo/Gemfile
RUN bundle install

# expose ports
EXPOSE 8080

构建日志

Sending build context to Docker daemon 19.54 MB
Sending build context to Docker daemon 
Step 0 : FROM myregistry:5000/ruby:2.1.2-1
 ---> 9ce683a713b4
Step 1 : MAINTAINER ME
 ---> Using cache
 ---> 8f54114fd2e7
Step 2 : RUN gem source -r https://rubygems.org/
 ---> Using cache
 ---> f58a08708863
Step 3 : RUN gem source -a http://gems.mydomain
 ---> Using cache
 ---> 3e69e17c5954
Step 4 : RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc
 ---> Using cache
 ---> 1edb37962dd4
Step 5 : RUN mkdir /foo
 ---> Running in 3d3441c34ee3
 ---> aeb90f00bc9b
Removing intermediate container 3d3441c34ee3
Step 6 : WORKDIR /foo
 ---> Running in 84b881d8f621
 ---> 10e1d8984458
Removing intermediate container 84b881d8f621
Step 7 : RUN gem install bundler
 ---> Running in 31e98523ce46
Successfully installed bundler-1.6.2
1 gem installed
 ---> 84d5195ab831
Removing intermediate container 31e98523ce46
Step 8 : ADD Gemfile /foo/Gemfile
 ---> 3e5f2675ee22
Removing intermediate container c90e8be5ea17
Step 9 : RUN bundle install
 ---> Running in ac0e83e5eebb    
Fetching gem metadata from http://gems.mydomain/......
Fetching additional metadata from http://gems.mydomain/..
Resolving dependencies...
Installing rake 10.3.2
Installing i18n 0.6.9
Installing multi_json 1.10.1
.
.
.
Installing railties 3.2.19
Installing responders 0.9.3
Using bundler 1.6.2
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.    
 ---> 19beae703adb
Removing intermediate container ac0e83e5eebb
Step 10 : EXPOSE 8080
 ---> Running in 1b1e55d349e5
 ---> 32405bdac6d1
Removing intermediate container 1b1e55d349e5
Successfully built 32405bdac6d1

git checkout B

git checkout A

docker build -t somename.

第二次构建日志

Sending build context to Docker daemon 19.52 MB
Sending build context to Docker daemon 
Step 0 : FROM myregistry:5000/ruby:2.1.2-1
 ---> 9ce683a713b4
Step 1 : MAINTAINER ME
 ---> Using cache
 ---> 8f54114fd2e7
Step 2 : RUN gem source -r https://rubygems.org/
 ---> Using cache
 ---> f58a08708863
Step 3 : RUN gem source -a http://gems.mydomain
 ---> Using cache
 ---> 3e69e17c5954
Step 4 : RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc
 ---> Using cache
 ---> 1edb37962dd4
Step 5 : RUN mkdir /foo
 ---> Using cache
 ---> aeb90f00bc9b
Step 6 : WORKDIR /foo
 ---> Using cache
 ---> 10e1d8984458
Step 7 : RUN gem install bundler
 ---> Using cache
 ---> 84d5195ab831
Step 8 : ADD Gemfile /foo/Gemfile
 ---> 4977e35c80f7
Removing intermediate container bd59cc0d5e51
Step 9 : RUN bundle install
 ---> Running in 6ff16f32e94a
Fetching gem metadata from http://gems.mydomain/......
Fetching additional metadata from http://gems.mydomain/..
Resolving dependencies...
Installing rake 10.3.2
Installing i18n 0.6.9
Installing multi_json 1.10.1
.
.
.    
Installing railties 3.2.19
Installing responders 0.9.3
Using bundler 1.6.2
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
 ---> d9332f9035c3
Removing intermediate container 6ff16f32e94a
Step 10 : EXPOSE 8080
 ---> Running in b20252a00160
 ---> 4d9932882e06
Removing intermediate container b20252a00160
Successfully built 4d9932882e06

最佳答案

当文件的 mtime 值发生更改时,Docker 会使 docker build 缓存失效,并且 git 不会跟踪文件 mtime 值。这种缓存失效也出现在其他情况下,例如在持续集成或涉及 docker、git 和分支的构建环境中。

在要求 docker 构建容器之前,我在运行的 Makefile 中使用了“触摸”目标:

touch:
    @echo "Reset timestamps on git working directory files..."
    find ./ | grep -v .git | xargs touch -t 200001010000.00

接下来,始终在 docker build 或同一 Makefile 中任何基于 docker 的“构建”目标之前运行 make touch...

另一种选择是设置一个自动修改 mtime 值的 git 钩子(Hook): https://git.wiki.kernel.org/index.php/ExampleScripts#Setting_the_timestamps_of_the_files_to_the_commit_timestamp_of_the_commit_which_last_touched_them

另一种可能的解决方案是 fork docker 并从其缓存定义中删除 mtime: https://github.com/docker/docker/blob/master/pkg/tarsum/tarsum.go

Note: as of docker 1.8, mtime is no longer taken into account when invalidating the cache. Pull request #12031 updated this behavior

关于git - 当 git checkout 相同的文件时,docker 添加缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26531108/

相关文章:

node.js - 如何将 docker 环境变量传递给 npm 脚本?

windows - Git:请告诉我你是谁

php - 版本控制 Mysql 数据(不仅仅是模式)

带有神器的 Git

linux - 如何在不停止流媒体服务器的情况下热重载 NATS 流媒体服务器?

docker - 在 boot2docker 中的 docker 中运行 kafka 时使用 JMX 监控 kafka

docker - Docker是否会减少或减轻对Puppet/Chef等人的需求?

reactjs - 在 docker : react app in docker fails to run 中运行一个 react 应用程序

git - 如何使用 git 在服务器上分离生产/开发环境?

git - 如何在 Gitlab 中成功的管道结束时创建 merge 请求?