簡體   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