Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding project folder except for Dockerfile

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?

like image 652
Niels B. Avatar asked Sep 17 '14 20:09

Niels B.


People also ask

How can you tell a Dockerfile to include specific files and directories in a build?

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 .

Should I put Dockerfile in Dockerignore?

The documentation says that yes it can. You can even use the . dockerignore file to exclude the Dockerfile and . dockerignore files.


2 Answers

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
like image 171
Killian Avatar answered Oct 20 '22 08:10

Killian


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.

like image 36
Kuhess Avatar answered Oct 20 '22 08:10

Kuhess