[英]In Docker with root, error `EACCES: permission denied, open '/root/.config/configstore/bower-github.json'` despite that file being accessible
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
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.
Here's my reconstruction of events:这是我对事件的重建:
bower i
step of docker-compose.yml
that's crashing, it's npm i
.docker-compose.yml
的bower i
步骤,而是npm i
。 If I comment out npm i
, then the script proceeds further.npm i
,那么脚本会继续进行。npm
installs the ember-cli-cookie@0.2.0
package. npm
安装ember-cli-cookie@0.2.0
package。npm
calls the postinstall script of ember-cli-cookie
. npm
调用ember-cli-cookie
的postinstall 脚本。postinstall
script calls bower install --allow-root
. postinstall
脚本调用bower install --allow-root
。npm
is sh -c -- bower install --allow-root
. npm
实际执行的命令是sh -c -- bower install --allow-root
。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 的末尾,重新构建映像并重新创建容器 - 它没有任何区别!
Why is this happening and how to fix it?为什么会发生这种情况以及如何解决?
I've found these related questions but their answers did not help me:我找到了这些相关的问题,但他们的答案对我没有帮助:
EACCES, permission denied when running bower — I don't have a ~/.cache
folder. EACCES,运行 bower 时权限被拒绝- 我没有
~/.cache
文件夹。
bower install fails giving me EACCES: permission denied error — the user inside the container is root
, the $USER
and $GROUP
env vars are empty. bower install 失败给我 EACCES: permission denied 错误- 容器内的用户是
root
, $USER
和$GROUP
环境变量是空的。
Error: EACCES: permission denied — the ~/.npm-global
approach did not help. 错误:EACCES:权限被拒绝—
~/.npm-global
方法没有帮助。 whoami
is root
already. whoami
已经是root
了。
⚠ Adding --unsafe-perm=true --allow-root
to npm i
resolves the issue, npm i
completes successfully, but then npm start
crashes with exactly the same error (except the inaccessible file is /root/.config/configstore/ember-cli.json
), and adding those flags to npm start
does not help. ⚠ 将
--unsafe-perm=true --allow-root
添加到npm i
解决了问题, npm i
成功完成,但随后 npm 文件与 /root/ /root/.config/configstore/ember-cli.json
npm start
崩溃与完全相同的错误/root/.config/configstore/ember-cli.json
),并将这些标志添加到npm start
没有帮助。
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
正在使用主机操作系统用户的uid
和gid
运行。 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/
,因此失败。
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 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.这个问题的优雅解决方案是在容器中创建一个用户,其
uid
和gid
与主机操作系统中的用户相同。 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
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.