如何在 Docker 中使用 "bind mount"

How to use "bind mount" in Docker

我在执行 运行 这个命令后在日志中收到错误:

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"]

绑定-v "/WorkSpace/d/data-volumes-03-adj-node-code:/app"毁了一切!它将主机目录中的内容挂载到容器的 /app 路径上,因此在构建 docker 映像期间安装的所有模块都将丢失。

可以做什么?在其他地方安装节点模块并更改默认节点路径。因此,您的 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

绑定挂载共享或挂载主机目录到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/

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

你应该-v "c:/WorkSpace/d/data-volumes-03-adj-node-code:/app"而不是

您应该运行以下内容:

docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback -v "$(pwd):/app" -v /app/node_modules feedback-node:volumes

Reference