2015-06-25 14 views
5

Tôi sử dụng đế chế trong cả phát triển và sản xuất và một điều thực sự gây lỗi cho tôi là tính đơn giản của bộ đệm docker. Tôi có ứng dụng ruby ​​yêu cầu bundle install để cài đặt các phụ thuộc vì vậy tôi bắt đầu với Dockerfile sau đây: ADD Gemfile Gemfile ADD Gemfile.lock Gemfile.lock RUN bundle install --path /root/bundle Tất cả các phụ thuộc đều được lưu trong bộ nhớ cache và nó hoạt động tốt cho đến khi tôi thêm đá quý mới. Ngay cả khi đá quý tôi đã thêm chỉ là 0,5 MB nó vẫn mất 10-15 phút để cài đặt tất cả các đá quý ứng dụng từ đầu. Và sau đó thêm 10 phút để triển khai nó do kích thước của thư mục phụ thuộc (khoảng 300MB).Vấn đề bộ đệm cài đặt bộ đệm khi cập nhật đá quý

Tôi đã gặp chính xác cùng một vấn đề với node_modules và npm. Tôi đã tự hỏi, có ai tìm ra giải pháp cho vấn đề này không?

kết quả nghiên cứu của tôi cho đến nay:

  • Source to image - lưu trữ tập tin tùy ý trên gia tăng xây dựng. Thật không may, do cách nó hoạt động nó đòi hỏi phải đẩy toàn bộ 300MB để đăng ký ngay cả khi đá quý không thay đổi. Xây dựng nhanh hơn -> triển khai chậm hơn ngay cả khi đá quý không được cập nhật.

  • Gemfile.tip - chia Gemfile thành hai tệp khác nhau và chỉ thêm đá quý vào một trong số chúng. Giải pháp rất cụ thể cho bundler và tôi không tin rằng nó sẽ mở rộng thêm 1-2 đá quý.

  • Harpoon - sẽ phù hợp nếu không thực tế là chúng buộc phải bỏ neo Dockerfile và chuyển sang định dạng riêng của chúng. Có nghĩa là thêm đau cho tất cả các nhà phát triển mới trong một nhóm như bộ công cụ này đòi hỏi thời gian để tìm hiểu một cách riêng biệt từ docker.

  • Bộ nhớ tạm thời gói. Đó chỉ là một ý tưởng mà tôi không chắc là có thể. Bằng cách nào đó mang bộ nhớ cache của trình quản lý gói (không phải thư mục phụ thuộc) vào máy trước khi cài đặt các gói và sau đó gỡ bỏ nó. Dựa trên hack của tôi nó tăng tốc đáng kể cài đặt gói cho cả bundler và npm mà không làm đầy máy với các tập tin bộ nhớ cache không cần thiết.

+0

Bạn có thể sao chép thư mục đá quý ra khỏi hình ảnh được tạo thành tệp tar. Sau đó, bạn có thể thêm một lớp ngay trước ADD Gemfile Gemfile của bạn để khôi phục thư mục gem đó trở lại hình ảnh. Tại thời điểm đó, chỉ cần thay đổi lại các thay đổi. Tôi đang thử nghiệm kỹ thuật đó ngay bây giờ. Nếu tôi làm cho nó hoạt động, tôi sẽ đăng câu trả lời. –

+0

@ScottJacobsen bất kỳ may mắn cho đến nay? – jQwierdy

+0

@jQwierdy - đăng giải pháp của tôi. –

Trả lời

2

Tôi lưu bộ nhớ cache vào một tệp tar trong thư mục tmp ứng dụng.Sau đó, tôi sao chép các viên đá quý vào một lớp bằng cách sử dụng lệnh ADD trước khi thực hiện cài đặt gói. Từ số Dockerfile.yml:

WORKDIR /home/app 

# restore the gem cache. This only runs when 
# gemcache.tar.bz2 changes, so usually it takes 
# no time 
ADD tmp/gemcache.tar.bz2 /var/lib/gems/ 

COPY Gemfile /home/app/Gemfile 
COPY Gemfile.lock /home/app/Gemfile.lock 
RUN gem update --system && \ 
gem update bundler && \ 
bundle install --jobs 4 --retry 5 

Đảm bảo bạn đang gửi bộ nhớ đệm đá quý đến máy đế của bạn. Gemcache của tôi là 118MB, nhưng kể từ khi tôi xây dựng tại địa phương nó sao chép nhanh. My .dockerignore:

tmp 
!tmp/gemcache.tar.bz2 

Bạn cần lưu bộ nhớ cache từ hình ảnh đã tạo nhưng ban đầu bạn có thể không có hình ảnh. Tạo một bộ nhớ cache trống như vậy (tôi có điều này trong một công việc cào):

task :clear_cache do 
    sh "tar -jcf tmp/gemcache.tar.bz2 -T /dev/null" 
end 

Sau khi hình ảnh được xây dựng sao chép đá quý vào bộ nhớ đệm đá quý. Hình ảnh của tôi được gắn thẻ app. Tôi tạo một container docker từ hình ảnh, sao chép /var/lib/gems/2.2.0 vào gemcache của tôi bằng cách sử dụng lệnh docker cp, và sau đó xóa container. Đây là nhiệm vụ rake của tôi:

task :cache_gems do 
    id = `docker create app`.strip 
    begin 
    sh "docker cp #{id}:/var/lib/gems/2.2.0/ - | bzip2 > tmp/gemcache.tar.bz2" 
    ensure 
    sh "docker rm -v #{id}" 
    end 
end 

Trên hình ảnh tiếp theo, xây dựng gemcache được sao chép vào một lớp trước khi gọi là bundle install. Quá trình này mất một chút thời gian, nhưng nó nhanh hơn bundle install từ đầu.

Các bản dựng sau đó thậm chí còn nhanh hơn vì trình gắn đế đã lưu vào bộ nhớ lớp ADD tmp/gemcache.tar.bz2 /var/lib/gems/. Nếu có bất kỳ thay đổi nào đối với Gemfile.lock chỉ những thay đổi đó được tạo.

Không có lý do gì để xây dựng lại bộ đệm đá quý trên mỗi thay đổi Gemfile.lock. Khi có đủ sự khác biệt giữa bộ nhớ cache và Gemfile.lock, bundle install chậm, bạn có thể tạo lại bộ nhớ cache đá quý. Khi tôi muốn xây dựng lại bộ đệm đá quý, nó là một lệnh rake cache_gems đơn giản.

+0

Giải pháp thú vị. Mặc dù mối quan tâm của tôi sẽ là bước thủ công của việc chạy bộ đệm đá quý tại một số điểm không xác định kịp thời. – mfilimonov

+0

Có thể làm điều gì đó như thế này trong dockerfile "kiểm tra bó || (bundle install && rake cache_gems)" sẽ có hành vi mong đợi? – jQwierdy

+0

Nó sẽ làm cho nó như vậy chỉ khi gói đã thay đổi, nó sẽ cài đặt và mỗi khi nó cài đặt nó sẽ đệm đá quý :-) – jQwierdy

3

Tôi đã tìm thấy hai giải pháp có thể sử dụng khối lượng dữ liệu ngoài để lưu trữ đá quý: onetwo.

Tóm lại,

  • bạn chỉ định một hình ảnh được sử dụng để lưu trữ chỉ
  • đá quý trong ứng dụng hình ảnh của bạn, trong docker-compose.yml bạn chỉ định các mount point cho BUNDLE_PATH qua volumes_from.
  • khi vùng chứa ứng dụng của bạn khởi động, nó sẽ thực thi bundle check || bundle install và mọi thứ đều tốt.

Đây là một giải pháp khả thi, tuy nhiên đối với tôi, cảm giác như nó hơi đi ngược lại với cách đế. Cụ thể, bundle install với tôi có vẻ như là một phần của quá trình xây dựng và không nên là một phần của thời gian chạy. Những thứ khác, phụ thuộc vào bundle install như asset:precompile hiện là tác vụ thời gian chạy.

Đây là giải pháp có thể xử lý nhưng tôi đang mong chờ điều gì đó mạnh mẽ hơn một chút.

Các vấn đề liên quan