I am trying to run a small Rails app in a docker container. I am getting close, however I am struggling with my Dockerfile.
I have added the following command to my Dockerfile to recursively add all files in my project folder.
ADD .
After this, I run
RUN bundle install --deployment
However, because my ADD
command also adds the Dockerfile, it means that my image cache breaks every time I edit my Dockerfile forcing me to rebundle.
According to https://docs.docker.com/reference/builder/#the-dockerignore-file, I can use a .dockerignore
file to ignore Dockerfile, but this causes the docker build
command to fail with
2014/09/17 22:12:46 Dockerfile was excluded by .dockerignore pattern 'Dockerfile'
How can I easily add my project to my image, but exclude the Dockerfile, so I don't break the docker image cache?
The best way to work around this is to specify the Dockerfile independently of the build context, using -f. For instance, this command will give the ADD command access to anything in your current directory. docker build -f docker-files/Dockerfile . docker build -f ../Dockerfile .
The documentation says that yes it can. You can even use the . dockerignore file to exclude the Dockerfile and . dockerignore files.
Your clarification in a comment to the answer from @Kuhess, saying that the actual problem is "the invalidation of the docker image cache causing bundle install to run again", is helpful in providing you an answer.
I've been using a Dockerfile that looks like the following for my rails 4.1.* app. By ADDing Gemfile* first, then running bundle install, and only then ADDing the rest of the app, the bundle install step is cached unless one of the Gemfile* files changes.
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
My Dockerfile is in the root dir of the app, but changes to it (or any other part of the app) do not cause the image cache for bundle install to break because they are added after it is RUN. The only thing that breaks it are changes to Gemfile*, which is correct.
FYI, my .dockerignore file looks as follows:
.git
log
vendor/bundle
There is an issue for that on Github: https://github.com/docker/docker/issues/7969
Your main problem is the eviction of the cache because of the ADD
and the modification of the Dockerfile
. One of the maintainer explains that, for the moment, the .dockerignore
file is not designed to deal with it:
It — .dockerignore — skips some files when you upload your context from client to daemon and daemon needs Dockerfile for building image. So main idea(for now) of .dockerignore is skipping big dirs for faster context upload, not clean context. full comment on Github
I am afraid that the image cache will break when you ADD Dockerfile
while these lines are not modified.
Maybe one way to deal with the cache is to place all the files you want to add in a different directory than the Dockerfile
:
.
├── Dockerfile
└── files_to_add/
Then if you ADD files_to_add
, the Dockerfile
will not be included and the cache will not be evicted.
But, I do not consider that this trick is a solution. I also want to have my Dockerfile
next to other files at the root of my projects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With