Docker'ı görüntünün temiz bir yapısı için zorlama


814

Aşağıdaki komutu kullanarak bir Docker dosyasından bir Docker görüntüsü oluşturdum.

$ docker build -t u12_core -f u12_core .

Aynı komutla yeniden oluşturmaya çalıştığımda, aşağıdaki gibi önbellek kullanıyor:

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

Önbellek, aerospike'ın kurulu olduğunu gösterir. Ancak, bu görüntüden çıkan kapların içinde bulamıyorum, bu yüzden önbelleği kullanmadan bu görüntüyü yeniden oluşturmak istiyorum. Docker'ı önbellek olmadan temiz bir görüntü oluşturmaya nasıl zorlayabilirim?


10
Bir yana, genellikle RUNdirektif sayısını en aza indirmeye çalışmalısınız .
tripleee

4
@tripleee Nedenini açıklayabilir misiniz?
Ya.

9
@Ya. Docker'ın her RUNyönerge için her zaman ayrı bir katman oluşturmasıydı , bu nedenle Dockerfilebirçok RUNyönerge ile büyük miktarlarda disk alanı tüketirdi; ancak görünüşe göre bu son versiyonlarda bir miktar iyileştirildi.
tripleee

Denediğimde docker-compose up -dnerede kullanabilirim --no-cache?
Oo

@Oo bu mümkün değil. Önce yapmalı docker-compose build --no-cacheve sonradocker-compose up -d
Martin Melka

Yanıtlar:


1441

Bir --no-cacheseçenek var:

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

Docker'ın eski sürümlerinde geçmeniz gerekiyordu --no-cache=true, ancak bu artık geçerli değil.


89
Ayrıca --no-cacheçalıştığını da unutmayın docker-compose build.
Blackus

42
Ayrıca kullanmak isteyebilirsiniz --pull. Bu, docker'a temel görüntünün en son sürümünü almasını söyleyecektir. --no-cacheTemel görüntüye (ör .:) zaten sahipseniz ve temel görüntüyü ubuntu/latestson çektiğinizden beri güncellenmişse buna ek olarak bu gereklidir . Dokümanlara buradan bakın .
Collin Krawll

2
@CollinKrawll: Bu --pullseçenek benim için hile yaptı. Sadece --no-cacheinşa hala kırıldı. Koy --pull, inşa et! Teşekkür ederim!
Erdős-Bacon

1
Birisi docker derleme çağırıyorsa, önbellek olmadan yeniden inşa etmek istediği varsayılmıyor mu? Hangi kullanım durumunda birisi bir görüntü oluşturmak ve daha önce oluşturulmuş bir görüntü kullanmak ister? <rant> Bir gün kaybettim çünkü daha önceki bir yapı sessizce başarısız oldu ancak "başarılı" tamamladı ve yapı betiği güncellemelerinin neden çalışmadığını anlamayan kırık resmi kullanıyordum </rant>
Jeff

3
@Jeff Bir docker görüntüsü geliştirirken, docker derlemesi yalnızca değiştirilen katmanları / adımları yeniden yapar. Beş adımım varsa ve dizin 3'e yeni bir adım eklersem, adım 1 ve 2 ile ilişkili katmanlar yeniden kullanılabilir. Bu büyük ölçüde geliştirme sürecini hızlandırır
gevreği

130

Bazı aşırı durumlarda, yinelenen derleme hatalarını çözmenin tek yolu koşmaktır:

docker system prune

Komut sizden onayınızı isteyecektir:

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]

Bu elbette soruya doğrudan bir cevap değil, ama bazı hayatları kurtarabilir ... Benimkini kurtardı.


8
-a -f ekleyerek daha iyi hale getirir
Ravi

1
@IulianOnofrei Benim için çalışıyor,Docker version 17.09.0-ce, build afdb6d4
Per Lundberg

1
@PerLundberg, dockeraynı sürüme güncelledim ve çalışıyor, teşekkür ederim.
Iulian Onofrei

1
Bu, her şeyi silmek istemiyorsanız kullanılabilir bir cevap değil, bu senaryo için aşırı derecede aşırıdır.
M_dk

1
Bu, muhtemelen istemediğiniz bir şey olan durdurulmuş kapların görüntülerini bile siler. Docker'ın son sürümlerinde docker builder prune, önbelleğe alınan derleme katmanlarını temizleme komutu bulunur . Yığın taşmasından komutları körü körüne kopyaladıktan sonra tuzağa düştüm.
Evil Azrael

59

Komut docker build --no-cache .benzer sorunumuzu çözdü.

Dockerfile dosyamız:

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

Ancak:

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

Güncelleştirmenin önbelleğe alınmasını önlemek için ve ayrı olarak yükleyin.

Bkz. Dockerfiles yazmak için en iyi uygulamalar


10
"Olmalıydı" yanıltıcıdır. Docker önbelleğe alınmış bir kopyasına sahip olduğunu görürse RUN apt-get update && apt-get -y install php5-fpmyine de eski içeriklerle yeniden kullanıldığını görürsünüz.
tripleee

10
Aslında onları birleştirmek hala mantıklı, çünkü aksi takdirde kurulum satırını değiştirirseniz, eski paket önbelleğini kullanmaya devam eder, bu da önbellek eskiyse (genellikle dosyalar 404 olacaktır.)
John Chadwick

18

Temel görüntünün güncellemeler için kontrol edilmesi de dahil olmak üzere derlemenizin tamamen yeniden oluşturulduğundan emin olmak için derlerken aşağıdaki seçenekleri kullanın:

--no-cache - Bu, zaten mevcut olan katmanların yeniden oluşturulmasını zorlar

--pull - Bu, FROM kullanılarak referans alınan temel görüntünün çekilmesini tetikler ve en son sürüme sahip olmanızı sağlar.

Bu nedenle tam komut şöyle görünecektir:

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

Docker-compose için aynı seçenekler mevcuttur:

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

13

--no-cacheSizin durumunuzda kullanmanızı tavsiye etmem .

Adım 3'ten 9'a kadar birkaç kurulum yapıyorsunuz (bu arada, tek bir astar kullanmayı tercih ederim) ve görüntünüzü her oluşturduğunuzda bu adımları yeniden çalıştırmanın yükünü istemiyorsanız yapabilirsiniz talimatınızdan Dockerfileönce geçici bir adımla değiştirin wget.

Ben tarafından alınan tarball üzerinde yapılan her modifikasyon için böyle bir şey yapmak RUN ls .ve o RUN ls ./zaman RUN ls ./.ve benzeri değiştirmek için kullanınwget

Elbette her bir yineleme için RUN echo 'test1' > test && rm testsayıyı artırmak gibi bir şey yapabilirsiniz 'test1.

Kirli görünüyor, ancak bildiğim kadarıyla, Docker'ın önbellek sisteminden yararlanmaya devam etmenin en etkili yolu, birçok katmanınız olduğunda zaman kazandırıyor ...


3
Önbelleği belirli bir noktadan sonra kullanamama özelliği, birçok kişi tarafından talep edilen bir özelliktir ( önbellek bozma alternatifleri için bkz. Github.com/moby/moby/issues/1996 )
leszek.hanusz

13

Docker-compose ile deneyin docker-compose up -d --build --force-recreate


5

Buradaki bilgilerin çoğu doğrudur.
Burada bir derleme ve onları kullanma şeklim.

Fikir, önerilen yaklaşıma sadık kalmak (diğer saklanan docker nesneleri üzerinde belirli bir etki oluşturmak ve hiçbir etki yaratmamak) ve yeterli olmadığında daha radikal yaklaşımı (belirli ve diğer saklanan docker nesneleri üzerinde etkisi olmayan) denemektir.

Önerilen yaklaşım:

1) Dockerfile'daki her adımın / talimatın yürütülmesini zorlayın:

docker build --no-cache 

veya docker-compose build:

docker-compose build --no-cache

Bunu uptüm kapsayıcıları yeniden oluşturan alt komutla da birleştirebiliriz :

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

Bu şekilde önbellek kullanılmaz, ancak docker oluşturucu ve FROMtalimatla başvurulan temel görüntü için .

2) Docker builder önbelleğini silin (Buildkit kullanırsak muhtemelen buna ihtiyacımız vardır):

docker builder prune -af

3) Üst görüntülerin önbelleğini kullanmak istemiyorsak, bunları silmeyi deneyebiliriz:

docker image rm -f fooParentImage

Çoğu durumda, bu 3 şey imajımızın temiz bir şekilde oluşturulmasına izin vermek için mükemmeldir.
Bu yüzden buna bağlı kalmalıyız.

Daha radikal bir yaklaşım:

Docker önbelleğindeki bazı nesnelerin derleme sırasında hala kullanıldıkları ve tekrarlanabilir görünen köşe durumlarda, eksik parçayı çok özel bir şekilde silebilmenin nedenini anlamaya çalışmalıyız. Gerçekten sıfırdan yeniden inşa etmek için bir yol bulamazsak, başka yollar da vardır, ancak bunların genellikle gerektiğinden çok daha fazlasını sildiğini hatırlamak önemlidir. Bu nedenle, yerel / geliştirici bir ortamda olmadığımızda onları dikkatli bir şekilde kullanmalıyız.

1) Onlarla ilişkili en az bir kap olmadan tüm görüntüleri kaldırın:

docker image prune -a

2) Daha birçok şeyi kaldırın:

docker system prune -a

Diyor ki:

UYARI! Bu kaldırılacak:
  - durdurulan tüm konteynerler
  - en az bir kapsayıcı tarafından kullanılmayan tüm ağlar
  - en az bir kapsayıcı içermeyen tüm görüntüler
  - hepsi önbellek oluştur

Bu süper silme komutunun kullanılması, kapsayıcıların durumuna (çalışıp çalışmadığına) büyük ölçüde bağlı olduğu için yeterli olmayabilir. Bu komut yeterli olmadığında, hangi docker kaplarının docker yapımızın yan etkilerine neden olabileceğini dikkatlice düşünmeye ve komutla kaldırılmalarına izin vermek için bu kapların çıkmasına izin vermeye çalışıyorum.


3

Oluşturucu önbelleğini aşağıdakilerle yönetebilirsiniz: docker builder

Tüm önbelleği istem olmadan temizlemek için: docker builder prune -af

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.