Programing

Docker가 Dockerfile을 빌드 할 때 RUN npm 설치 지침을 캐시하는 방법

lottogame 2020. 11. 20. 08:26
반응형

Docker가 Dockerfile을 빌드 할 때 RUN npm 설치 지침을 캐시하는 방법


현재 내 애플리케이션을위한 노드 백엔드를 개발 중입니다. 도킹 할 때 (docker build.) 가장 긴 단계는 RUN npm install. RUN npm install명령은 작은 서버 코드 변경 시마다 실행되며 개발자가 매번 빌드가 완료 될 때까지 기다리도록하여 생산성에 영향을줍니다.

응용 프로그램 코드가있는 위치에서 npm 설치를 실행하고 ADD 명령을 사용하여 컨테이너에 node_modules를 추가하면이 문제가 해결되지만 모범 사례와는 거리가 멀습니다. 그것은 Dockerizing에 대한 전체 아이디어를 깨뜨리고 컨테이너의 무게를 훨씬 더 많이 유발합니다.

다른 해결책이 있습니까?


그래서 도커 파일을 작성할 때 효율성에 관한 이 훌륭한 기사를 찾았습니다 .

다음은 RUN npm install명령어 를 실행하기 전에 애플리케이션 코드를 추가하는 잘못된 Docker 파일의 예입니다 .

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"]

응용 프로그램의 사본을 2 개의 COPY 명령 (하나는 package.json 파일 용, 다른 하나는 나머지 파일 용)으로 나누고 실제 코드를 추가하기 전에 npm 설치 명령을 실행하면 코드 변경으로 인해 RUN npm 설치가 트리거되지 않습니다. 지시에 따라 package.json의 변경 만 트리거됩니다. 더 나은 연습 Docker 파일 :

FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>

# 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"]

package.json 파일이 추가되고 종속성을 설치 한 다음 앱이있는 컨테이너 WORKDIR에 복사합니다.

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

모든 도커 빌드에서 npm 설치 단계를 피하려면 해당 행을 복사하고 ^ / opt / app ^를 앱이 컨테이너 내부에있는 위치로 변경하십시오.


기묘한! 아무도 다단계 빌드에 대해 언급하지 않습니다 .

# ---- 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

Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/


I've found that the simplest approach is to leverage Docker's copy semantics:

The COPY instruction copies new files or directories from and adds them to the filesystem of the container at the path .

This means that if you first explicitly copy the package.json file and then run the npm install step that it can be cached and then you can copy the rest of the source directory. If the package.json file has changed, then that will be new and it will re-run the npm install caching that for future builds.

A snippet from the end of a Dockerfile would look like:

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

# install application
COPY     . /usr/app

I imagine you may already know, but you could include a .dockerignore file in the same folder containing

node_modules
npm-debug.log

to avoid bloating your image when you push to docker hub


you don't need to use tmp folder, just copy package.json to your container's application folder, do some install work and copy all files later.

COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app

참고URL : https://stackoverflow.com/questions/35774714/how-to-cache-the-run-npm-install-instruction-when-docker-build-a-dockerfile

반응형