Ok, encontré este gran artículo sobre la eficiencia al escribir un archivo de ventana acoplable.
Este es un ejemplo de un archivo docker incorrecto que agrega el código de la aplicación antes de ejecutar la RUN npm install
instrucción:
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"]
Al dividir la copia de la aplicación en 2 instrucciones COPY (una para el archivo package.json y la otra para el resto de los archivos) y ejecutar la instrucción de instalación npm antes de agregar el código real, cualquier cambio de código no activará la instalación de RUN npm instrucción, solo los cambios del package.json lo activarán. Archivo acoplable de mejores prácticas:
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"]
Aquí es donde se agregó el archivo package.json, instale sus dependencias y cópielas en el contenedor WORKDIR, donde reside la aplicación:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
Para evitar la fase de instalación de npm en cada compilación de la ventana acoplable, simplemente copie esas líneas y cambie ^ / opt / app ^ a la ubicación de su aplicación dentro del contenedor.
ADD
se desanima a favor deCOPY
, afaik.COPY
es aún más eficaz. En mi opinión, los dos últimos párrafos no son necesarios, ya que son duplicados y también desde el punto de vista de la aplicación, no importa en qué parte del sistema de archivos viva la aplicación, siempre queWORKDIR
esté configurado.apt-get clean
. Además, agregue ./node_modules a su .dockerignore, para evitar copiar su directorio de trabajo en su contenedor construido y para acelerar el paso de copia de contexto de compilación de la compilación.package.json
a la posición de descanso final, también funciona bien (eliminando cualquier cp / mv).¡Extraño! Nadie menciona la construcción de varias etapas .
# ---- Base Node ---- FROM alpine:3.5 AS base # install node RUN apk add --no-cache nodejs-current tini # set working directory WORKDIR /root/chat # Set tini as entrypoint ENTRYPOINT ["/sbin/tini", "--"] # copy project file COPY package.json . # # ---- Dependencies ---- FROM base AS dependencies # install node packages RUN npm set progress=false && npm config set depth 0 RUN npm install --only=production # copy production node_modules aside RUN cp -R node_modules prod_node_modules # install ALL node_modules, including 'devDependencies' RUN npm install # # ---- Test ---- # run linters, setup and tests FROM dependencies AS test COPY . . RUN npm run lint && npm run setup && npm run test # # ---- Release ---- FROM base AS release # copy production node_modules COPY --from=dependencies /root/chat/prod_node_modules ./node_modules # copy app sources COPY . . # expose port and define CMD EXPOSE 5000 CMD npm run start
Impresionante tuto aquí: https://codefresh.io/docker-tutorial/node_docker_multistage/
fuente
COPY
declaración despuésENTRYPOINT
?Descubrí que el enfoque más simple es aprovechar la semántica de copia de Docker:
Esto significa que si primero copia explícitamente el
package.json
archivo y luego ejecuta elnpm install
paso, se puede almacenar en caché y luego puede copiar el resto del directorio de origen. Si elpackage.json
archivo ha cambiado, será nuevo y volverá a ejecutar el almacenamiento en caché de npm install para futuras compilaciones.Un fragmento del final de un Dockerfile se vería así:
fuente
cd /usr/app
puede / debe usarWORKDIR /usr/app
./usr/app
dentro de la imagen que creará una/usr/app/node_modules
con las dependencias instaladas desde npm install.COPY . /usr/app
volvería a copiar elpackage.json
archivo/usr/app
con el resto de los archivos?Imagino que ya lo sabe, pero podría incluir un archivo .dockerignore en la misma carpeta que contiene
para evitar que la imagen se hinche cuando empuja al hub de Docker
fuente
no necesita usar la carpeta tmp, simplemente copie package.json en la carpeta de la aplicación de su contenedor, haga un trabajo de instalación y copie todos los archivos más tarde.
fuente