membangun konteks untuk gambar buruh pelabuhan sangat besar

142

Saya telah membuat beberapa direktori berbeda di mesin host saya ketika saya mencoba untuk belajar tentang Docker hanya untuk menjaga dockerfiles saya terorganisir. Dockerfile saya yang baru saja saya jalankan terlihat seperti ini:

FROM crystal/centos
MAINTAINER crystal

ADD ./rpms/test.rpm ./rpms/ 
RUN yum -y --nogpgcheck localinstall /rpms/test.rpm 

Rpm saya yang sebenarnya hanya 1 GB. Tetapi ketika saya mencoba melakukannya sudo docker build -t="crystal/test" ., saya mendapatkan mengirimkan konteks build ke Docker daemon 3.5 GB. Apakah ada hal lain yang saya tidak sadari ketika Anda terus membangun gambar Docker? Apakah memori saya terakumulasi ketika saya membuat lebih banyak gambar di direktori saya yang lain di mesin host saya?

Kristal
sumber
2
Konteks build adalah semua file / direktori dalam direktori saat ini.
Nabin
Simpan hanya file yang Anda perlukan untuk membangun di direktori ini. Yaitu, Dockerfile dan semua file / direktori lokal disalin / ditambahkan ke build image di Dockerfile. Juga, manfaatkan.dockerignore
Vishrant

Jawaban:

266

Klien Docker mengirim seluruh "membangun konteks" ke daemon Docker. Konteks build itu (secara default) adalah seluruh direktori yang Dockerfileada di dalamnya (jadi, seluruh rpmspohon).

Anda dapat mengatur .dockerignorefile untuk membuat Docker mengabaikan beberapa file. Anda mungkin ingin bereksperimen dengannya.

Atau, Anda dapat memindahkan rpmsfolder satu tingkat direktori Anda di atas Dockerfile, dan hanya symlink test.rpmke Dockerfiledirektori.


Seperti banyak pengguna tunjukkan dalam komentar, seseorang perlu menambahkan .gitfolder.dockerignore yang merupakan penyebab perbedaan 150MB -> 5GB dalam kasus saya.

Thomas Orozco
sumber
4
Sayangnya sepertinya symlinking tidak dimungkinkan dalam kasus ini karena ADDperintah tidak mengikuti sym sym selama build. Lihat: github.com/docker/docker/issues/1676
JimmidyJoo
5
penyelamat! Rel pengembang: pastikan untuk menambahkan tmp logke .dockerignore+ yang kustom lainnya
equivalent8
7
jangan lupa menambahkan folder .git ke file .dockerignore (dengan asumsi Anda menggunakan git)
dsncode
8
Yap, .gitfolder disertakan secara default - ini pasti membuat saya ketahuan.
Paul Suart
1
Apa sebenarnya "membangun konteks" itu? Saya mencoba mencari file-file ini menggunakan perintah build galat RUN, tetapi saya tidak melihat file di folder Dockerfile saya di dalam sistem file docker (selama waktu pembangunan.) Dapatkah seseorang tolong beri saya contoh sederhana bagaimana membangun konteks berguna?
Patrick
52

Perbarui 2019

Mulai dari Docker v18.06 ada opsi untuk menggunakan pembuat gambar baru yang disebut Build Kit .

Sudah dipaket sebelumnya dengan Docker, tidak perlu menginstal apa pun. Ini kompatibel dengan Dockerfilesintaks, tidak perlu mengubah Dockerfile.

Builder Docker Legacy vs Builder Docker Baru

Berikut adalah contoh membangun gambar dengan file besar yang tidak digunakan di direktori build:

Legacy Docker Build:

$ time docker image build --no-cache .
Sending build context to Docker daemon  4.315GB
[...]
Successfully built c9ec5d33e12e

real    0m51.035s
user    0m7.189s
sys 0m10.712s

BuildKit Docker Baru:

$ time DOCKER_BUILDKIT=1 docker image build --no-cache .
[+] Building 0.1s (5/5) FINISHED                                                
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 37B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
[...]
 => => writing image sha256:ba5bca3a525ac97573b2e1d3cb936ad50cf8129eedfa9  0.0s

real    0m0.166s
user    0m0.034s
sys 0m0.026s

Satu-satunya perubahan adalah DOCKER_BUILDKIT=1variabel lingkungan, perbedaan waktu sangat besar.

.dockerignore Mengajukan

Harap dicatat, bahwa .dockerignorefile tersebut masih valid dan bermanfaat. Beberapa Dockerfileperintah seperti COPY . .masih akan mempertimbangkan .dockerignoreaturan. Tetapi file sisi dalam direktori build (tidak direferensikan dalam Dockerfile) tidak disalin lagi sebagai "membangun konteks" oleh BuildKit.

Andriy Berestovskyy
sumber
1
Penting untuk dicatat bahwa DOCKER_BUILDKIT saat ini tidak didukung untuk Windows Containers. (Hanya Linux, Tercantum dalam batasan: docs.docker.com/develop/develop-images/build_enhancements )
Vaccano
18

Saya memperbaikinya dengan memindahkan Dockerfile dan docker-compose.yml ke subfolder dan berfungsi dengan baik. Rupanya buruh pelabuhan mengirim folder saat ini ke daemon dan folder saya adalah 9 gigs.

Emad
sumber
4
Metode ini memberikan jalur terlarang: di luar kesalahan konteks pembangunan jika file dari direktori induk disalin, ada solusi untuk ini?
Kitwradr
8

Jika Anda memiliki .dockerignorekonteks file dan build masih besar, Anda dapat memeriksa apa yang sedang dikirim ke konteks build docker menggunakan The Silver Searcher :

ag --path-to-ignore .dockerignore --files-with-matches

Perhatikan bahwa beberapa **pola mungkin tidak berfungsi dengan baik.

Lihat masalah Github ini untuk komentar tambahan: https://github.com/moby/moby/issues/16056

Luís Bianchin
sumber
4

Dalam kasus saya saat itulah saya mengeksekusi dengan -fargumen yang salah - tanpa path ke direktori di mana terletak Dockerfile

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile /home/DF/ - Baik

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile - salah

FreeStyler
sumber
1

Jika Anda ingin memegang kendali penuh atas konteks pembuatan Anda, Anda juga bisa membuat wadah sepenuhnya tanpa konteks apa pun dan COPYdata yang relevan ke dalam wadah sesudahnya.

docker build - < Dockerfile

Satu kelemahan dari ini adalah bahwa dengan pendekatan ini Anda hanya dapat melihat ADDhal-hal di dockerfile merujuk ke URL jarak jauh, dan bukan file dari host lokal Anda.

Lihat https://docs.docker.com/engine/reference/commandline/build/#build-with--

Christian
sumber
0

Saya memiliki masalah yang sama dengan FreeStyler. Namun saya membangun dari direktori satu dari konteks saya. Jadi argumen -f benar konteksnya salah.

project 
|
-------docker-dir 

Bangunan dari docker-dir berikut ini baik-baik saja

docker build -t br_base:0.1 . 

Membangun dari dock-dir konteks build berubah. Karena itu saya perlu mengubah konteks dalam perintah. Konteks diberikan oleh '.' dalam perintah di atas.

Perintah baru dari direktori proyek seharusnya

docker build -t br_base:0.1 ./base

Konteks di sini diberikan oleh './base'

BravoRomeo23
sumber
0

jika Anda membuat gambar dan mendapatkan konteks pengiriman pesan ke daemon docker yang memerlukan waktu log untuk menyalin,

kemudian tambahkan file .dockerignore . itu harus menyertakan file atau direktori yang tidak perlu disalin.

Pandit Shashikant
sumber
0

Untuk NodeJS Application, tambahkan .dockerignorefile direktori proyek root Anda dan di dalam .dockerignorefile tambahkan berikut ini

node_modules
dist
Bernard Nongpoh
sumber