bardzo duży kontekst budowania dla obrazu Dockera

166

Utworzyłem kilka różnych katalogów na moim komputerze-hoście, próbując poznać Docker tylko po to, aby moje pliki dockerowe były uporządkowane. Mój plik Dockerfile, który właśnie uruchomiłem, wygląda następująco:

FROM crystal/centos
MAINTAINER crystal

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

Moje rzeczywiste obroty to tylko 1 GB. Ale kiedy próbuję to zrobić sudo docker build -t="crystal/test" ., wysyłam kontekst kompilacji do demona Dockera o pojemności 3,5 GB. Czy jest coś jeszcze, czego nie jestem świadomy, gdy nadal tworzysz obrazy Dockera? Czy moja pamięć gromadzi się, gdy tworzę więcej obrazów w innych katalogach na moim komputerze głównym?

Kryształ
źródło
3
Kontekst budowania to wszystkie pliki / katalogi w bieżącym katalogu.
Nabin
1
W tym katalogu przechowuj tylko pliki potrzebne do kompilacji. Oznacza to, że plik Dockerfile i wszelkie lokalne pliki / katalogi skopiowane / dodane do obrazu kompilacji w pliku Dockerfile. Skorzystaj również z.dockerignore
Vishrant

Odpowiedzi:

304

Klient platformy Docker wysyła cały „kontekst kompilacji” do demona platformy Docker. Ten kontekst budowania (domyślnie) to cały katalog, w którym się Dockerfileznajduje (czyli całe rpmsdrzewo).

Możesz skonfigurować .dockerignoreplik, aby Docker ignorował niektóre pliki. Możesz z tym poeksperymentować.

Alternatywnie, możesz przenieść swój rpmsfolder o jeden poziom wyżej niż twój Dockerfilei tylko symboliczne łącze test.rpmdo Dockerfilekatalogu.


Często będziesz chciał dodać .gitfolder do folderu,.dockerignore który był przyczyną różnicy 150 MB -> 5 GB dla niektórych użytkowników w komentarzach tutaj.

Thomas Orozco
źródło
4
Niestety wydaje się, że w tym przypadku dowiązanie symboliczne nie jest możliwe, ponieważ ADDpolecenie nie podąża za dowiązaniami symbolicznymi podczas kompilacji. Zobacz: github.com/docker/docker/issues/1676
JimmidyJoo
5
ratownik! Programiści Rails: pamiętaj, aby dodać tmp logdo .dockerignore+ innych niestandardowych
odpowiednik8
8
nie zapomnij dodać folderu .git do pliku .dockerignore (zakładając, że używasz git)
dsncode
8
Tak, .gitfolder jest dołączony domyślnie - to zdecydowanie mnie zaskoczyło.
Paul Suart
1
Czym dokładnie jest „kontekst budowania”? Próbowałem znaleźć te pliki za pomocą polecenia Docker build RUN, ale nie widzę plików w moim folderze Dockerfile w systemie plików Docker (w czasie kompilacji). Czy ktoś może mi podać prosty przykład przydatności kontekstu kompilacji?
Patrick,
65

Zaktualizuj 2019

Począwszy od wersji Docker 18.06 istnieje możliwość użycia nowego narzędzia do tworzenia obrazów o nazwie Build Kit .

Jest wstępnie dołączony do Dockera, nie trzeba niczego instalować. Jest wstecznie zgodny ze Dockerfileskładnią, nie trzeba zmieniać rozszerzenia Dockerfile.

Legacy Docker Build vs New Docker BuildKit

Oto przykład budowania obrazu z ogromnym nieużywanym plikiem w katalogu kompilacji:

Starsza kompilacja platformy Docker:

$ 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

Nowy zestaw Docker BuildKit:

$ 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

Jedyną zmianą jest DOCKER_BUILDKIT=1zmienna środowiskowa, różnica w czasie jest ogromna.

.dockerignore Plik

Należy pamiętać, że .dockerignoreplik jest nadal aktualny i przydatny. Niektóre Dockerfilepolecenia, takie jak COPY . ., nadal będą uwzględniać .dockerignorezasady. Ale pliki poboczne w katalogu kompilacji (nie Dockerfileprzywoływane w ) nie są już kopiowane jako „kontekst kompilacji” przez BuildKit.

Andriy Berestovskyy
źródło
2
Należy zauważyć, że DOCKER_BUILDKIT nie jest obecnie obsługiwany dla kontenerów systemu Windows. (Tylko Linux, wymienione z ograniczeniami: docs.docker.com/develop/develop-images/build_enhancements )
Vaccano,
Działa na macOS 10.15 od 2020-09-05!
LexH
Wydaje się to nieszczere; buildkit nadal wysyła najpierw kontekst kompilacji. Jak dokładnie kontekst kompilacji przeszedł z 4,3 GB do ?? B i 0 po włączeniu tej opcji? Ponieważ to nie jest moje doświadczenie; Przesłałem ten sam rozmiar kontekstu: => [internal] load build context => => transferring context: 924.39MB 86.3stylko [...]linie, które powinny pokazywać 4,3 GB przynajmniej przy pierwszym uruchomieniu. Przyznane za drugim razem, nie przenosi kontekstu, czego wszyscy potrzebowaliśmy.
dlamblin
@dlamblin pls zobacz .dockerignoresekcję odpowiedzi: BuildKit nie kopiuje już plików pobocznych w katalogu kompilacji (nie ma odniesienia w pliku Dockerfile). Zwykle tak jest, ale twoje doświadczenia mogą się różnić;)
Andriy Berestovskyy
1
Widzę; miałeś niepotrzebne pliki w kontekście kompilacji, a ja miałem prawie 1 GB niezbędnych plików. Teraz ... buildkit JEST DUŻO LEPSZY. Nie przesyła ponownie plików do buforowanej odbudowy awarii i najwyraźniej przenosi tylko potrzebne pliki (jak
wskazałeś
17

Naprawiłem to, przenosząc mój plik Dockerfile i docker-compose.yml do podfolderu i działało świetnie. Najwyraźniej docker wysyła bieżący folder do demona, a mój folder to 9 gigów.

Emad
źródło
5
Ta metoda podaje Forbidden path: błąd poza kontekstem kompilacji, jeśli kopiowany jest plik z katalogu nadrzędnego, czy jest jakieś rozwiązanie tego problemu?
Kitwradr
9

Jeśli masz .dockerignoreplik, a kontekst kompilacji jest nadal duży, możesz sprawdzić, co jest wysyłane do kontekstu kompilacji platformy Docker za pomocą programu The Silver Searcher :

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

Zwróć uwagę, że niektóre **wzorce mogą nie działać poprawnie.

Zobacz ten numer Github, aby uzyskać dodatkowe komentarze: https://github.com/moby/moby/issues/16056

Luís Bianchin
źródło
4

W moim przypadku było to wtedy, gdy -fwykonuję z niewłaściwymi argumentami - bez ścieżki do katalogu, w którym znajduje się plik Dockerfile

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

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

FreeStyler
źródło
1

Jeśli chcesz mieć pełną kontrolę nad kontekstem kompilacji, możesz później zbudować kontener całkowicie bez kontekstu i COPYodpowiednich danych.

docker build - < Dockerfile

Jedynym minusem tego byłoby to, że przy takim podejściu można to zrobić tylko ADD rzeczy w pliku docker odwoływać się do zdalnego adresu URL, a nie pliki z lokalnego hosta.

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

Christian D.
źródło
0

Miałem ten sam problem co FreeStyler. Jednak budowałem z katalogu jeden w górę z mojego kontekstu. Więc argumenty -f były poprawne, kontekst był nieprawidłowy.

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

Budowanie z katalogu docker-dir było w porządku

docker build -t br_base:0.1 . 

Budowanie z dock-dir zmienił się kontekst budowania. Dlatego musiałem zmienić kontekst w poleceniu. Kontekst jest określony przez „.” w powyższym poleceniu.

Nowa komenda z katalogu projektu powinna brzmieć

docker build -t br_base:0.1 ./base

Kontekst jest tutaj określony przez „./base”

BravoRomeo23
źródło
0

jeśli tworzysz obraz i otrzymujesz wiadomość wysyłającą kontekst kompilacji do demona Dockera którego skopiowanie zajmuje czas w logu,

następnie dodaj plik .dockerignore . powinien zawierać pliki lub katalog, których nie trzeba kopiować.

Shashikant Pandit
źródło
0

W przypadku NodeJS ApplicationDodaj .dockerignoreplik do katalogu głównego projektu i wewnątrz .dockerignorepliku dodaj następujące elementy

node_modules
dist
Bernard Nongpoh
źródło
-1

Podsumowując, co możesz zrobić, jeśli kontekst kompilacji obrazu platformy Docker jest zbyt duży:

  • upewnij się, że nie masz nieużywanych plików w kontekście (nieużywane pliki - te, które wciąż są nietykalne podczas budowania obrazu);
  • dodaj nieużywane pliki i / lub katalogi do .dockerignore (jak wspomniano tutaj );
  • upewnij się, że określasz właściwy folder jako kontekst budowania obrazu (jak wspomniano tutaj );
  • spróbuj użyć BuildKit z DOCKER_BUILDKIT = 1 (jak wspomniano tutaj );
  • spróbuj podzielić projekt na mniejsze części, aby zoptymalizować zawartość kontekstu kompilacji;
  • jeśli masz złożony projekt, możesz chcieć ręcznie zebrać wszystkie niezbędne pliki w oddzielnym folderze przed kompilacją i użyć ich jako kontekstu kompilacji dla określonego obrazu.
Alexander Salykin
źródło