繁体   English   中英

在具有 root 权限的 Docker 中,错误“EACCES:权限被拒绝,打开“/root/.config/configstore/bower-github.json”,尽管该文件可以访问

[英]In Docker with root, error `EACCES: permission denied, open '/root/.config/configstore/bower-github.json'` despite that file being accessible

设置

我正在尝试对一个使用节点 12、npm 8 和凉亭的非常古老的项目进行 docker 化。

由于没有捆绑这三个依赖项的预构建映像,因此我正在使用此Dockerfile构建自己的映像:

FROM node:12

RUN npm install -g npm@8
RUN npm install -g bower

RUN echo "node version: $(node --version)"
RUN echo "npm version: $(npm --version)"
RUN echo "bower version: $(bower --version)"

这是docker-compose.yml (片段):

version: "3.9"

services:
  frontend:
    build: ./front-end
    working_dir: /home/node/app/
    volumes:
      - ./front-end:/home/node/app/
    entrypoint: [ "/bin/bash", "-c" ]
    command:
      - |
        npm i
        bower i --allow-root
        npm start

问题

我这样运行它:

docker compose build frontend --no-cache --progress=plain
docker compose up --force-recreate frontend

它像这样崩溃:

my-frontend-1  | npm ERR! path /home/node/app/node_modules/ember-cli-cookie
my-frontend-1  | npm ERR! command failed
my-frontend-1  | npm ERR! command sh -c -- bower install --allow-root
my-frontend-1  | npm ERR! /home/node/app/node_modules/bower/lib/node_modules/configstore/index.js:54
my-frontend-1  | npm ERR!                             throw err;
my-frontend-1  | npm ERR!                             ^
my-frontend-1  | npm ERR!
my-frontend-1  | npm ERR! Error: EACCES: permission denied, open '/root/.config/configstore/bower-github.json'
my-frontend-1  | npm ERR! You don't have access to this file.

分析

这是我对事件的重建:

  1. 首先,崩溃的不是docker-compose.ymlbower i步骤,而是npm i 如果我注释掉npm i ,那么脚本会继续进行。
  2. npm安装ember-cli-cookie@0.2.0 package。
  3. npm调用ember-cli-cookiepostinstall 脚本
  4. postinstall脚本调用bower install --allow-root
  5. npm实际执行的命令是sh -c -- bower install --allow-root
  6. 它与EACCES: permission denied, open '/root/.config/configstore/bower-github.json'

以下是不可访问文件的权限:

root@7d24854cf1af:/home/node/app# ls -alhF /root/.config/configstore/
total 20K
drwx------ 1 root root 4.0K Aug 24 20:16 ./
drwx------ 1 root root 4.0K Aug 24 19:55 ../
-rw------- 1 root root    2 Aug 24 20:16 bower-github.json
-rw------- 1 root root   55 Aug 24 19:55 update-notifier-npm.json

whoami返回root

我通过在npm i之前将命令插入docker-compose.yml来检查权限和用户名。

我不明白这怎么可能:root 无法访问具有-rw------- 1 root root权限的文件。

如果我尝试像这样手动访问它(复制sh -c方法):

sh -c -- "nano /root/.config/configstore/bower-github.json"

...我可以很好地查看文件保存更改。

我什至尝试将RUN chmod -R a+rwx /root/.config/到我的 Dockerfile 的末尾,重新构建映像并重新创建容器 - 它没有任何区别!

问题

为什么会发生这种情况以及如何解决?

PS作业

我找到了这些相关的问题,但他们的答案对我没有帮助:

问题的原因

npm从调用它的用户运行,但从拥有当前目录的用户运行。

由于项目文件夹是volumes: -ed 到容器中, npm正在使用主机操作系统用户的uidgid运行。 这样的用户在容器中不存在,所以它有点像鬼。 该用户无权访问/root/.config/ ,因此失败。

一个相关的问题

node_modules/在主机操作系统文件系统上并且npm在容器中时,文件所有权将存在差异,从而阻止您从主机操作系统中删除node_modules/

解决这两个问题

这个问题的优雅解决方案是在容器中创建一个用户,其uidgid与主机操作系统中的用户相同。 这是你如何做到的。

Dockerfile

FROM node:12

# https://jtreminio.com/blog/running-docker-containers-as-current-host-user/
ARG USER_ID
ARG GROUP_ID

RUN if [ ${USER_ID:-0} -ne 0 ] && [ ${GROUP_ID:-0} -ne 0 ]; then \
  userdel -f node &&\
  if getent group node ; then groupdel node; fi &&\
  groupadd -g ${GROUP_ID} node &&\
  useradd -l -u ${USER_ID} -g node node &&\
  install -d -m 0755 -o node -g node /home/node &&\
  chown --changes --silent --no-dereference --recursive \
  --from=33:33 ${USER_ID}:${GROUP_ID} \
  /home/node \
  ;fi

USER node

# https://stackoverflow.com/a/59151128/901944
RUN mkdir ~/.npm-global
RUN npm config set prefix '~/.npm-global'
ENV PATH=/home/node/.npm-global/bin:$PATH

RUN npm install -g npm@8

使用docker构建容器:

USER_ID=$(id -u) GROUP_ID=$(id -g) \
    docker image build \
    --build-arg USER_ID=$(id -u ${USER}) \
    --build-arg GROUP_ID=$(id -g ${USER}) \
    -t frontend \
    .

docker-compose.yml (片段):

services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        USER_ID: ${USER_ID:-0}
        GROUP_ID: ${GROUP_ID:-0}

使用docker compose构建容器:

USER_ID=$(id -u) GROUP_ID=$(id -g) docker compose build --no-cache fronend

资源

这篇令人惊叹的文章详细描述了问题并探索了潜在的解决方案,从更简单的解决方案开始,并解释了它们为什么不好以及为什么需要精心设计的解决方案。

https://jtreminio.com/blog/running-docker-containers-as-current-host-user/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM