在使用Docker卷(volumes)时,尝试在Node项目中创建文件夹时出现“EACCES:permission denied mkdir ...”错误。

6

我尝试使用Docker卷(-)运行一个Node项目容器。

docker run -p 3000:3000 -v /myapp/node_modules -v $(pwd):/myapp batzu/frontend 

然后遇到了一个错误 -

EACCES: permission denied, mkdir '/myapp/node_modules/.cache'

但是当我尝试在不使用-v标志的情况下运行相同的容器时 -

docker run -p 3000:3000 batzu/frontend

容器正常启动,没有错误。
首次运行Docker日志-
> frontend@0.1.0 start
> react-scripts start

ℹ 「wds」: Project is running at http://172.17.0.2/
ℹ 「wds」: webpack output is served from 
ℹ 「wds」: Content not from webpack is served from /myapp/public
ℹ 「wds」: 404s will fallback to /
Starting the development server...

Failed to compile.

EACCES: permission denied, mkdir '/myapp/node_modules/.cache'

使用的构建命令(该应用程序是一个示例 react-app)-

docker build -f Dockerfile.dev -t batzu/frontend .

我的Dockerfile.dev -

FROM node:alpine

WORKDIR /myapp

COPY package.json .
RUN npm install
COPY . .

CMD ["npm", "run", "start"]

package.json是React项目生成的文件-

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/user-event": "^12.7.1",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.2",
    "web-vitals": "^1.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

我试图通过sh进入容器并从中执行npm run start,但仍然遇到相同的错误,即使我可以在shell中执行mkdir '/myapp/node_modules/.cache'而没有任何权限错误。
我无法理解-v /myapp/node_modules在docker运行中到底是做什么的,因为我被告知它应该在我们将工作目录映射到容器的/myapp/目录之前,对node_modules文件夹进行类似书签的操作。为什么这会导致错误?
有人能指向我正确的方向或解释我做错了什么或者有什么修复方法吗......?
先谢谢大家了 :)

这个回答解决了您的问题吗?在Docker中访问主机目录被拒绝的权限 - Max
问题是我可以在node_modules文件夹中运行任何命令而没有任何问题,只有npm run start会抛出错误。 - batzu
npm run start是做什么的?请在问题中附上package.json脚本部分。 - Max
尽量不要使用${cwd}值,而是使用普通的文件夹,例如/foo/bar - Max
你看过这个stackoverflow问题了吗? - Max
显示剩余2条评论
3个回答

6
您的Dockerfile.dev应该如下所示,请注意,COPY将代表node用户执行,并且WORKDIR应为/home/node(有关更多信息,请参见https://github.com/nodejs/docker-node/issues/740#issuecomment-458545074):
FROM node:alpine

WORKDIR /home/node/app
RUN chown -R node:node /home/node/app

COPY --chown=node:node package.json .

RUN npm install

COPY --chown=node:node . .

# At the end, set the user to use when running this image
USER node

CMD npm run start

请注意,如果您将测试覆盖率服务添加到docker-compose.yml文件中,它将与dockerdocker-compose CLI一起使用。

5

通过查看其他人的Dockerfiles和在容器中运行bash终端命令,我得出的结论是我使用的基础镜像node:alpine会在容器内创建一个名为node的用户。

npm run start命令作为node用户的进程(带有节点的UID)执行,该用户没有root权限(我发现这一点是通过查看htop获得的)。因此,为了使node用户成为/app目录的所有者,我在Dockerfile中添加了以下内容-

RUN chown -R node.node /app

更新后的Dockerfile.dev文件-

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install
RUN chown -R node.node /app

COPY . .

CMD ["npm", "run", "start"]

这解决了我的问题,希望它也能帮助其他人。:)


0
在 Dockerfile.dev 中添加一行。
RUN chmod 777 node_modules

现在 Dockerfile.dev 的内容如下:

FROM node:alpine
WORKDIR '/app'
COPY package.json .
RUN npm install
COPY . .
RUN chmod 777 node_modules
CMD ["npm","run","start"]

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