Làm cách nào để có docker-compose để luôn tạo lại các container từ hình ảnh mới?


198

Hình ảnh docker của tôi được xây dựng trên máy chủ Jenkins CI và được đẩy lên Docker Registry riêng của chúng tôi. Mục tiêu của tôi là cung cấp môi trường với docker-compose, luôn bắt đầu trạng thái được xây dựng ban đầu của hình ảnh.

Tôi hiện đang sử dụng docker-compose 1.3.2 cũng như 1.4.0 trên các máy khác nhau nhưng chúng tôi cũng đã sử dụng các phiên bản cũ hơn trước đây.

Tôi luôn sử dụng các docker-compose pull && docker-compose up -dlệnh để lấy các hình ảnh mới từ sổ đăng ký và khởi động chúng. Tôi tin rằng hành vi ưa thích của tôi đã hoạt động như mong đợi đến một thời điểm nhất định, nhưng kể từ đó docker-compose upbắt đầu chạy lại các container đã dừng trước đó thay vì bắt đầu các hình ảnh được xây dựng ban đầu mỗi lần.

Có cách nào để thoát khỏi hành vi này? Cách đó có thể là một trong đó có dây trong tệp cấu hình docker-compose.yml để không phụ thuộc "không quên" một cái gì đó trên dòng lệnh trên mỗi lệnh gọi?

ps. Bên cạnh việc tìm cách đạt được mục tiêu của mình, tôi cũng rất muốn biết thêm một chút về nền tảng của hành vi này. Tôi nghĩ ý tưởng cơ bản của Docker là xây dựng một cơ sở hạ tầng bất biến. Hành vi hiện tại của docker-compose dường như chỉ xung đột với cách tiếp cận này .. hoặc tôi có bỏ lỡ một số điểm ở đây không?

Câu trả lời:


232

docker-compose up --force-recreatelà một tùy chọn, nhưng nếu bạn đang sử dụng nó cho CI, tôi sẽ bắt đầu xây dựng docker-compose rm -fđể dừng và loại bỏ các thùng chứa và khối lượng (sau đó làm theo với kéo và lên).

Đây là những gì tôi sử dụng:

docker-compose rm -f
docker-compose pull
docker-compose up --build -d
# Run some tests
./tests
docker-compose stop -t 1

Lý do các container được tạo lại là để bảo toàn bất kỳ khối lượng dữ liệu nào có thể được sử dụng (và nó cũng xảy ra để làm cho upnhanh hơn rất nhiều).

Nếu bạn đang làm CI, bạn không muốn điều đó, vì vậy chỉ cần xóa mọi thứ bạn sẽ muốn bạn muốn.

Cập nhật: sử dụng up --buildđã được thêm vào docker-compose1.7


1
Vâng, thực sự đây là những gì tôi làm trong CI. Không chắc tại sao tôi không đề cập đến điều đó ...
Adrian Mouat

@dnephin docker-compose run -dkhông tồn tại? Bạn muốn nói docker-compose up -dkhông?
Guillaume Vincent

2
nếu bạn chạy docker-compose pulltrước khi docker-compose rm -fbạn có thể tiết kiệm nhiều thời gian hơn
stephanlindauer

2
Cờ -d ở cuối làm gì?
David J. Davis

3
"-d Chế độ tách rời: Chạy các container trong nền",
dnephin

135

Giải pháp duy nhất hiệu quả với tôi là lệnh này:

docker-compose build --no-cache

Điều này sẽ tự động lấy hình ảnh mới từ repo và sẽ không sử dụng phiên bản bộ đệm được dựng sẵn với bất kỳ tham số nào bạn đã sử dụng trước đó.


1
Ngoài ra, trong Windows 10, nó có thể giúp đặt máy chủ DNS trong cài đặt từ Tự động sang Cố định hoặc từ Cố định sang Tự động.
qräbnö

2
Làm việc cho tôi trên tòa nhà OS X với phiên bản docker-comopse 2.
RoboBear

1
Làm việc trên docker OS X.
HelloWorld

55

Theo tài liệu chính thức hiện tại, có một đoạn cắt ngắn dừng và loại bỏ các thùng chứa, mạng, khối lượng và hình ảnh được tạo bởi, nếu chúng đã bị dừng hoặc bị xóa một phần, v.v., thì nó cũng sẽ thực hiện thủ thuật:

docker-compose down

Sau đó, nếu bạn có những thay đổi mới trên hình ảnh hoặc Dockerfiles, hãy sử dụng:

docker-compose build --no-cache

Cuối cùng:docker-compose up

Trong một lệnh: docker-compose down && docker-compose build --no-cache && docker-compose up


2
docker-compose build --no-cachechỉ cần thiết nếu có thay đổi trên Dockerfiles.
Victor Timoftii

Thật vậy, Victor. Cảm ơn! Tôi nghĩ rằng nó cũng cần thiết sau khi cập nhật một mô-đun / ứng dụng được thực thi khi container khởi động. Đối với những trường hợp này, trước khi chạy docker-compose up, là cần thiết để xây dựng lại các dịch vụ với docker-compose build.
ivanleoncz

18

Bạn có thể vượt qua --force-recreateđể docker compose up, mà nên sử dụng container tươi.

Tôi nghĩ lý do đằng sau việc tái sử dụng các container là để bảo toàn mọi thay đổi trong quá trình phát triển. Lưu ý rằng Compose thực hiện một số thứ tương tự với các tập, điều này cũng sẽ tồn tại giữa giải trí container (một container được tạo lại sẽ gắn với các tập của người tiền nhiệm). Điều này có thể hữu ích, ví dụ, nếu bạn có bộ chứa Redis được sử dụng làm bộ đệm và bạn không muốn mất bộ đệm mỗi khi bạn thực hiện một thay đổi nhỏ. Vào những lúc khác, nó thật khó hiểu.

Tôi không tin có bất kỳ cách nào bạn có thể ép buộc điều này từ tệp Soạn.

Có thể cho rằng nó đụng độ với các nguyên tắc cơ sở hạ tầng bất biến. Đối số có lẽ là bạn không sử dụng Compose trong sản xuất (chưa). Ngoài ra, tôi không chắc chắn rằng tôi đồng ý rằng infra bất biến là ý tưởng cơ bản của Docker, mặc dù đó chắc chắn là một trường hợp sử dụng / điểm bán tốt.


Cảm ơn câu trả lời. Tôi nghĩ rằng nó sẽ thực sự hữu ích khi buộc nó ở mức cấu hình, ví dụ. để thực thi nó cho một bộ chứa cơ sở dữ liệu và tắt giải trí theo mặc định cho các bộ chứa ứng dụng ..
Kristof Jozsa

8
--force-recreatekhông hoạt động đối với tôi ... Hình ảnh không được kéo ngay cả khi có phiên bản mới hơn ...
lisak

1
@lisak Mình chưa bao giờ nói nó kéo hình ảnh mới. Nó không. Nó chỉ bắt đầu các container mới bằng cách sử dụng bất kỳ hình ảnh nào có sẵn tại địa phương. Bạn sẽ cần phải chạy docker kéo bằng tay.
Adrian Mouat

2
docker-compose up --build

HOẶC LÀ

docker-compose build --no-cache

1
Khi có thể, vui lòng thực hiện một nỗ lực để cung cấp giải thích bổ sung thay vì chỉ mã. Những câu trả lời như vậy có xu hướng hữu ích hơn vì chúng giúp các thành viên của cộng đồng và đặc biệt là các nhà phát triển mới hiểu rõ hơn lý do của giải pháp và có thể giúp ngăn chặn nhu cầu giải quyết các câu hỏi tiếp theo.
Rajan

-10
$docker-compose build

Nếu có một cái gì đó mới, nó sẽ được xây dựng lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.