社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

节点,js在官方节点上找不到本地安装的模块。js docker图像[重复]

Tinstar71 • 3 年前 • 1567 次点击  

我有一个应用程序具有以下服务:

  • web/ -在端口5000上保存并运行python 3 flask web服务器。使用sqlite3。
  • worker/ -有一个 index.js 文件,它是队列的工作进程。web服务器通过端口使用json API与该队列交互 9730 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)

事实证明,这些模块都不存在 /工作者/节点_模块 (主机上或容器中)。

如果是主持人,我 npm install ,然后一切正常。但我不想这么做。我希望容器处理依赖项。

这里怎么了?

(不用说,所有的包裹都在里面。) package.json .)

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/128013
 
1567 次点击  
文章 [ 18 ]  |  最新文章 3 年前
Izaya
Reply   •   1 楼
Izaya    4 年前

如果不使用docker compose 你可以这样做:

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

PHZ.fi-Pharazon
Reply   •   2 楼
PHZ.fi-Pharazon    4 年前

使用纱线,您可以通过设置

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

看见 https://www.caxy.com/blog/how-set-custom-location-nodemodules-path-yarn

samuelcolt
Reply   •   3 楼
samuelcolt    4 年前

你可以走了 node_modules 变成一个 / 文件夹

How it works

FROM node:0.12

WORKDIR /worker

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

COPY . /worker/
Kasper
Reply   •   4 楼
Kasper    4 年前

如果你想要 node_modules 文件夹在开发期间对主机可用,您可以在启动容器时而不是在构建时安装依赖项。我这样做是为了让语法高亮显示在我的编辑器中工作。

Dockerfile

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

dockerignore先生

添加 节点单元 .dockerignore 以防止在 Dockerfile COPY . . 节点单元 .

**/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
Joel Sullivan
Reply   •   5 楼
Joel Sullivan    4 年前

node_modules Docker实例中的目录将被缓存在指定或未指定的装载点中,之后将覆盖 节点单元 作为Docker构建过程的一部分构建的目录。因此,我添加了新模块 package.json 不会出现在Docker实例中。

幸运的是,我找到了这个优秀的页面,它解释了正在发生的事情,并给出了至少三种解决方法: https://burnedikt.com/dockerized-node-development-and-mounting-node-volumes/

Parav01d
Reply   •   6 楼
Parav01d    6 年前

您可以在Dockerfile中尝试以下内容:

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

然后你应该像这样使用音量:

volumes:
  - worker/:/worker:rw

startscript应该是worker存储库的一部分,如下所示:

#!/bin/sh
npm install
npm start

因此,node_模块是您的工作卷的一部分,在一切就绪时会同步,并执行npm脚本。

itmuckel
Reply   •   7 楼
itmuckel    5 年前

您也可以放弃Dockerfile,因为它很简单,只需使用一个基本图像并在compose文件中指定命令:

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

这对我来说特别有用,因为我只需要图像的环境,但在容器外操作我的文件,我认为这也是你想要做的。

pigLoveRabbit520
Reply   •   8 楼
pigLoveRabbit520    7 年前

在我看来,我们不应该这样做 RUN npm install 在Dockerfile里。相反,在运行正式的节点服务之前,我们可以使用bash启动一个容器来安装依赖项

docker run -it -v ./app:/usr/src/app  your_node_image_name  /bin/bash
root@247543a930d6:/usr/src/app# npm install
Paul Becotte
Reply   •   9 楼
Paul Becotte    8 年前

对于节点开发环境,我看到了两个不同的要求。。。将源代码装入容器,并从容器中装入节点_模块(用于IDE)。要完成第一步,你要做通常的坐骑,但不是所有的。。。就是你需要的东西

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

(不这样做的理由) - /worker/node_modules 这是因为docker compose将在两次运行之间保留该卷,这意味着您可能会偏离图像中的实际内容(这不仅违背了绑定装载主机的目的)。

第二个更难。我的解决方案有点老套,但很管用。我有一个脚本,可以在主机上安装node_modules文件夹,只要记住在更新包时调用它就行了。json(或者,将其添加到本地运行docker compose build的make目标中)。

install_node_modules:
    docker build -t building .
    docker run -v `pwd`/node_modules:/app/node_modules building npm install
Egel
Reply   •   10 楼
Egel    7 年前

还有一些没有映射的简单解决方案 node_module 将目录插入另一个卷。它将把安装npm软件包转移到最终的CMD命令中。

这种方法的缺点是:

  • npm install 每次运行容器时(从 npm yarn 也可能会加快这一过程)。

工人/码头工人

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
sergeysynergy
Reply   •   11 楼
sergeysynergy    8 年前

将容器中的节点_模块安装到与项目文件夹不同的位置,并将节点_路径设置到节点_模块文件夹有助于我(您需要重建容器)。

我用的是docker compose。我的项目文件结构:

-/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文件夹中的Dockerfile:

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
Justin Stayton
Reply   •   12 楼
Justin Stayton    9 年前

由于 the way Node.js loads modules , node_modules 可以位于源代码路径中的任何位置。例如,把你的消息来源放在 /worker/src 还有你的 package.json 在里面 /worker 所以 /worker/node_modules 是安装它们的地方。

Community Akshay L
Reply   •   13 楼
Community Akshay L    4 年前

更新:使用 solution 由@FrederikNS提供。

我也遇到了同样的问题。当文件夹 /worker 被装载到容器中——它的所有内容都将被同步(因此,如果本地没有node_modules文件夹,它将消失。)

由于基于操作系统的npm软件包不兼容,我不能只在本地安装模块,然后启动容器,所以。。

我的解决方案是用一个 src node_modules 使用 this index.js file .所以 index.js 文件现在是我申请的起点。

当我运行容器时,我安装了 /app/src 文件夹到我的本地 src 文件夹

容器文件夹看起来像这样:

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

它是 丑陋的 ,但它是有效的。。

holms
Reply   •   14 楼
holms    8 年前

有一个优雅的解决方案:

只需挂载不是整个目录,而是应用程序目录。这样你就不会有麻烦了 npm_modules .

例子:

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

Dockerfile。德夫:

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
ericstolten
Reply   •   15 楼
ericstolten    9 年前

我最近也有类似的问题。你可以安装 node_modules 在其他地方设置 NODE_PATH 环境变量。

在下面的例子中,我安装了 节点单元 进入 /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
Guillaume Vincent
Reply   •   16 楼
Guillaume Vincent    4 年前

@FrederikNS提供的解决方案是有效的,但我更喜欢显式地将我的node_modules命名为volume。

我的 project/docker-compose.yml 文件(docker compose版本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
Derk Jan Speelman jsan
Reply   •   17 楼
Derk Jan Speelman jsan    5 年前

这个 node_modules 文件夹被卷覆盖,无法在容器中访问。我用的是 native module loading strategy 要从卷中取出文件夹,请执行以下操作:

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

Dockerfile:

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

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

这个 节点单元 无法从容器外部访问目录,因为它包含在映像中。

GammaGames FrederikNS
Reply   •   18 楼
GammaGames FrederikNS    3 年前

这是因为您添加了 worker 目录作为卷发送到 docker-compose.yml ,因为卷在生成期间未装入。

当docker构建图像时 node_modules 目录是在 工人 目录,所有依赖项都安装在那里。然后在运行时 工人 来自docker外部的目录被装载到docker实例中(该实例没有安装 节点单元 ),隐藏 节点单元 你刚刚安装的。您可以通过从服务器中删除已装入的卷来验证这一点 docker撰写。yml .

解决方法是使用数据卷存储所有 节点单元 ,因为数据卷在 工人 目录已装入。这可以在 docker撰写。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后来修改了它的语法,要求使用前导 ./ 用于装入与docker compose相关的文件。yml文件。