Py学习  »  docker

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

Tinstar71 • 3 年前 • 1723 次点击  

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

  • 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
 
1723 次点击  
文章 [ 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    9 年前

对于节点开发环境,我看到了两个不同的要求。。。将源代码装入容器,并从容器中装入节点_模块(用于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    8 年前

还有一些没有映射的简单解决方案 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    10 年前

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

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

更新:使用 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文件。