본문 바로가기

소프트웨어 이야기/docker

[Docker]docker에서 bundle 데이터가 캐싱되는 상황

개발 / 테스트 환경을 위한 서버에 도커로 레일즈를 올릴 때, 

수정 사항이 생길 때마다 배포를 하게 된다.

이 때, bundle install이 매번 실행되면 gem들이 설치될 때까지 매번 기다려야 한다.


그래서 레일즈 개발하는 분들이 아래의 페이지처럼 bundle install을 통해 생성된 gem들을 이미지로 묶어버리는 방법을 찾아 정리해두었다.


http://ilikestuffblog.com/2014/01/06/how-to-skip-bundle-install-when-deploying-a-rails-app-to-docker/



이렇게 Dockerfile을 수정해줘야 한다

저기.. Gemfile을 ADD해주고... bundle install을 해주는 부분을 추가해줘야한다.


한번 Dockerfile을 돌렸으면, gem들을 설치해주는 부분이 캐싱된다 

Gemfile의 메타 데이터나, 내용 자체에 변경사항이 생기지 않는 한,

Dockerfile은 이전에 캐싱되었던 gem  정보를 계속 가져와서 활용한다


처음에 docker file을 돌리면, bundle install을 해주는 작업들이 이력으로 남을거다.

그런데 같은 Gemfile 내용으로 docker file을 돌린적이 있으면 아래처럼 로그들이 뜰거고, Using cache가 뜬다.


만약 Gemfile이 변경되면, removing intermediate image .. 이런게 뜨면서 새로 bundle install이 되면서

새로운 중간 이미지가 생성된다. 


Uploading context 337.9 kB
Uploading context
Step 1 : FROM ubuntu:12.10
 ---> b750fe79269d
Step 2 : MAINTAINER brian@morearty.org
 ---> Using cache
 ---> 5895ed9e78a4
Step 3 : RUN apt-get update
 ---> Using cache
 ---> d2898351463e
Step 4 : RUN apt-get install -y curl git build-essential ruby1.9.3 libsqlite3-dev
 ---> Using cache
 ---> aa1dbf3e6452
Step 5 : RUN gem install rubygems-update --no-ri --no-rdoc
 ---> Using cache
 ---> 8f4ef4bcfd32
Step 6 : RUN update_rubygems
 ---> Using cache
 ---> 358ef92178c7
Step 7 : RUN gem install bundler sinatra --no-ri --no-rdoc
 ---> Using cache
 ---> 9e7d9c0fd7de
Step 8 : WORKDIR /tmp
 ---> Using cache
 ---> b10a5c9f12c0
Step 9 : ADD railsapp/Gemfile Gemfile
 ---> Using cache
 ---> 79deb268175e
Step 10 : ADD railsapp/Gemfile.lock Gemfile.lock
 ---> Using cache
 ---> 1315e65cb616
Step 11 : RUN bundle install
 ---> Using cache
 ---> 6f067cbf6c2f
Step 12 : ADD railsapp /opt/railsapp
 ---> 655d668c338d
Step 13 : WORKDIR /opt/railsapp
 ---> Running in 0272330053b5
 ---> 94dda8e65416
Step 14 : CMD rails server thin
 ---> Running in 9afb1cee2bcf
 ---> 1429538cbdfb
Successfully built 1429538cbdfb

real    0m17.974s
user    0m0.000s
sys     0m0.020s




위의 도커스크립트에서 캐싱처리가 되는 원리는,

도커에서는 ADD와 COPY에 대한 명령문들을 그대로 캐싱한다고 한다.


위의 내용은 docker docs를 참고했다 

https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#build-cache


add와 copy는 checksum을 사용해서 파일의 정확성을 검사한다

파일의 수정일자, 마지막 접근 일자 등은 checksum에 영향을 주는 요소는 아니다.

내용이나 메타데이터가 변경되었는지를 비교해서, 기존에 만들어진 이미지와 이번에 돌아가게될 명령문에서 실행해야하는 요소들이 같은지, 다른지를 판단한다.


위의 개념은 docker의 build-cache라는 개념이다.

만약 add / copy 등에서 cache가 되는 기능을 사용하지 않으려면, docker-build --no-cache=true 처럼 no-cache 옵션을 추가해주어야한다.


Docker에 남은 캐시를 지우는 방법


https://forums.docker.com/t/how-to-delete-cache/5753

https://docs.docker.com/engine/reference/commandline/images/#filtering



새로 빌드가 될 때, 태깅이 되지 않거나, <none>:<none>으로 남는 케이스들이 있다. 

얘네들을 지우는게 문제가 되지는 않는건지는 확인해볼 필요가 있다.