2016-03-03 16 views
32

Attualmente sto sviluppando un back-end Node per la mia applicazione. Durante la fase di ancoraggio (configurazione docker), la fase più lunga è RUN npm install. L'istruzione RUN npm install viene eseguita su ogni piccola modifica del codice del server, influendo sulla produttività facendo in modo che lo sviluppatore attenda che la generazione termini ogni volta.Come memorizzare le istruzioni di installazione RUN npm quando la finestra mobile crea un file Docker

Ho scoperto che l'esecuzione di npm in cui il codice dell'applicazione è attivo e l'aggiunta di node_modules al contenitore con l'istruzione ADD risolve questo problema, , ma è ben lontano dalle migliori pratiche. In qualche modo rompe l'idea di metterlo in pratica e fa pesare molto più il contenitore.

Qualsiasi altra soluzione?

risposta

66

Ok, quindi ho trovato l'efficienza this great article durante la scrittura di un file di finestra mobile.

Questo è un esempio di un file di finestra mobile cattivo aggiungendo il codice dell'applicazione prima di eseguire l'istruzione di RUN npm install:

FROM ubuntu 

RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list 
RUN apt-get update 
RUN apt-get -y install python-software-properties git build-essential 
RUN add-apt-repository -y ppa:chris-lea/node.js 
RUN apt-get update 
RUN apt-get -y install nodejs 

WORKDIR /opt/app 

COPY . /opt/app 
RUN npm install 
EXPOSE 3001 

CMD ["node", "server.js"] 

Dividendo la copia della domanda in 2 istruzioni di copia (una per il file package.json e l'altro per il resto dei file) ed eseguendo le istruzioni di installazione di npm prima di aggiungere il codice effettivo, qualsiasi modifica del codice non attiverà l'istruzione di installazione di RUN npm, solo le modifiche di package.json lo attiveranno. Better File pratica finestra mobile:

FROM ubuntu 
MAINTAINER David Weinstein <[email protected]> 

# install our dependencies and nodejs 
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list 
RUN apt-get update 
RUN apt-get -y install python-software-properties git build-essential 
RUN add-apt-repository -y ppa:chris-lea/node.js 
RUN apt-get update 
RUN apt-get -y install nodejs 

# use changes to package.json to force Docker not to use the cache 
# when we change our application's nodejs dependencies: 
COPY package.json /tmp/package.json 
RUN cd /tmp && npm install 
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/ 

# From here we load our application's code in, therefore the previous docker 
# "layer" thats been cached will be used if possible 
WORKDIR /opt/app 
COPY . /opt/app 

EXPOSE 3000 

CMD ["node", "server.js"] 

Questo è dove aggiunto il file package.json, installare le sue dipendenze e copiarli nel WORKDIR contenitore, in cui l'applicazione vive:

ADD package.json /tmp/package.json 
RUN cd /tmp && npm install 
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/ 

Per evitare installare il NPM fase su ogni build di finestra mobile copia semplicemente quelle righe e modifica ^/opt/app^nella posizione in cui la tua app vive all'interno del contenitore.

+2

che funziona. Alcuni punti però. 'ADD' è scoraggiato in favore di' COPY', afaik. 'COPY' è ancora più efficace.IMO, gli ultimi due paragrafi non sono necessari, dal momento che sono duplicati e anche dal punto di vista dell'app non importa dove sul filesystem risiede l'app, purché sia ​​impostato 'WORKDIR'. – eljefedelrodeodeljefe

+2

È ancora meglio combinare tutti i comandi apt-get su un RUN, incluso un 'apt-get clean'. Inoltre, aggiungi ./node_modules al tuo .dockerignore, per evitare di copiare la tua directory di lavoro nel tuo contenitore creato e per accelerare il passo di copia del contesto build del build. – Symmetric

+0

Per quale motivo si esegue il comando di copia in un RUN separato? E importa se sposto il pacchetto node_modules invece di copiarlo? Perché potrebbe diventare relativamente grande a seconda di quanto si installa –

2

immagino si può già sapere, ma si potrebbe includere un file .dockerignore nella stessa cartella contenente

node_modules 
npm-debug.log 

per evitare il gonfiore vostra immagine quando si preme a finestra mobile hub

5

ho trovato che l'approccio più semplice è sfruttare la semantica della copia di Docker:

L'istruzione COPY copia nuovi file o directory da e li aggiunge al file system del contenitore nel percorso.

Questo significa che prima se si copia il file in modo esplicito package.json e quindi eseguire il passo npm install che può essere memorizzato nella cache e quindi è possibile copiare il resto della directory di origine. Se il file package.json è stato modificato, allora sarà nuovo e verrà eseguita nuovamente la cache di installazione di npm per le build future.

un frammento dalla fine di un Dockerfile sarà simile:

# install node modules 
COPY package.json /usr/app/package.json 
RUN cd /usr/app && npm install 

# install application 
COPY . /usr/app 
Problemi correlati