Riduci la dimensione del contenitore docker costruito con nix

Sto imballando l'applicazione python in docker con il dockerTools di nix e tutto è buono tranne la dimensione dell'image. Python è di circa 40 MB e se aggiungi numpy e pandas sarebbe poche centinaia di megabyte, mentre il codice applicativo è solo ~ 100 KB.

L'unica soluzione che vedo è confezionare le dependencies in un'image separata e poi ereditarne quella principale, non correggerà la dimensione, ma alless non avrò bisogno di trasferire immagini enormi su each commit. Inoltre non so come farlo, devo usare un'image con nix o creare ambiente con pythonPackages.buildEnv e albind la mia app?

Sarebbe bello avere una soluzione generica, ma il pitone specifico sarebbe buono. Anche se hai una soluzione imperfetta, ti invitiamo a condividere.

Ok, con fromImage attributo da buildImage per buildImage ho diviso un livello enorme in un enorme livello di dipendenza e un piccolo livello di codice app. Mi chiedo se c'è un modo per spostare questo strato di dipendenza dal grasso in un'image separata, quindi potrei condividerla tra i miei altri progetti?

Non c'è bisogno di confezionare le dependencies in un'image separata e di ereditarle, anche se ciò non può fare del male.

Tutto quello che devi fare è assicurarsi di aggiungere il codice dell'applicazione come uno degli ultimi passaggi del Dockerfile. Ogni command avrà un proprio livello, quindi se si modifica solo il codice dell'applicazione, tutti i livelli sopra tale modifica possono essere utilizzati dalla cache.

Esempio dalla documentazione Docker Images e Layers :

Il file del docker

 FROM ubuntu:15.10 COPY . /app RUN make /app CMD python /app/app.py 

contiene quattro livelli distinti. Se si modifica solo l'ultima row, solo quel livello e tutti i livelli sottostanti dovranno essere trasferiti. Quando si spinge o si tira vedrà 4b0ba2c4050a: Already exists accanto ai livelli utilizzati dalla cache. Seguendo questo approccio non si finisce con un'image più piccola, ma, come si dice, non è necessario tirare grandi immagini su each modifica.

Dopo un po 'di googling e dockerTools codice dockerTools lettura ho finito con questa soluzione:

 let deps = pkgs.dockerTools.buildImage { name = "deps"; content = [ list of all deps here ]; }; in pkgs.dockertools.buildImage { name = "app"; fromImage = deps; } 

Questo creerà un'image docker a due livelli, una delle quali sarebbe dependencies, altra è app. Sembra anche che il valore da fromImage potrebbe essere il risultato di pullImage che dovrebbe dare lo stesso risultato (se ho capito correttamente il codice), ma non sono stato in grado di controllarlo.