Làm cách nào để buộc Docker xây dựng hình ảnh rõ ràng


818

Tôi đã xây dựng hình ảnh Docker từ tệp Docker bằng lệnh bên dưới.

$ docker build -t u12_core -f u12_core .

Khi tôi đang cố gắng xây dựng lại nó bằng cùng một lệnh, nó sẽ sử dụng bộ đệm xây dựng như:

Step 1 : FROM ubuntu:12.04
 ---> eb965dfb09d2
Step 2 : MAINTAINER Pavan Gupta <pavan.gupta@gmail.com>
 ---> Using cache
 ---> 4354ccf9dcd8
Step 3 : RUN apt-get update
 ---> Using cache
 ---> bcbca2fcf204
Step 4 : RUN apt-get install -y openjdk-7-jdk
 ---> Using cache
 ---> 103f1a261d44
Step 5 : RUN apt-get install -y openssh-server
 ---> Using cache
 ---> dde41f8d0904
Step 6 : RUN apt-get install -y git-core
 ---> Using cache
 ---> 9be002f08b6a
Step 7 : RUN apt-get install -y build-essential
 ---> Using cache
 ---> a752fd73a698
Step 8 : RUN apt-get install -y logrotate
 ---> Using cache
 ---> 93bca09b509d
Step 9 : RUN apt-get install -y lsb-release
 ---> Using cache
 ---> fd4d10cf18bc
Step 10 : RUN mkdir /var/run/sshd
 ---> Using cache
 ---> 63b4ecc39ff0
Step 11 : RUN echo 'root:root' | chpasswd
 ---> Using cache
 ---> 9532e31518a6
Step 12 : RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
 ---> Using cache
 ---> 47d1660bd544
Step 13 : RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
 ---> Using cache
 ---> d1f97f1c52f7
Step 14 : RUN wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/ubuntu12'
 ---> Using cache
 ---> bd7dde7a98b9
Step 15 : RUN tar -xvf aerospike.tgz
 ---> Using cache
 ---> 54adaa09921f
Step 16 : RUN dpkg -i aerospike-server-community-*/*.deb
 ---> Using cache
 ---> 11aba013eea5
Step 17 : EXPOSE 22 3000 3001 3002 3003
 ---> Using cache
 ---> e33aaa78a931
Step 18 : CMD /usr/sbin/sshd -D
 ---> Using cache
 ---> 25f5fe70fa84
Successfully built 25f5fe70fa84

Bộ nhớ cache cho thấy hàng không vũ trụ được cài đặt. Tuy nhiên, tôi không tìm thấy nó bên trong các thùng chứa sinh ra từ hình ảnh này, vì vậy tôi muốn xây dựng lại hình ảnh này mà không cần sử dụng bộ đệm. Làm cách nào tôi có thể buộc Docker xây dựng lại một hình ảnh sạch mà không có bộ đệm?


10
Bên cạnh đó, bạn thường nên cố gắng giảm thiểu số lượng RUNchỉ thị.
tripleee

4
@tripleee Bạn có thể giải thích tại sao?
Ya.

9
@Ya. Trước đây, Docker luôn tạo ra một lớp riêng biệt cho mỗi RUNchỉ thị, do đó, Dockerfilevới nhiều lệnh RUNsẽ tiêu thụ một lượng không gian đĩa khổng lồ; nhưng điều này rõ ràng đã được cải thiện phần nào trong các phiên bản gần đây.
tripleee

Khi tôi thử docker-compose up -d, tôi có thể sử dụng ở --no-cacheđâu?
Oo

@Oo điều đó là không thể. Trước tiên bạn phải làm docker-compose build --no-cachevà sau đódocker-compose up -d
Martin Melka

Câu trả lời:


1445

Có một --no-cachelựa chọn:

docker build --no-cache -t u12_core -f u12_core .

Trong các phiên bản cũ hơn của Docker bạn cần phải vượt qua --no-cache=true, nhưng điều này không còn nữa.


89
Cũng lưu ý rằng --no-cachelàm việc với docker-compose build.
Blackus

42
Bạn cũng có thể muốn sử dụng --pull. Điều này sẽ báo cho docker để có được phiên bản mới nhất của hình ảnh cơ sở. Điều này là cần thiết ngoài việc --no-cachebạn đã có hình ảnh cơ sở (ví dụ ubuntu/latest:) và hình ảnh cơ sở đã được cập nhật kể từ lần cuối bạn kéo nó. Xem các tài liệu ở đây .
Collin Krawll

2
@CollinKrawll: --pullTùy chọn đã thực hiện thủ thuật cho tôi. Chỉ là --no-cache, xây vẫn vỡ. Đặt vào --pulllà tốt, xây dựng làm việc! Cảm ơn bạn!
Erdős-Bacon

1
Nếu ai đó đang gọi docker build không phải là giả định rằng họ muốn xây dựng lại mà không có bộ đệm? Trong trường hợp sử dụng, ai đó sẽ muốn xây dựng một hình ảnh và sử dụng một hình ảnh được xây dựng trước đó? <rant> Tôi vừa mất một ngày vì bản dựng trước đó đã âm thầm hoàn thành "thành công" và tôi đang sử dụng hình ảnh bị hỏng không hiểu tại sao các bản cập nhật cho tập lệnh xây dựng không hoạt động </ rant>
Jeff

3
@Jeff Khi bạn đang phát triển hình ảnh docker, bản dựng docker sẽ chỉ làm lại các lớp / bước đã được sửa đổi. Nếu tôi có năm bước và tôi thêm một bước mới tại chỉ mục 3, các lớp được liên kết với bước 1 và 2 có thể được sử dụng lại. Điều này giúp tăng tốc đáng kể quá trình phát triển
flakes

130

Trong một số trường hợp cực đoan, cách duy nhất của bạn xung quanh các lỗi xây dựng định kỳ là chạy:

docker system prune

Lệnh sẽ yêu cầu bạn xác nhận:

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all networks not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N]

Tất nhiên đây không phải là câu trả lời trực tiếp cho câu hỏi, nhưng có thể cứu một số mạng sống ... Nó đã cứu tôi.


8
thêm -a -f làm cho nó tốt hơn
Ravi

1
@IulianOnofrei Làm việc cho tôi,Docker version 17.09.0-ce, build afdb6d4
Per Lundberg

1
@PerLundberg, tôi đã cập nhật dockerlên cùng một phiên bản và nó hoạt động, cảm ơn bạn.
Iulian Onofrei

1
Đây là cách quá mức cần thiết cho kịch bản này và không phải là câu trả lời có thể sử dụng được nếu bạn không muốn xóa mọi thứ.
M_dk

1
Điều này thậm chí sẽ xóa hình ảnh của các container bị dừng, có thể là điều bạn không muốn. Các phiên bản gần đây của docker có lệnh docker builder prunexóa các lớp xây dựng được lưu trữ. Chỉ rơi vào bẫy sau khi sao chép một cách mù quáng các lệnh từ stack stack.
Ác quỷ Azrael

59

Lệnh đã docker build --no-cache .giải quyết vấn đề tương tự của chúng tôi.

Dockerfile của chúng tôi là:

RUN apt-get update
RUN apt-get -y install php5-fpm

Nhưng lẽ ra phải là:

RUN apt-get update && apt-get -y install php5-fpm

Để ngăn chặn bộ đệm cập nhật và cài đặt riêng.

Xem: Cách thực hành tốt nhất để viết Dockerfiles


10
"Đáng lẽ phải" là sai lệch. Nếu Docker thấy rằng nó có một bản sao được lưu trong bộ nhớ cache RUN apt-get update && apt-get -y install php5-fpmthì bạn vẫn sẽ thấy nó được sử dụng lại với nội dung cũ.
tripleee

10
Trên thực tế, vẫn hợp lý khi tham gia cùng họ, vì nếu không, nếu bạn thay đổi dòng cài đặt, nó vẫn sẽ sử dụng bộ đệm gói cũ, thường sẽ gặp vấn đề nếu bộ đệm bị lỗi thời (thông thường, các tệp sẽ 404.)
John Chadwick

19

Để đảm bảo rằng bản dựng của bạn được xây dựng lại hoàn toàn, bao gồm kiểm tra hình ảnh cơ sở để cập nhật, hãy sử dụng các tùy chọn sau khi xây dựng:

--no-cache - Điều này sẽ buộc xây dựng lại các lớp đã có sẵn

--pull - Điều này sẽ kích hoạt kéo hình ảnh cơ sở được tham chiếu bằng TỪ đảm bảo bạn có phiên bản mới nhất.

Lệnh đầy đủ do đó sẽ trông như thế này:

docker build --pull --no-cache --tag myimage:version .

Các tùy chọn tương tự có sẵn cho docker-compose:

docker-compose build --no-cache --pull

13

Tôi không khuyên bạn nên sử dụng --no-cachetrong trường hợp của bạn.

Bạn đang chạy một vài cài đặt từ bước 3 đến 9 (Nhân tiện, tôi sẽ thích sử dụng một lớp lót) và nếu bạn không muốn sử dụng lại các bước này mỗi khi bạn xây dựng hình ảnh của mình, bạn có thể sửa đổi của bạn Dockerfilevới một bước tạm thời trước khi wgethướng dẫn của bạn .

Tôi sử dụng để làm một cái gì đó như RUN ls .và thay đổi nó RUN ls ./sau đó RUN ls ./.và cứ như vậy cho mỗi sửa đổi được thực hiện trên tarball được lấy bởiwget

Tất nhiên bạn có thể làm một cái gì đó như RUN echo 'test1' > test && rm testtăng số lượng 'test1cho mỗi lần lặp.

Trông có vẻ bẩn, nhưng theo tôi biết đó là cách hiệu quả nhất để tiếp tục hưởng lợi từ hệ thống bộ đệm của Docker, giúp tiết kiệm thời gian khi bạn có nhiều lớp ...


3
Khả năng không thể sử dụng bộ đệm sau một thời điểm nhất định là một tính năng được nhiều người yêu cầu (xem github.com/moby/moby/issues/1996 để biết các lựa chọn thay thế cho việc phá bộ đệm)
leszek.hanusz

13

Với docker-compose thử docker-compose up -d --build --force-recreate


5

Hầu hết thông tin ở đây là chính xác.
Đây là một bản tổng hợp về chúng và cách tôi sử dụng chúng.

Ý tưởng là bám sát vào cách tiếp cận được đề xuất (xây dựng cụ thể và không ảnh hưởng đến các đối tượng docker được lưu trữ khác) và thử cách tiếp cận triệt để hơn (không xây dựng cụ thể và tác động lên các đối tượng docker được lưu trữ khác) khi nó không đủ.

Phương pháp đề xuất:

1) Buộc thực thi từng bước / hướng dẫn trong Dockerfile:

docker build --no-cache 

hoặc với docker-compose build:

docker-compose build --no-cache

Chúng ta cũng có thể kết hợp điều đó với lệnh upphụ tạo lại tất cả các container:

docker-compose build --no-cache &&
docker-compose up -d --force-recreate 

Những cách này không sử dụng bộ đệm nhưng cho trình tạo docker và hình ảnh cơ sở được tham chiếu với FROMhướng dẫn.

2) Xóa bộ nhớ cache của trình tạo docker (nếu chúng ta sử dụng Buildkit, chúng ta rất có thể cần điều đó):

docker builder prune -af

3) Nếu chúng tôi không muốn sử dụng bộ đệm của hình ảnh gốc, chúng tôi có thể cố gắng xóa chúng, chẳng hạn như:

docker image rm -f fooParentImage

Trong hầu hết các trường hợp, 3 điều này là hoàn toàn đủ để cho phép xây dựng hình ảnh rõ ràng của chúng tôi.
Vì vậy, chúng ta nên cố gắng bám vào đó.

Cách tiếp cận triệt để hơn:

Trong các trường hợp góc có vẻ như một số đối tượng trong bộ đệm docker vẫn được sử dụng trong quá trình xây dựng và có vẻ như có thể lặp lại, chúng ta nên cố gắng hiểu nguyên nhân để có thể xóa phần bị thiếu một cách cụ thể. Nếu chúng ta thực sự không tìm cách xây dựng lại từ đầu, có những cách khác nhưng điều quan trọng cần nhớ là những cách này thường xóa nhiều hơn mức cần thiết. Vì vậy, chúng ta nên sử dụng chúng với tổng thể thận trọng khi chúng ta không ở trong môi trường địa phương / dev.

1) Xóa tất cả các hình ảnh mà không có ít nhất một thùng chứa liên quan đến chúng:

docker image prune -a

2) Xóa nhiều thứ khác:

docker system prune -a

Điều đó nói :

CẢNH BÁO! Điều này sẽ loại bỏ:
  - tất cả các container đã dừng
  - tất cả các mạng không được sử dụng bởi ít nhất một container
  - tất cả hình ảnh không có ít nhất một thùng chứa liên quan đến chúng
  - tất cả bộ đệm xây dựng

Sử dụng lệnh siêu xóa đó có thể không đủ vì nó phụ thuộc nhiều vào trạng thái của các thùng chứa (chạy hay không). Khi lệnh đó là không đủ, tôi cố gắng suy nghĩ cẩn thận những container nào có thể gây ra tác dụng phụ cho việc xây dựng docker của chúng tôi và cho phép những container này được thoát ra để cho phép chúng được gỡ bỏ bằng lệnh.


3

Bạn có thể quản lý bộ đệm của trình tạo với docker builder

Để làm sạch tất cả các bộ đệm mà không có dấu nhắc: docker builder prune -af

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.