Cara memaksa Docker untuk membangun citra dengan bersih

819

Saya telah membuat gambar Docker dari file Docker menggunakan perintah di bawah ini.

$ docker build -t u12_core -f u12_core .

Ketika saya mencoba untuk membangunnya kembali dengan perintah yang sama, itu menggunakan cache build seperti:

Step 1 : FROM ubuntu:12.04
 ---> eb965dfb09d2
Step 2 : MAINTAINER Pavan Gupta <[email protected]>
 ---> 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

Cache menunjukkan bahwa aerospike diinstal. Namun, saya tidak menemukannya di dalam wadah yang muncul dari gambar ini, jadi saya ingin membangun kembali gambar ini tanpa menggunakan cache. Bagaimana saya bisa memaksa Docker untuk membangun kembali gambar bersih tanpa cache?

Pavan Gupta
sumber
10
Sebagai tambahan, Anda umumnya harus mencoba meminimalkan jumlah RUNarahan.
tripleee
4
@ tripleee Bisakah Anda menjelaskan mengapa?
Ya
9
@Ya. Dulu Docker selalu membuat lapisan terpisah untuk setiap RUNarahan, jadi Dockerfiledengan banyak RUNarahan akan mengkonsumsi jumlah ruang disk yang sangat besar; tetapi ini agaknya telah diperbaiki dalam versi terbaru.
tripleee
Ketika saya mencoba docker-compose up -d, di mana saya bisa menggunakan --no-cache?
Oo
@Oo itu tidak mungkin. Pertama-tama harus Anda lakukan docker-compose build --no-cachedan kemudiandocker-compose up -d
Martin Melka

Jawaban:

1446

Ada --no-cachepilihan:

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

Dalam versi Docker yang lebih lama Anda harus lulus --no-cache=true, tetapi ini tidak lagi terjadi.

Assaf Lavie
sumber
89
Perhatikan juga bahwa --no-cachebekerja dengan docker-compose build.
Blackus
42
Anda mungkin juga ingin menggunakannya --pull. Ini akan memberitahu buruh pelabuhan untuk mendapatkan versi terbaru dari gambar dasar. Ini diperlukan sebagai tambahan --no-cachejika Anda sudah memiliki gambar dasar (contoh:) ubuntu/latestdan gambar dasar telah diperbarui sejak terakhir kali Anda menariknya. Lihat dokumen di sini .
Collin Krawll
2
@CollinKrawll: --pullOpsi melakukan trik untuk saya. Cuma --no-cache, badannya masih rusak. Dimasukkan ke dalam --pulljuga, membangun bekerja! Terima kasih!
Erdős-Bacon
1
Jika seseorang memanggil buruh pelabuhan, bukankah itu diasumsikan bahwa mereka ingin membangun kembali tanpa cache? Dalam kasus penggunaan apa seseorang ingin membuat gambar dan menggunakan gambar yang dibangun sebelumnya? <rant> Saya baru saja kehilangan satu hari karena bangunan sebelumnya gagal diam-diam namun berhasil "berhasil" dan saya menggunakan gambar yang rusak tidak memahami mengapa pembaruan pada skrip pembuatan tidak berfungsi </rant>
Jeff
3
@ Jeff Ketika Anda mengembangkan gambar buruh pelabuhan, buruh pelabuhan hanya akan mengulangi lapisan / langkah yang telah dimodifikasi. Jika saya memiliki lima langkah, dan saya menambahkan langkah baru di indeks 3, lapisan yang terkait dengan langkah 1 dan 2 dapat digunakan kembali. Ini sangat mempercepat proses pengembangan
serpihan
130

Dalam beberapa kasus ekstrem, satu-satunya cara Anda mengatasi kegagalan build berulang adalah dengan menjalankan:

docker system prune

Perintah akan meminta Anda untuk konfirmasi Anda:

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]

Ini tentu saja bukan jawaban langsung untuk pertanyaan itu, tetapi mungkin menyelamatkan beberapa nyawa ... Itu memang menyelamatkan saya.

Wallace Sidhrée
sumber
8
menambahkan -a -f membuatnya lebih baik
Ravi
1
@IulianOnofrei Bekerja untuk saya,Docker version 17.09.0-ce, build afdb6d4
Per Lundberg
1
@ PerLundberg, saya memperbarui dockerke versi yang sama dan berfungsi, terima kasih.
Iulian Onofrei
1
Ini adalah cara yang berlebihan untuk skenario ini dan bukan jawaban yang dapat digunakan jika Anda tidak ingin menghapus semuanya.
M_dk
1
Ini bahkan akan menghapus gambar kontainer yang terhenti, mungkin sesuatu yang tidak Anda inginkan. Docker versi terbaru memiliki perintah docker builder pruneuntuk menghapus lapisan build yang di-cache. Baru saja jatuh ke dalam perangkap setelah menyalin perintah dari stack overflow.
Evil Azrael
59

Perintah itu docker build --no-cache .memecahkan masalah kami yang serupa.

Dockerfile kami adalah:

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

Tetapi seharusnya:

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

Untuk mencegah caching pembaruan dan instal secara terpisah.

Lihat: Praktik terbaik untuk menulis Dockerfiles

Youniteus
sumber
10
"Seharusnya" itu menyesatkan. Jika Docker melihat bahwa ia memiliki salinan cache RUN apt-get update && apt-get -y install php5-fpmAnda masih akan melihatnya digunakan kembali dengan konten yang lama.
tripleee
10
Sebenarnya masih masuk akal untuk bergabung dengan mereka, karena jika tidak, jika Anda mengubah jalur instalasi, ia masih akan menggunakan paket cache lama, yang akan sering mengalami masalah jika cache kedaluwarsa (biasanya, file akan 404.)
John Chadwick
19

Untuk memastikan bahwa bangunan Anda sepenuhnya dibangun kembali, termasuk memeriksa gambar dasar untuk pembaruan, gunakan opsi berikut saat membangun:

--no-cache - Ini akan memaksa pembangunan kembali lapisan yang sudah tersedia

--pull - Ini akan memicu tarikan gambar dasar yang dirujuk menggunakan FROM memastikan Anda mendapatkan versi terbaru.

Perintah penuh akan terlihat seperti ini:

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

Opsi yang sama tersedia untuk komposisi buruh pelabuhan:

docker-compose build --no-cache --pull
M_dk
sumber
13

Saya tidak akan merekomendasikan menggunakan --no-cachedalam kasus Anda.

Anda menjalankan beberapa instalasi dari langkah 3 hingga 9 (saya ingin, lebih suka menggunakan satu liner) dan jika Anda tidak ingin overhead menjalankan kembali langkah-langkah ini setiap kali Anda membangun gambar Anda, Anda dapat modifikasi Anda Dockerfiledengan langkah sementara sebelum wgetinstruksi Anda .

Saya menggunakan untuk melakukan sesuatu seperti RUN ls .dan mengubahnya untuk RUN ls ./saat itu RUN ls ./.dan seterusnya untuk setiap modifikasi yang dilakukan pada tarball diambil olehwget

Tentu saja Anda dapat melakukan sesuatu seperti RUN echo 'test1' > test && rm testmenambah angka 'test1untuk setiap iterasi.

Ini terlihat kotor, tetapi sejauh yang saya tahu itu adalah cara paling efisien untuk terus mendapatkan manfaat dari sistem cache Docker, yang menghemat waktu ketika Anda memiliki banyak lapisan ...

Olivier
sumber
3
Kemampuan untuk tidak dapat menggunakan cache setelah titik tertentu adalah fitur yang diminta oleh banyak orang (lihat github.com/moby/moby/issues/1996 untuk alternatif penghilang cache)
leszek.hanusz
13

Dengan mencoba menulis komposisi buruh pelabuhan docker-compose up -d --build --force-recreate

Yash
sumber
6

Sebagian besar informasi di sini benar.
Berikut kompilasi dari mereka dan cara saya menggunakannya.

Idenya adalah untuk tetap pada pendekatan yang direkomendasikan (membangun spesifik dan tidak berdampak pada objek buruh pelabuhan tersimpan lainnya) dan untuk mencoba pendekatan yang lebih radikal (tidak membangun spesifik dan berdampak pada objek buruh pelabuhan disimpan lainnya) ketika itu tidak cukup.

Pendekatan yang disarankan:

1) Memaksa pelaksanaan setiap langkah / instruksi di Dockerfile:

docker build --no-cache 

atau dengan docker-compose build:

docker-compose build --no-cache

Kita juga bisa menggabungkannya dengan upsub-perintah yang membuat ulang semua kontainer:

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

Cara ini tidak menggunakan cache tetapi untuk pembuat buruh pelabuhan dan gambar dasar yang dirujuk dengan FROMinstruksi.

2) Hapus cache builder buruh pelabuhan (jika kita menggunakan Buildkit, kita mungkin sangat membutuhkannya):

docker builder prune -af

3) Jika kami tidak ingin menggunakan cache dari gambar induk, kami dapat mencoba menghapusnya seperti:

docker image rm -f fooParentImage

Dalam kebanyakan kasus, 3 hal ini cukup sempurna untuk memungkinkan membangun citra kita secara bersih.
Jadi kita harus berusaha untuk tetap pada itu.

Pendekatan yang lebih radikal:

Dalam kasus sudut di mana tampaknya beberapa objek dalam cache buruh pelabuhan masih digunakan selama pembuatan dan yang terlihat berulang, kita harus mencoba memahami penyebabnya untuk dapat menghapus bagian yang hilang dengan sangat spesifik. Jika kita benar-benar tidak menemukan cara untuk membangun kembali dari awal, ada cara lain tetapi penting untuk diingat bahwa ini umumnya menghapus lebih dari yang diperlukan. Jadi kita harus menggunakannya dengan hati-hati secara keseluruhan ketika kita tidak berada di lingkungan lokal / pengembang.

1) Hapus semua gambar tanpa setidaknya satu wadah yang terkait dengannya:

docker image prune -a

2) Hapus banyak hal lagi:

docker system prune -a

Yang mengatakan:

PERINGATAN! Ini akan menghapus:
  - semua kontainer berhenti
  - semua jaringan tidak digunakan oleh setidaknya satu wadah
  - semua gambar tanpa setidaknya satu wadah yang terkait dengannya
  - semua build cache

Menggunakan perintah super delete itu mungkin tidak cukup karena sangat tergantung pada keadaan kontainer (berjalan atau tidak). Ketika perintah itu tidak cukup, saya mencoba untuk berpikir dengan hati-hati wadah buruh pelabuhan mana yang dapat menyebabkan efek samping pada pembuatan buruh pelabuhan kami dan untuk memungkinkan kontainer-kontainer ini dikeluarkan agar memungkinkan mereka untuk dihapus dengan perintah.

davidxxx
sumber
3

Anda dapat mengelola cache builder dengan docker builder

Untuk membersihkan semua cache tanpa prompt: docker builder prune -af

Shawn
sumber