由于绑定挂载,Dockerfile 和 docker-compose 找不到节点模块

Posted

技术标签:

【中文标题】由于绑定挂载,Dockerfile 和 docker-compose 找不到节点模块【英文标题】:Node modules not found with Dockerfile and docker-compose due to bind mount 【发布时间】:2019-10-20 12:09:21 【问题描述】:

所以我有这个 NodeJS express 应用程序。这是代码工作:

Dockerfile

FROM node:10.16-alpine
WORKDIR /app
COPY . /app
RUN npm install
CMD ["npm", "start"]

docker-compose.yml

version: "3.7"

services:
  node-express:
    build: .
    ports: 
      - 80:3000

但对于这个应用程序,我想查看实时代码更改。所以我知道 是您可以使用绑定挂载的地方,但只要我添加卷 像这样:

docker-compose.yml

version: "3.7"

services:
  node-express:
    build: .
    volumes: 
      - .:/app
    ports: 
      - 80:3000

看起来 node_modules 不再在“app”目录中了.. 我怎样才能解决这个问题?我已经为此工作了四个小时,但我仍然 无法发现错误!

错误

HijackManiac:webserver hijackmaniac$ docker-compose up
Creating network "webserver_default" with the default driver
Building node-express
Step 1/5 : FROM node:10.16-alpine
 ---> a298c79121d9
Step 2/5 : WORKDIR /app
 ---> Running in 9b99df0f54ba
Removing intermediate container 9b99df0f54ba
 ---> 48f9b606b32d
Step 3/5 : COPY . /app
 ---> 1f29dc735dc7
Step 4/5 : RUN npm install
 ---> Running in 81225f56a9fd
npm WARN webserver@1.0.0 No description
npm WARN webserver@1.0.0 No repository field.

added 106 packages from 130 contributors and audited 202 packages in 3.344s
found 0 vulnerabilities

Removing intermediate container 81225f56a9fd
 ---> 2985dc77bc12
Step 5/5 : CMD ["npm", "start"]
 ---> Running in 271ab42687ce
Removing intermediate container 271ab42687ce
 ---> 38a39768792e

Successfully built 38a39768792e
Successfully tagged webserver_node-express:latest
WARNING: Image for service node-express was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating webserver_node-express_1 ... done
Attaching to webserver_node-express_1
node-express_1  | 
node-express_1  | > webserver@1.0.0 start /app
node-express_1  | > node src/app.js
node-express_1  | 
node-express_1  | internal/modules/cjs/loader.js:638
node-express_1  |     throw err;
node-express_1  |     ^
node-express_1  | 
node-express_1  | Error: Cannot find module 'express'
node-express_1  |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
node-express_1  |     at Function.Module._load (internal/modules/cjs/loader.js:562:25)
node-express_1  |     at Module.require (internal/modules/cjs/loader.js:690:17)
node-express_1  |     at require (internal/modules/cjs/helpers.js:25:18)
node-express_1  |     at Object.<anonymous> (/app/src/app.js:2:17)
node-express_1  |     at Module._compile (internal/modules/cjs/loader.js:776:30)
node-express_1  |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
node-express_1  |     at Module.load (internal/modules/cjs/loader.js:653:32)
node-express_1  |     at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
node-express_1  |     at Function.Module._load (internal/modules/cjs/loader.js:585:3)
node-express_1  | npm ERR! code ELIFECYCLE
node-express_1  | npm ERR! errno 1
node-express_1  | npm ERR! webserver@1.0.0 start: `node src/app.js`
node-express_1  | npm ERR! Exit status 1
node-express_1  | npm ERR! 
node-express_1  | npm ERR! Failed at the webserver@1.0.0 start script.
node-express_1  | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
node-express_1  | npm WARN Local package.json exists, but node_modules missing, did you mean to install?
node-express_1  | 
node-express_1  | npm ERR! A complete log of this run can be found in:
node-express_1  | npm ERR!     /root/.npm/_logs/2019-06-04T23_55_20_327Z-debug.log
webserver_node-express_1 exited with code 1

查看工作树:

在我在 docker-compose.yml 中添加卷之前,容器已成功运行。这是结构:

【问题讨论】:

你能发布你的项目文件结构吗? 当你设置工作目录WORKDIR 意味着你已经在那里了。从 Dockerfile 中查看您的复制声明。您已将所有当前目录复制到 /app,这实际上意味着容器文件系统中的 /app/app 我不认为这是真的,因为当我在 docker-compose.yml 中运行这个没有“volumes”的 docker-compose 时。我没有看到 /app/app。我会把图片上传到这个帖子。 【参考方案1】:

您需要修改项目结构,将文件夹中的每个可编辑代码移动到一个文件夹中,比如src,或者更新您的 Dockerfile 以将 node_modules 移动到上一级目录。

我们知道,当 Node 在当前目录找不到 node_modules 时,它会开始在父目录中寻找它,所以我们利用它。

与此类似的 Dockerfile 将解决您的问题。

FROM node:10.16-alpine
WORKDIR /node
COPY package.json package-lock.json ./

RUN npm install
WORKDIR /node/app
COPY . .

CMD ["npm", "start"]

请确保也对 docker-compose.yml 进行适当的更改(目录结构已更改)

【讨论】:

【参考方案2】:

当您将项目的卷挂载到容器工作目录中时,您将使用本地项目目录中的内容覆盖自原始复制/添加到 Dockerfile 以来所做的任何更改。在这种情况下,这意味着 node_modules 文件夹。我发现解决此问题的最简单方法是不挂载整个项目目录,而只是挂载我的源代码的子文件夹。

【讨论】:

这对我的情况仍然没有帮助。如果没有必要,我不想更改项目结构。

以上是关于由于绑定挂载,Dockerfile 和 docker-compose 找不到节点模块的主要内容,如果未能解决你的问题,请参考以下文章

docke--Dockerfile构建docker镜像

Docke--Dockerfile 构建LNMP环境

Docke--Dockerfile实践

Linux系统的目录绑定配置

#云原生征文# docker数据卷与DockerFile学习

Docker-Dockerfile1