programing

도커 구성: npm 설치 성공 후 볼륨에 node_modules가 없음

magicmemo 2023. 5. 26. 20:50
반응형

도커 구성: npm 설치 성공 후 볼륨에 node_modules가 없음

다음과 같은 서비스를 제공하는 앱이 있습니다.

  • web/포트 5000에서 파이썬 3 플라스크 웹 서버를 보유하고 실행합니다.sqlite3을 사용합니다.
  • worker/을 가지고 있습니다.index.js대의작업파인일웹다니. API over port를 하여 이 와 상호 합니다.9730작업자는 redis를 저장용으로 사용합니다. 작업자는 합니다.worker/images/

이 은 이제이질오직은문과 이 있을 뿐입니다.worker.

worker/Dockerfile

FROM node:0.12

WORKDIR /worker

COPY package.json /worker/
RUN npm install

COPY . /worker/

docker-compose.yml

redis:
    image: redis
worker:
    build: ./worker
    command: npm start
    ports:
        - "9730:9730"
    volumes:
        - worker/:/worker/
    links:
        - redis

가 행할때실을 할 때.docker-compose build은 NPM에 됩니다./worker/node_modules역시

npm WARN package.json unfold@1.0.0 No README data

> phantomjs@1.9.2-6 install /worker/node_modules/pageres/node_modules/screenshot-stream/node_modules/phantom-bridge/node_modules/phantomjs
> node install.js

<snip>

하지만 내가 할 때는docker-compose up다음 오류가 표시됩니다.

worker_1 | Error: Cannot find module 'async'
worker_1 |     at Function.Module._resolveFilename (module.js:336:15)
worker_1 |     at Function.Module._load (module.js:278:25)
worker_1 |     at Module.require (module.js:365:17)
worker_1 |     at require (module.js:384:17)
worker_1 |     at Object.<anonymous> (/worker/index.js:1:75)
worker_1 |     at Module._compile (module.js:460:26)
worker_1 |     at Object.Module._extensions..js (module.js:478:10)
worker_1 |     at Module.load (module.js:355:32)
worker_1 |     at Function.Module._load (module.js:310:12)
worker_1 |     at Function.Module.runMain (module.js:501:10)

에 존재하는 모듈이 없는 것으로 나타났습니다./worker/node_modules(호스트 또는 컨테이너에 있음).

호스트에 있는 경우, 저는npm install그러면 모든 것이 잘 작동합니다.하지만 저는 그렇게 하고 싶지 않아요.컨테이너가 종속성을 처리하기를 원합니다.

여기서 무슨 일이 일어나고 있습니까?

할 필요 , 패키지는 (물론모패는지키든)에 있습니다.package.json.)

이 당신의 사자가이문발생다합니가제를 합니다.worker의 으로서의 디렉토리docker-compose.yml볼륨이 빌드 중에 마운트되지 않기 때문입니다.

도가이를빌때드할미지커▁▁the,빌할▁the▁image드를▁builds.node_modules는 디토는다생다니됩성같 됩니다.worker디렉터리 및 모든 종속성이 설치됩니다.그러면 런타임에worker 인스턴스에 도커 인스턴스node_modules), 김node_modules방금 설치했습니다.마운트된 볼륨을 에서 제거하여 이를 확인할 수 있습니다.docker-compose.yml.

해결 방법은 데이터 볼륨을 사용하여 모든 데이터 볼륨을 저장하는 것입니다.node_modules 를 복사하기 에 빌드된 도커 이미지에서 데이터를 합니다.worker디렉터리가 마운트되었습니다.이 작업은 에서 수행할 수 있습니다.docker-compose.yml다음과 같이:

redis:
    image: redis
worker:
    build: ./worker
    command: npm start
    ports:
        - "9730:9730"
    volumes:
        - ./worker/:/worker/
        - /worker/node_modules
    links:
        - redis

이미지의 휴대성에 문제가 있는지는 잘 모르겠지만 주로 도커를 사용하여 런타임 환경을 제공하는 것처럼 보이므로 문제가 되지 않습니다.

볼륨에 대한 자세한 내용을 보려면 https://docs.docker.com/userguide/dockervolumes/ 에서 유용한 사용자 가이드를 참조하십시오.

편집: 도커는 그 이후로 선행이 필요하도록 구문을 변경했습니다../도커-docker.yml 파일과 관련된 파일에 마운트할 수 있습니다.

node_modules폴더가 볼륨에 의해 덮어쓰여 컨테이너에서 더 이상 액세스할 수 없습니다.기본 모듈 로드 전략을 사용하여 볼륨에서 폴더를 꺼냅니다.

/data/node_modules/ # dependencies installed here
/data/app/ # code base

도커 파일:

COPY package.json /data/
WORKDIR /data/
RUN npm install
ENV PATH /data/node_modules/.bin:$PATH

COPY . /data/app/
WORKDIR /data/app/

node_modules이미지에 포함되어 있기 때문에 컨테이너 외부에서 디렉토리에 액세스할 수 없습니다.

@Frederik이 제공하는 솔루션NS는 작동하지만 node_modules 볼륨의 이름을 명시적으로 지정하는 것을 선호합니다.

나의project/docker-compose.yml(파일 이름 1: (파일 이름 포함 1.6+):

version: '2'
services:
  frontend:
    ....
    build: ./worker
    volumes:
      - ./worker:/worker
      - node_modules:/worker/node_modules
    ....
volumes:
  node_modules:

내 파일 구조는:

project/
   │── worker/
   │     └─ Dockerfile
   └── docker-compose.yml

은 다음이의볼생다라는 이름의 .project_node_modules애플리케이션을 올릴 때마다 다시 사용합니다.

나의docker volume ls다음과 같이 표시됩니다.

DRIVER              VOLUME NAME
local               project_mysql
local               project_node_modules
local               project2_postgresql
local               project2_node_modules

저도 최근에 비슷한 문제가 있었습니다.를 설치할 수 .node_modules 곳에서 설정하고 다른곳설니다정합에서▁the다▁elsewhere니를 설정합니다.NODE_PATH환경 변수입니다.

는 아래예서설습니다했치를 했습니다.node_modules안으로/install

작업자/도커 파일

FROM node:0.12

RUN ["mkdir", "/install"]

ADD ["./package.json", "/install"]
WORKDIR /install
RUN npm install --verbose
ENV NODE_PATH=/install/node_modules

WORKDIR /worker

COPY . /worker/

도커-docker.yml

redis:
    image: redis
worker:
    build: ./worker
    command: npm start
    ports:
        - "9730:9730"
    volumes:
        - worker/:/worker/
    links:
        - redis

우아한 솔루션이 있습니다.

전체 디렉터리가 아니라 앱 디렉터리만 마운트하면 됩니다.이렇게 하면 당신은 문제가 없을 것입니다.npm_modules.

예:

  frontend:
    build:
      context: ./ui_frontend
      dockerfile: Dockerfile.dev
    ports:
    - 3000:3000
    volumes:
    - ./ui_frontend/src:/frontend/src

Dockerfile.dev:

FROM node:7.2.0

#Show colors in docker terminal
ENV COMPOSE_HTTP_TIMEOUT=50000
ENV TERM="xterm-256color"

COPY . /frontend
WORKDIR /frontend
RUN npm install update
RUN npm install --global typescript
RUN npm install --global webpack
RUN npm install --global webpack-dev-server
RUN npm install --global karma protractor
RUN npm install
CMD npm run server:dev

업데이트: @Frederik에서 제공하는 솔루션을 사용합니다.NS.

저도 같은 문제에 직면했습니다.가 폴가있때을일 때./worker컨테이너에 마운트되었습니다. 컨테이너의 모든 컨텐츠가 동기화됩니다(따라서 로컬에 없는 경우 node_message 폴더가 사라집니다.

OS 기반의 호환되지 않는 npm 패키지 때문에, 저는 모듈을 로컬로 설치할 수 없었습니다. 그리고 나서 컨테이너를 시작할 수 있었습니다.

이에 대한 저의 해결책은 소스를 포장하는 것이었습니다.src 링크를 클릭합니다.node_modulesindex.js 파일을 사용하여 해당 폴더로 이동합니다.그래서 그.index.js파일은 이제 내 애플리케이션의 시작점입니다.

컨테이너를 실행할 때, 나는 그것을 장착했습니다./app/src 내컬더폴에 src폴더를 누릅니다.

컨테이너 폴더는 다음과 같습니다.

/app
  /node_modules
  /src
    /node_modules -> ../node_modules
    /app.js
  /index.js

못생겼지만 효과가 있습니다.

Node.js가 모듈을 로드하는 방식으로 인해node_modules소스 코드의 경로 어디에나 있을 수 있습니다.예를 들어, 출처를 다음 위치에 놓습니다./worker/src그리고 당신의package.json/worker,그렇게/worker/node_modules그들이 설치된 곳입니다.

이 없는 .node_module디렉터리를 다른 볼륨으로 이동합니다.설치 중인 npm 패키지를 최종 CMD 명령으로 이동하려고 합니다.

이 접근 방식의 단점:

  • 려달을 npm install컨테이너를 실행할 때마다 (에서 제외)npmyarn또한 이 프로세스를 약간 가속화할 수도 있습니다.

작업자/도커 파일

FROM node:0.12
WORKDIR /worker
COPY package.json /worker/
COPY . /worker/
CMD /bin/bash -c 'npm install; npm start'

도커-docker.yml

redis:
    image: redis
worker:
    build: ./worker
    ports:
        - "9730:9730"
    volumes:
        - worker/:/worker/
    links:
        - redis

node_modules를 프로젝트 폴더와 다르게 컨테이너에 설치하고 NODE_PATH를 node_modules 폴더로 설정하면 도움이 됩니다(컨테이너를 다시 빌드해야 합니다).

저는 도커 컴포지를 사용하고 있습니다.내 프로젝트 파일 구조:

-/myproject
--docker-compose.yml
--nodejs/
----Dockerfile

도커-docker.yml:

version: '2'
services:
  nodejs:
    image: myproject/nodejs
    build: ./nodejs/.
    volumes:
      - ./nodejs:/workdir
    ports:
      - "23005:3000"
    command: npm run server

nodejs 폴더의 도커 파일:

FROM node:argon
RUN mkdir /workdir
COPY ./package.json /workdir/.
RUN mkdir /data
RUN ln -s /workdir/package.json /data/.
WORKDIR /data
RUN npm install
ENV NODE_PATH /data/node_modules/
WORKDIR /workdir

노드 개발 환경에는 두 가지 별도의 요구 사항이 있습니다.소스 코드를 컨테이너에 마운트하고 IDE용 컨테이너에서 node_modules를 마운트합니다.첫 번째를 달성하기 위해, 당신은 보통의 마운트를 하지만, 모든 것은...당신이 필요로 하는 것들

volumes:
    - worker/src:/worker/src
    - worker/package.json:/worker/package.json
    - etc...

)- /worker/node_modules이는 도커 마운트가 실행 간에 볼륨을 유지하기 때문입니다. 즉, 호스트에서 마운트를 바인딩하는 것이 아니라 실제로 이미지에 있는 볼륨에서 벗어날 수 있습니다.

두 번째는 사실 더 어렵습니다.제 해결책은 약간 진부하지만, 효과가 있습니다.호스트 시스템에 node_modules 폴더를 설치하는 스크립트가 있으며 패키지를 업데이트할 때마다 호출해야 합니다.json(또는 도커-스캐너 빌드를 로컬로 실행하는 make target에 추가)

install_node_modules:
    docker build -t building .
    docker run -v `pwd`/node_modules:/app/node_modules building npm install

내 생각에는, 우리는 하지 말아야 합니다.RUN npm install도커 파일에 있습니다.하기 전에 bash를 할 수 .

docker run -it -v ./app:/usr/src/app  your_node_image_name  /bin/bash
root@247543a930d6:/usr/src/app# npm install

.node_modules의 상태가./폴더를 누릅니다.

작동 방식

FROM node:0.12

WORKDIR /worker

COPY package.json /worker/
RUN npm install \
  && mv node_modules /node_modules

COPY . /worker/

도커 파일에서 다음과 같은 작업을 시도할 수 있습니다.

FROM node:0.12
WORKDIR /worker
CMD bash ./start.sh

그런 다음 볼륨을 다음과 같이 사용해야 합니다.

volumes:
  - worker/:/worker:rw

시작 스크립트는 작업자 저장소의 일부여야 하며 다음과 같습니다.

#!/bin/sh
npm install
npm start

따라서 node_modules는 작업자 볼륨의 일부이며 동기화되고 모든 작업이 실행될 때 npm 스크립트가 실행됩니다.

또한 Docker 파일은 단순하기 때문에 기본 이미지를 사용하고 작성 파일에 다음 명령을 지정하면 됩니다.

version: '3.2'

services:
  frontend:
    image: node:12-alpine
    volumes:
      - ./frontend/:/app/
    command: sh -c "cd /app/ && yarn && yarn run start"
    expose: [8080]
    ports:
      - 8080:4200

이것은 저에게 특히 유용합니다. 왜냐하면 저는 단지 이미지의 환경이 필요하지만, 컨테이너 외부에서 제 파일을 조작하기 때문입니다. 저는 이것이 여러분도 하고 싶은 일이라고 생각합니다.

만약 당신이 원한다면,node_modules개발 중에 호스트가 사용할 수 있는 폴더. 빌드 시간 대신 컨테이너를 시작할 때 종속성을 설치할 수 있습니다.이 작업은 편집기에서 구문 강조 기능을 사용하기 위해 수행됩니다.

도커 파일

# We're using a multi-stage build so that we can install dependencies during build-time only for production.

# dev-stage
FROM node:14-alpine AS dev-stage
WORKDIR /usr/src/app
COPY package.json ./
COPY . .
# `yarn install` will run every time we start the container. We're using yarn because it's much faster than npm when there's nothing new to install
CMD ["sh", "-c", "yarn install && yarn run start"]

# production-stage
FROM node:14-alpine AS production-stage
WORKDIR /usr/src/app
COPY package.json ./
RUN yarn install
COPY . .

.무시.

더하다node_modules.dockerignore.Dockerfile달리기COPY . .는 볼륨을 하여 볼을사여데를이터륨하를 가져옵니다.node_modules.

**/node_modules

도커-docker.yml

node_app:
    container_name: node_app
    build:
        context: ./node_app
        target: dev-stage # `production-stage` for production
    volumes:
        # For development:
        #   If node_modules already exists on the host, they will be copied
        #   into the container here. Since `yarn install` runs after the
        #   container starts, this volume won't override the node_modules.
        - ./node_app:/usr/src/app
        # For production:
        #   
        - ./node_app:/usr/src/app
        - /usr/src/app/node_modules

는 이 있는 했지만 다음과 같은.node_modules되지 않은 지점에 캐시되다가 됩니다.node_modules도커 빌드 프로세스의 일부로 빌드된 디렉터리입니다.그래서 새로운 모듈을 추가했습니다.package.json도커 인스턴스에 표시되지 않습니다.

다행히도 저는 무슨 일이 일어나고 있는지 설명하고 최소 3가지 해결 방법을 제공하는 이 훌륭한 페이지를 발견했습니다. https://burnedikt.com/dockerized-node-development-and-mounting-node-volumes/

도커 합성을 사용하지 않으면 다음과 같이 할 수 있습니다.

FROM node:10

WORKDIR /usr/src/app

RUN npm install -g @angular/cli

COPY package.json ./
RUN npm install

EXPOSE 5000

CMD ng serve --port 5000 --host 0.0.0.0

그것을 : 그런다구축다니합음다.docker build -t myname .소스가 없는 두 의 볼륨을 추가하여 실행합니다.docker run --rm -it -p 5000:5000 -v "$PWD":/usr/src/app/ -v /usr/src/app/node_modules myname

Yarn을 사용하면 node_modules를 볼륨 외부로 이동할 수 있습니다.

# ./.yarnrc
--modules-folder /opt/myproject/node_modules

https://www.caxy.com/blog/how-set-custom-location-nodemodules-path-yarn 을 참조하십시오.

하는 또 은 이문를위또방은법다른한기극복하제입니다.clientNOT Find/NOT have node_modules 파일입니다.

프론트 엔드를 구축하고 자체적으로 실행할 수 있는 도커 허브로 밀어넣습니다.

그래서 당신이 할 때docker-compose up백엔드 및 DB의 경우 지정된 도커 허브 레포에서 프런트 엔드 이미지를 꺼냅니다.이러한 방식으로, 노드 모듈 문제는 문제가 되지 않습니다. 프론트 엔드 컨테이너가 이미 개별적으로 실행되고 있고 당신은 단지 그것을 당신의 안으로 끌어 들이고 있기 때문입니다.docker-compose.yml

디렉터리 구조의 예:

my-app/
-docker-compose.yml
-- backend/
-- client/
-------Dockerfile

그리고 당신의 안에서docker-compose.yml빌드를 다음과 같이 지정하면 됩니다.

version: '3'
services:
  frontend:
    image: <your-docker-frontend-rep>/<project>:tag

저는 아직 도커가 처음이라 틀리면 편하게 댓글 달아주세요. TY.

언급URL : https://stackoverflow.com/questions/30043872/docker-compose-node-modules-not-present-in-a-volume-after-npm-install-succeeds

반응형