如何在Docker中使用“绑定挂载”

4

在运行以下命令后,我的日志中出现了错误:

docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback -v "/WorkSpace/d/data-volumes-03-adj-node-code:/app" -v /app/node_modules feedback-node:volumes

错误信息如下:

internal/modules/cjs/loader.js:892 throw err; ^

Error: Cannot find module '/app/server.js' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15) at Function.Module._load (internal/modules/cjs/loader.js:745:27) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12) at internal/main/run_main_module.js:17:47 { code: 'MODULE_NOT_FOUND', requireStack: [] }

我该如何解决这个问题?

My Dockerfile:

FROM node:14
 
WORKDIR /app
 
COPY package.json .
 
RUN npm install 
 
COPY . .
 
EXPOSE 80
 
# VOLUME ["/app/feedback"]
 
CMD ["node", "server.js"]

workspace

docker settings general

docker settings resources

docker settings engine


1
看起来你的卷在容器内部遮挡了文件。尝试使用以下命令启动容器:docker run -d -p 3000:80 --name feedback-app -v /app/node_modules feedback-node:volumes - Eranga Heshan
еҲ йҷӨжүҖжңүзҡ„-vйҖүйЎ№гҖӮ(-v node_modulesжҳҜз»ҷDockerзҡ„жҢҮд»ӨпјҢз”ЁдәҺдҝқз•ҷж—§зҡ„node_modulesзӣ®еҪ•е№¶дјҳе…ҲдҪҝз”Ёж—§зүҲжң¬пјҢеҚіеҝҪз•Ҙй•ңеғҸдёӯд»»дҪ•жӣҙж”№пјҢжҜ”еҰӮpackage.jsonж–Ү件гҖӮдҪ дёҚйңҖиҰҒиҝҷдёӘгҖӮ) - David Maze
@DavidMaze: 其实,我没有完全理解你的意思。 我运行了这个命令,但它也没有起作用。docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback -v "/WorkSpace/d/data-volumes-01-starting-setup:/app" feedback-node:volumes - x19
你能重新构建feedback-node:volumes镜像并尝试这个命令docker run -d -p 3000:80 --name feedback-app feedback-node:volumes吗?最后一个命令是@DavidMaze建议的。它会删除所有你的卷。 - Eranga Heshan
@DavidMaze: 我想学习Docker。我知道如何运行一个Node.js项目。 - x19
显示剩余5条评论
6个回答

3
绑定挂载 -v "/WorkSpace/d/data-volumes-03-adj-node-code:/app" 会导致问题! 它将主机目录的内容挂载到容器的 /app 路径上,因此在构建 Docker 镜像期间安装的所有模块都将丢失。
怎么办?在其他地方安装 Node 模块,并将默认的 Node 路径更改为它。因此,您的 Dockerfile 变为(删除了 COPY . .,因为您想要将项目文件绑定挂载到容器上,因此它不必要):
FROM node:14
 
WORKDIR /modules
 
COPY package.json .
 
RUN npm install 

ENV NODE_PATH=/modules/node_modules
 
EXPOSE 80

WORKDIR /app
 
CMD ["node", "server.js"]

运行您的Docker镜像:

docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback -v "/c/WorkSpace/d/data-volumes-03-adj-node-code:/app" -v /modules/node_modules feedback-node:volumes

你的代码不起作用。当我改变文件的内容时,我希望在浏览器中看到这些变化。 我从优达学城获得了这段代码。 https://www.udemy.com/course/docker-kubernetes-the-practical-guide/learn/lecture/22166914#questions/15564548/ - x19
关于您在Docker中的“绑定挂载”问题,我已经测试了我的脚本,它是有效的。但是关于您项目中的“热重载”,这是需要在node.js服务器中进行配置的。例如,您可以使用https://nodemon.io/。只需将Dockerfile的最后一行替换为:`CMD ["npx", "nodemon", "server.js"]` @SaidRoohullahAllem - Hamon
我知道 nodemon 如何工作,但我的意思不是这个。 刷新页面后,我希望看到更改。 例如,在一个 jsx 文件中有 "HELLO X",在运行容器后我将其更改为 "HELLO Y",现在如果我刷新页面,我希望看到 "HELLO Y"。 在 udemy 课程中,老师做到了,但我不知道为什么那段代码在我的系统中不起作用。 - x19
使用nodemon进行设置可以实现你想要的效果,但如果在这个课程中是通过你原来提出问题的代码实现的,那就很有趣!我希望能够查看一下,但这门课程并不是开放/免费的。但我怀疑可能有一些细节被遗漏了。 - Hamon

1
问题在于您没有在 -v "/WorkSpace/d/data-volumes-03-adj-node-code:/app" 中指定项目目录的完整路径。

您应该改为使用 -v "c:/WorkSpace/d/data-volumes-03-adj-node-code:/app"


0

将共享目录绑定挂载或挂载主机目录到Docker容器中。

在容器内,您挂载的主机目录的所有内容都将可访问。

使用绑定挂载时,我们通常只在Docker镜像中安装依赖项,因为所有代码都可以从挂载路径访问。

例如dockerfile

FROM node:slim
WORKDIR /app
COPY package*.json ./
RUN apt-get update
RUN npm install
EXPOSE 1337
CMD ["npm", "start"]

package.json

{
  "name": "nodemon-docker-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start:express": "node ./index.js",
    "start": "nodemon"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^1.19.2"
  }
}

所以对于热重载,你也可以使用nodemon

不要将整个文件夹直接移动到容器中,因为可能会覆盖你的依赖项。

docker run -d -p 1337:1337 --name nodemon-app -v host_folder_path:/container path nodemon-node:v1.0

或者

docker run --rm -it -p 1337:1337 -v "${PWD}/server:/usr/src/app/server" nodemon-node:v1.0

同样也有一篇不错的文章:https://www.freecodecamp.org/news/how-to-enable-live-reload-on-docker-based-applications/


0
你应该运行以下代码:
docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback -v "$(pwd):/app" -v /app/node_modules feedback-node:volumes

参考资料


0
使用下面的命令,对我来说有效。
docker run -it -p 3000:80 --mount type=bind,src="$(pwd)",target=/app -v /app/node_modules feedback:m1

0

绑定挂载是将主机目录(在我们的情况下为Windows)共享或挂载到Docker容器中。

在容器目录中,您挂载的主机目录的所有内容都将是可访问和异步(读写),您可以编辑主机计算机上的任何文件,并且所有更改都将影响容器目录或文件。

要实现此目标,您的Dckerfile应如下所示:

FROM node:14

WORKDIR /app
# copy everything from the host app directory to the current directory on the container (/app)
COPY package*.json . 

RUN npm install

COPY . .

EXPOSE 80

CMD [ "npm", "start" ]

在你的 package.json 文件中

{
  "name": "data-volume-example",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "author": "O.Abdelaaziz",
  "license": "ISC",
  "scripts": {
    "start": "nodemon server.js"
  },
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "2.0.4"
  }
}

现在重要的是命令,如何编写不出错的命令并避免任何错误,例如:

docker: 守护程序返回错误:在创建挂载源路径“/run/desktop/mnt/host/c/Users/amine/Desktop/data-volumes”时出错:mkdir /run/desktop/mnt/host/c: 文件已存在。

或者当您认为您已经成功运行容器,但在列出正在运行/停止的容器后却发现容器已停止时,会出现一些错误。

docker ps -a 

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                        PORTS     NAMES
c31d3bd8204a   102       "docker-entrypoint.s…"   52 seconds ago   Exited (254) 49 seconds ago             node_data_volumes_container

通过记录容器

docker logs c31d3bd8204a


npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /app/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/app/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

在绑定挂载卷中,我们知道文件夹的存储位置,因为作为开发人员,我们将容器内路径应映射到主机上的路径,这就是诀窍。
如何编写呢? 请看这个链接: 使用Docker工具箱为Windows挂载Docker卷 你的命令应该像这样。
docker run -d --name node_data_volumes_container -p 3000:80 -v feedback:/app/feedback -v "/C/Users/amine/Desktop/data-volumes/:/app" -v /app/node_modules b52

-d 在分离模式下运行容器
--name 给容器命名
-p 将主机上的端口(3000)转发到容器上的端口(80)
-v feedback:/app/feedback 命名卷可保留所有文件,即使停止容器也是如此
-v "/C/Users/amine/Desktop/data-volumes/:/app" 将主机目录绑定到容器目录
-v /app/node_modules 匿名卷可保留/查找依赖关系,即使停止容器也是如此
b52 来自镜像id的前三个字母(您可以提供完整id或名称)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接