我正在尝试在docker容器中运行一个小型Rails应用程序。我越来越近,但是我正在努力使用我的Dockerfile。
我已将以下命令添加到我的Dockerfile中,以递归方式添加项目文件夹中的所有文件。
ADD .
在此之后,我运行
RUN bundle install --deployment
但是,因为我的ADD
命令还添加了Dockerfile,这意味着每次编辑Dockerfile时我的图像缓存都会中断,迫使我重新绑定。
根据https://docs.docker.com/reference/builder/#the-dockerignore-file,我可以使用.dockerignore
文件来忽略Dockerfile,但这会导致docker build
命令失败
2014/09/17 22:12:46 Dockerfile was excluded by .dockerignore pattern 'Dockerfile'
如何轻松地将我的项目添加到我的图像中,但排除了Dockerfile,所以我不打破docker镜像缓存?
答案 0 :(得分:4)
您对@Kuhess答案的评论澄清,说实际问题是“docker图像缓存失效导致bundle install再次运行”,这有助于为您提供答案。
我一直在使用我的rails 4.1。* app的Dockerfile,如下所示。通过首先添加Gemfile *,然后运行bundle install,然后仅添加应用程序的其余部分,将缓存bundle安装步骤,除非其中一个Gemfile *文件发生更改。
FROM ruby:2.1.3
RUN adduser --disabled-password --home=/rails --gecos "" rails
RUN gem install bundler --no-ri --no-rdoc
RUN gem install -f rake --no-ri --no-rdoc
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp
RUN chown -R rails:rails /myapp
USER rails
EXPOSE 3000
ENV RAILS_ENV production
CMD bundle exec rails server -p 3000
我的Dockerfile位于应用程序的根目录中,但是对它的更改(或应用程序的任何其他部分)不会导致bundle install的映像缓存中断,因为它们是在RUN之后添加的。唯一打破它的是对Gemfile *的更改,这是正确的。
仅供参考,我的.dockerignore文件如下所示:
.git
log
vendor/bundle
答案 1 :(得分:1)
Github上有一个问题:https://github.com/docker/docker/issues/7969
由于ADD
和Dockerfile
的修改,您的主要问题是驱逐缓存。其中一位维护者解释说,目前.dockerignore
文件并非旨在处理它:
它 - .dockerignore - 当您将上下文从客户端上传到守护进程时跳过一些文件,并且守护进程需要Dockerfile来构建映像。所以.dockerignore的主要想法(现在)正在跳过大型目录以加快上传速度,而不是干净的上下文。 full comment on Github
我担心在ADD Dockerfile
these lines未修改{{3}}时,图片缓存会中断。
也许处理缓存的一种方法是将要添加的所有文件放在与Dockerfile
不同的目录中:
.
├── Dockerfile
└── files_to_add/
然后,如果您ADD files_to_add
,则不会包含Dockerfile
,并且不会驱逐缓存。
但是,我不认为这个技巧是一个解决方案。我还希望将Dockerfile
放在项目根目录下的其他文件旁边。