2014-12-17 28 views
26

Tôi có một tập tin Docker cố gắng để triển khai mã Django để một containerLàm thế nào để cập nhật mã từ Git để một container Docker

FROM ubuntu:latest 
MAINTAINER { myname } 

#RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sou$ 

RUN apt-get update 

RUN DEBIAN_FRONTEND=noninteractive apt-get install -y tar git curl dialog wget net-tools nano buil$ 
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python python-dev python-distribute python-p$ 

RUN mkdir /opt/app 
WORKDIR /opt/app 

#Pull Code 
RUN git clone [email protected]/{user}/{repo} 

RUN pip install -r website/requirements.txt 

#EXPOSE = ["8000"] 
CMD python website/manage.py runserver 0.0.0.0:8000 

Và sau đó tôi xây dựng mã của tôi như docker build -t dockerhubaccount/demo:v1 ., và điều này kéo mã của tôi từ Bitbucket để thùng chứa. Tôi chạy nó như docker run -p 8000:8080 -td felixcheruiyot/demo:v1 và mọi thứ dường như hoạt động tốt.

Bây giờ tôi muốn cập nhật mã tức là kể từ khi tôi sử dụng git clone ..., tôi có sự nhầm lẫn này:

  • Làm thế nào tôi có thể cập nhật mã của tôi khi tôi có cam kết mới và khi container Docker xây dựng nó tàu với mã mới (lưu ý: khi tôi chạy build nó không lấy nó vì cache).
  • Quy trình làm việc tốt nhất cho loại phương pháp này là gì?

Trả lời

20

Có một số phương pháp bạn có thể sử dụng.

  1. Bạn có thể sử dụng docker build --no-cache để tránh sử dụng bộ nhớ cache của bản sao Git.
  2. Lệnh khởi động gọi git pull. Vì vậy, thay vì chạy python manage.py, bạn sẽ có một cái gì đó như CMD cd /repo && git pull && python manage.py hoặc sử dụng tập lệnh bắt đầu nếu mọi thứ phức tạp hơn.

Tôi có xu hướng thích 2. Bạn cũng có thể chạy một công việc cron để cập nhật mã trong vùng chứa của mình, nhưng đó là một ít công việc hơn và đi một chút so với triết lý Docker.

+2

Tôi sẽ nhận 2 câu trả lời. Tôi nghĩ rằng nó có ý nghĩa hơn kể từ khi chạy --no-cache sẽ cài đặt mọi thứ một cách tiếp cận mới, không phải là tốt. Cảm ơn sự đóng góp của bạn. –

+0

nếu một người nào đó thực thi 'docker exec -it con/tainer bash' - điều đó sẽ chạy' bash' thay vì bất cứ điều gì được chỉ định trong 'CMD'. Dường như với tôi rằng cả hai tùy chọn là khá tối ưu, và điều này phải là vấn đề rất phổ biến - tôi cảm thấy cần có một cách để vô hiệu hóa bộ nhớ đệm ở giữa 'Dockerfile'. – avloss

5

Một giải pháp khác.

Lệnh tạo trình tạo Docker sử dụng bộ nhớ cache miễn là chuỗi chỉ lệnh giống hệt như một hình ảnh được lưu trong bộ nhớ cache. Vì vậy, nếu bạn viết

RUN echo '2014122400' >/dev/null && git pull ... 

Khi cập nhật tiếp theo, bạn thay đổi như sau.

RUN echo '2014122501' >/dev/null && git pull ... 

Điều này có thể ngăn trình cắm không sử dụng bộ nhớ cache.

+0

Tôi nghĩ câu trả lời hay nhất là điều này. Với phương pháp này, chúng tôi chỉ có thể tắt bộ nhớ cache phù hợp. – makerj

+0

cần lưu ý rằng điều này sẽ gây ra mọi thứ SAU KHI dòng này được xây dựng lại. Tốt nếu git pull của bạn là dòng cuối cùng như trong câu hỏi OPs.Có thể là xấu nếu git kéo của bạn là trước đó trong một Dockerfile – JHowIX

10

Tôi khuyên bạn nên thanh toán mã trên máy chủ của mình và COPY vào hình ảnh. Bằng cách đó, nó sẽ được cập nhật bất cứ khi nào bạn thực hiện thay đổi. Ngoài ra, trong quá trình phát triển, bạn có thể liên kết gắn kết thư mục nguồn qua thư mục mã trong vùng chứa, nghĩa là mọi thay đổi đều được phản ánh ngay trong vùng chứa.

Lệnh docker cho kho lưu trữ git kiểm tra bản cập nhật cuối cùng sẽ rất hữu ích!

2

Tôi muốn cung cấp một giải pháp khả thi khác. Tuy nhiên, tôi cần phải cảnh báo rằng nó chắc chắn không phải là "con đường bến tàu" làm việc và dựa vào sự tồn tại của khối lượng (có thể là một kẻ chặn tiềm năng trong các công cụ như Docker Swarm và Kubernetes). lợi dụng thực tế là nội dung của các thư mục chứa được sử dụng như Docker Volumes, thực sự được lưu trữ trong hệ thống tệp của máy chủ lưu trữ. Hãy xem this một phần tài liệu.

Trong trường hợp của bạn, bạn sẽ thực hiện /opt/app khối lượng Docker.Bạn không cần ánh xạ Khối lượng một cách rõ ràng đến một vị trí trên hệ thống tệp của máy chủ kể từ khi tôi mô tả dưới đây, ánh xạ có thể được lấy động.

Vì vậy, cho người mới bắt đầu rời khỏi Dockerfile của bạn chính xác như nó được và chuyển lệnh tạo container của bạn để một cái gì đó như:

docker run -p 8000:8080 -v /opt/app --name some-name -td felixcheruiyot/demo:v1 

Lệnh docker inspect -f {{index .Volumes "/opt/webapp"}} some-name sẽ in đường dẫn hệ thống tập tin đầy đủ về các máy chủ nơi mã của bạn được lưu trữ (this là nơi tôi chọn thủ thuật kiểm tra).

Được trang bị kiến ​​thức đó tất cả những gì bạn phải làm là thay thế mã đó và tất cả các bộ của bạn. kịch bản triển khai Vì vậy, một rất đơn giản sẽ là một cái gì đó như:

code_path=$(docker inspect -f {{index .Volumes "/opt/webapp"}} some-name) 
rm -rfv $code_path/* 
cd $code_path 
git clone [email protected]/{user}/{repo} 

Những lợi ích bạn nhận được với một cách tiếp cận như thế này là:

  • Có hình ảnh cacheless không có khả năng tốn kém giúp rebuild
  • Không có cần di chuyển thông tin chạy ứng dụng cụ thể vào lệnh chạy. Các Dockerfile là nguồn duy nhất của cần thiết cho việc áp dụng instrumenting

CẬP NHẬT

Bạn có thể đạt được kết quả tương tự tôi đã đề cập ở trên sử dụng docker cp (bắt đầu Docker 1.8). Bằng cách này, vùng chứa không cần có khối lượng và bạn có thể thay thế mã trong vùng chứa như bạn thực hiện trên hệ thống tệp lưu trữ.

Tất nhiên như tôi đã đề cập ở phần đầu của câu trả lời, đây không phải là "con đường bến tàu" làm việc, điều này khiến các thùng chứa không thay đổi và có thể lặp lại.

+0

chỉ là một lưu ý ... container docker bất biến? làm thế nào để điều này đối phó với một môi trường python thay đổi khi một bản cập nhật ứng dụng sử dụng phụ thuộc mới? – Yoeri

+0

@Yoeri Cách người quản lý quảng cáo sử dụng các vùng chứa * mới * bất cứ khi nào có thay đổi. Điều đó có nghĩa là khi ứng dụng được cập nhật theo bất kỳ cách nào (có thể là mã ứng dụng, phụ thuộc, cấu hình, v.v.), nên tạo một vùng chứa mới. Mục đích là có khả năng tái tạo đầy đủ của container – geoand

+1

vì vậy nó sẽ tốt hơn khi sử dụng một thùng chứa (hoặc máy chủ) riêng biệt với các nguồn và môi trường và chia sẻ các ổ đĩa đó ..Tôi luôn tìm câu hỏi về việc thay đổi mã nguồn, không bao giờ thay đổi phụ thuộc. .. – Yoeri

0

Nếu bạn sử dụng GitHub, bạn có thể sử dụng API GitHub để không lưu các lệnh RUN cụ thể.

Bạn cần phải có JQ cài đặt để phân tích cú pháp JSON: apt-get install -y jq

Ví dụ:

docker build --build-arg SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | jq -r '.[0].sha') -t imageName . 

Trong Dockerfile (ARG lệnh nên ngay trước RUN):

ARG SHA=LATEST 
RUN SHA=${SHA} \ 
    git clone https://github.com/Tencent/mars.git 

Hoặc nếu bạn không muốn cài đặt jq:

SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | grep sha | head -1) 

Nếu một kho lưu trữ có các cam kết mới, git clone sẽ được thực thi.

+0

Bạn cũng có thể sử dụng 'ADD' để có' docker build' tải xuống HEAD hiện tại từ API mỗi lần . Sau đó, khi HEAD thay đổi bộ nhớ cache bị vô hiệu. http://stackoverflow.com/questions/36996046/how-to-prevent-dockerfile-caching-git-clone/39278224#39278224 – anq

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