costruire un contesto per l'immagine docker molto grande


142

Ho creato un paio di directory diverse sul mio computer host mentre provo a conoscere Docker solo per organizzare i miei file docker. Il mio Dockerfile che ho appena eseguito è simile al seguente:

FROM crystal/centos
MAINTAINER crystal

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

Il mio numero di giri effettivo è solo 1 GB. Ma quando provo a farlo sudo docker build -t="crystal/test" ., ricevo l'invio di un contesto di build al daemon Docker da 3,5 GB. C'è qualcos'altro di cui non sono a conoscenza mentre continui a creare immagini Docker? La mia memoria si sta accumulando mentre creo più immagini nelle mie altre directory sul mio computer host?


2
Il contesto di compilazione è costituito da tutti i file / directory nella directory corrente.
Nabin,

Conservare solo i file necessari per la compilazione in questa directory. Cioè, il Dockerfile e tutti i file / directory locali copiati / aggiunti all'immagine di build nel Dockerfile. Inoltre, usa.dockerignore
Vishrant l'

Risposte:


266

Il client Docker invia l'intero "contesto di compilazione" al demone Docker. Tale contesto di compilazione (per impostazione predefinita) è l'intera directory in cui si Dockerfiletrova (quindi l'intero rpmsalbero).

È possibile impostare un .dockerignorefile per fare in modo che Docker ignori alcuni file. Potresti voler sperimentare con esso.

In alternativa, puoi spostare la rpmscartella di un livello di directory sopra la tua Dockerfilee solo link simbolico test.rpmnella Dockerfiledirectory di.


Come molti utenti hanno sottolineato nei commenti, è necessario aggiungere la .gitcartella alla.dockerignore quale era la causa di una differenza di 150 MB -> 5 GB nel mio caso.


4
Sfortunatamente sembra che in questo caso il ADDcollegamento simbolico non sia possibile poiché il comando non segue i collegamenti simbolici durante una compilazione. Vedi: github.com/docker/docker/issues/1676
JimmidyJoo,

5
salvavita ! Sviluppatori di Rails: assicurati di aggiungere tmp loga .dockerignore+ altri personalizzati
equivalente8

7
non dimenticare di aggiungere la cartella .git al file .dockerignore (supponendo che tu stia usando git)
dsncode

8
Sì, la .gitcartella è inclusa per impostazione predefinita - questo mi ha sicuramente sorpreso.
Paul Suart,

1
Qual è esattamente il "contesto di costruzione"? Ho provato a cercare questi file usando il comando RUN build docker, ma non vedo i file nella mia cartella Dockerfile all'interno del filesystem docker (durante il tempo di compilazione). Qualcuno può darmi un semplice esempio di come sia utile il contesto build?
Patrick,

52

Aggiornamento 2019

A partire da Docker v18.06 è disponibile un'opzione per utilizzare un nuovo generatore di immagini chiamato Build Kit .

È pre-raggruppato con Docker, non è necessario installare nulla. È retrocompatibile con la Dockerfilesintassi, non è necessario modificarlo Dockerfile.

Legacy Docker Build vs New Docker BuildKit

Ecco un esempio di costruzione di un'immagine con un enorme file inutilizzato nella directory di 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

Nuovo 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

L'unica modifica è la DOCKER_BUILDKIT=1variabile d'ambiente, la differenza nel tempo è enorme.

.dockerignore File

Si noti che il .dockerignorefile è ancora valido e utile. Alcuni Dockerfilecomandi simili COPY . .terranno comunque conto delle .dockerignoreregole. Ma i file laterali nella directory di build (non citati in Dockerfile) non vengono più copiati come "contesto di build" da BuildKit.


1
È importante notare che DOCKER_BUILDKIT non è attualmente supportato per i contenitori di Windows. (Solo Linux, elencato sotto le limitazioni: docs.docker.com/develop/develop-images/build_enhancements )
Vaccano

18

L'ho risolto spostando il mio Dockerfile e docker-compose.yml in una sottocartella e funzionava benissimo. Apparentemente la finestra mobile invia la cartella corrente al demone e la mia cartella era di 9 concerti.


4
Questo metodo fornisce il percorso proibito: al di fuori dell'errore del contesto di compilazione se viene copiato un file da una directory padre, qualche soluzione per questo?
Kitwradr,

8

Se hai un .dockerignorefile e il contesto di compilazione è ancora grande, puoi controllare cosa viene inviato al contesto di compilazione della finestra mobile usando Silver Searcher :

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

Si noti che alcuni **motivi potrebbero non funzionare correttamente.

Vedi questo numero di Github per ulteriori commenti: https://github.com/moby/moby/issues/16056


4

Nel mio caso è stato quando -feseguo con argomenti sbagliati - senza percorso alla directory in cui si trova Dockerfile

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

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


1

Se si desidera avere il pieno controllo del contesto di compilazione, è possibile anche creare il contenitore completamente senza alcun contesto e COPYdati rilevanti nel contenitore in seguito.

docker build - < Dockerfile

Un ADDaspetto negativo di questo sarebbe che con questo approccio è possibile solo cose nel file docker che fanno riferimento a un URL remoto e non file dall'host locale.

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


0

Ho avuto lo stesso problema di FreeStyler. Comunque stavo costruendo da una directory una dal mio contesto. Quindi gli argomenti -f erano corretti, il contesto era errato.

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

Costruendo dalla docker-dir il seguente andava bene

docker build -t br_base:0.1 . 

Costruendo dal dock-dir il contesto di compilazione è cambiato. Pertanto, avevo bisogno di cambiare il contesto nel comando. Il contesto è dato dal '.' nel comando sopra.

Il nuovo comando dalla directory del progetto dovrebbe essere

docker build -t br_base:0.1 ./base

Il contesto qui è dato dal './base'


0

se si sta creando un'immagine e si sta ricevendo un messaggio che invia il contesto di compilazione al demone docker che richiede tempo di log per la copia,

quindi aggiungere il file .dockerignore . dovrebbe includere i file o la directory che non devono essere copiati.


0

Per NodeJS Application, aggiungere un .dockerignorefile nella directory del progetto principale e all'interno del .dockerignorefile aggiungere quanto segue

node_modules
dist
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.