简体   繁体   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

Setup设置

I'm trying to dockerize a pretty old project that uses Node 12, npm 8 and bower.我正在尝试对一个使用节点 12、npm 8 和凉亭的非常古老的项目进行 docker 化。

Since there's no prebuilt image that bundles these three dependencies, I'm building my own image with this Dockerfile :由于没有捆绑这三个依赖项的预构建映像,因此我正在使用此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)"

Here's the docker-compose.yml (fragment):这是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

Problem问题

I run it like this:我这样运行它:

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

It crashes like this:它像这样崩溃:

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.

Analysis分析

Here's my reconstruction of events:这是我对事件的重建:

  1. First of all, it's not the bower i step of docker-compose.yml that's crashing, it's npm i .首先,崩溃的不是docker-compose.ymlbower i步骤,而是npm i If I comment out npm i , then the script proceeds further.如果我注释掉npm i ,那么脚本会继续进行。
  2. npm installs the ember-cli-cookie@0.2.0 package. npm安装ember-cli-cookie@0.2.0 package。
  3. npm calls the postinstall script of ember-cli-cookie . npm调用ember-cli-cookiepostinstall 脚本
  4. The postinstall script calls bower install --allow-root . postinstall脚本调用bower install --allow-root
  5. The actual command executed by npm is sh -c -- bower install --allow-root . npm实际执行的命令是sh -c -- bower install --allow-root
  6. It crashes with EACCES: permission denied, open '/root/.config/configstore/bower-github.json' .它与EACCES: permission denied, open '/root/.config/configstore/bower-github.json'

Here are permissions for the inaccessible file:以下是不可访问文件的权限:

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 returns root . whoami返回root

I checked permissions and username by inserting commands into docker-compose.yml immediately before npm i .我通过在npm i之前将命令插入docker-compose.yml来检查权限和用户名。

I don't understand how this can be possible: root is unable to access a file with permissions of -rw------- 1 root root .我不明白这怎么可能:root 无法访问具有-rw------- 1 root root权限的文件。

If I try accessing it manually like this (replicating the sh -c approach):如果我尝试像这样手动访问它(复制sh -c方法):

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

...I'm able to view the file save changes to it just fine. ...我可以很好地查看文件保存更改。

I even tried adding RUN chmod -R a+rwx /root/.config/ to the end of my Dockerfile, rebuilding the image and recreating the container — it made no difference!我什至尝试将RUN chmod -R a+rwx /root/.config/到我的 Dockerfile 的末尾,重新构建映像并重新创建容器 - 它没有任何区别!

Question问题

Why is this happening and how to fix it?为什么会发生这种情况以及如何解决?

PS Homework PS作业

I've found these related questions but their answers did not help me:我找到了这些相关的问题,但他们的答案对我没有帮助:

The cause of the problem问题的原因

npm is running from the user that's invoking it, but from the user who owns current directoy. npm从调用它的用户运行,但从拥有当前目录的用户运行。

Since the project folder is volumes: -ed into the container, npm is running with uid and gid of the host OS user.由于项目文件夹是volumes: -ed 到容器中, npm正在使用主机操作系统用户的uidgid运行。 Such user does not exist in the container, so it's kinda a ghost.这样的用户在容器中不存在,所以它有点像鬼。 This user has no access to /root/.config/ , thus the failure.该用户无权访问/root/.config/ ,因此失败。

A related problem一个相关的问题

When node_modules/ is on the host OS filesystem and npm is in a container, there's gonna be a discrepancy in file ownership, preventing you from eg deleing node_modules/ from the host OS.node_modules/在主机操作系统文件系统上并且npm在容器中时,文件所有权将存在差异,从而阻止您从主机操作系统中删除node_modules/

The solution to both problems解决这两个问题

The graceful solution to this problem is to create a user in the container with uid and gid identical to your user in the host OS.这个问题的优雅解决方案是在容器中创建一个用户,其uidgid与主机操作系统中的用户相同。 Here's how you do it.这是你如何做到的。

Dockerfile : 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

Build the container with docker :使用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 (fragment): docker-compose.yml (片段):

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

Build the container with docker compose :使用docker compose构建容器:

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

Source资源

This amazing article describes the problem in detail and explores potential solutions, starting with simpler ones and explaining why they are no good and why the elaborate solution is required.这篇令人惊叹的文章详细描述了问题并探索了潜在的解决方案,从更简单的解决方案开始,并解释了它们为什么不好以及为什么需要精心设计的解决方案。

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

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

相关问题 Firebase-functions 部署错误“错误:EACCES:权限被拒绝,打开'/root/.config/configstore/firebase-tools.json'” - Firebase-functions deploy error "Error: EACCES: permission denied, open '/root/.config/configstore/firebase-tools.json'" Docker 文件:EACCES:权限被拒绝错误 - 无法写入文件:节点 - Docker File: EACCES: permission denied error - Could not write file : Node Docker 错误:EACCES:权限被拒绝,mkdir - Docker Error: EACCES: permission denied, mkdir Gulp gulp-sass“错误:EACCES:许可被拒绝,开放” - Gulp gulp-sass “Error: EACCES: permission denied, open” 根shrc的权限被拒绝 - Permission denied for root shrc mq_open() - EACCES,权限被拒绝 - mq_open() - EACCES, Permission denied 在Docker容器中以非root身份运行nginx会给出权限被拒绝错误 - Running nginx as non-root in Docker container gives permission denied error 用root以外的用户启动Docker守护程序时出错(权限被拒绝) - Error when starting Docker daemon with user other than root (permission denied) Okta 无法启动错误:EACCES:权限被拒绝 - Okta wont start Error: EACCES: permission denied 符号链接将“权限被拒绝”...给root - Symlink giving “Permission denied”… to root
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM