在docker镜像上使用npm global install时没有访问权限错误

Gab*_*ujo 16 npm docker

我正在尝试使用全局安装的firebase-tools和angular-cli 构建一个docker镜像.我正在为两个版本的节点构建相同的图像:6.x(LTS硼)和v8.x(最新的alpine).在本地,两个图像都很好,但是当我尝试在docker hub中构建时,只有v6.x构建成功.使用v8.x,它将被困在undefined和nobody用户访问权限中.我已经在使用root用户(USER root),因为没有这个设置(或使用USER节点),两个图像都无法构建.

这是我的Dockerfile:

FROM node:latest

USER root

RUN npm install --quiet --no-progress -g @angular/cli@latest firebase-tools
RUN npm cache clean --force
Run Code Online (Sandbox Code Playgroud)

这是输出:

Step 4/5 : RUN npm install --quiet --no-progress -g @angular/cli@latest firebase-tools

 ---> Running in fce3da11b04e

 npm WARN deprecated node-uuid@1.4.8: Use uuid module instead
 /usr/local/bin/firebase -> /usr/local/lib/node_modules/firebase-tools/bin/firebase
 /usr/local/bin/ng -> /usr/local/lib/node_modules/@angular/cli/bin/ng

> node-sass@4.5.3 install /usr/local/lib/node_modules/@angular/cli/node_modules/node-sass
> node scripts/install.js

Unable to save binary /usr/local/lib/node_modules/@angular/cli/node_modules/node-sass/vendor/linux-x64-57 : { Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/@angular/cli/node_modules/node-sass/vendor'
  at Object.fs.mkdirSync (fs.js:890:18)
  at sync (/usr/local/lib/node_modules/@angular/cli/node_modules/mkdirp/index.js:71:13)
  at Function.sync (/usr/local/lib/node_modules/@angular/cli/node_modules/mkdirp/index.js:77:24)
  at checkAndDownloadBinary (/usr/local/lib/node_modules/@angular/cli/node_modules/node-sass/scripts/install.js:111:11)
  at Object.<anonymous> (/usr/local/lib/node_modules/@angular/cli/node_modules/node-sass/scripts/install.js:154:1)
  at Module._compile (module.js:569:30)
  at Object.Module._extensions..js (module.js:580:10)
  at Module.load (module.js:503:32)
  at tryModuleLoad (module.js:466:12)
  at Function.Module._load (module.js:458:3)

errno: -13,
code: 'EACCES',
syscall: 'mkdir',
path: '/usr/local/lib/node_modules/@angular/cli/node_modules/node-sass/vendor' }

> grpc@1.3.8 install /usr/local/lib/node_modules/firebase-tools/node_modules/grpc > node-pre-gyp install --fallback-to-build --library=static_library
node-pre-gyp ERR! Tried to download(undefined): https://storage.googleapis.com/grpc-precompiled-binaries/node/grpc/v1.3.8/node-v57-linux-x64.tar.gz node-pre-gyp ERR! Pre-built binaries not found for grpc@1.3.8 and node@8.1.2 (node-v57 ABI) (falling back to source compile with node-gyp)
gyp WARN EACCES user "undefined" does not have permission to access the dev dir "/root/.node-gyp/8.1.2" gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp"
gyp WARN EACCES user "nobody" does not have permission to access the dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp/8.1.2" gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp"
gyp WARN EACCES user "nobody" does not have permission to access the dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp/8.1.2" gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp"
gyp WARN EACCES user "nobody" does not have permission to access the dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp/8.1.2" gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp"
gyp WARN EACCES user "nobody" does not have permission to access the dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp/8.1.2" gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/local/lib/node_modules/firebase-tools/node_modules/grpc/.node-gyp"
(infinite loop)
Run Code Online (Sandbox Code Playgroud)

Gus*_*uss 42

问题是因为虽然NPM以nobody用户身份运行全局安装的模块脚本,但哪种有意义,最新版本的NPM开始将节点模块的文件权限设置为root.因此,不再允许模块脚本在其模块中创建文件和目录.

有关参考资料,请参阅NPM问题#3849中的讨论.

在docker环境中有意义的简单解决方法是将NPM默认全局用户设置回root,如下所示:

npm -g config set user root
Run Code Online (Sandbox Code Playgroud)

之后你不应再有任何EACCES错误.

  • 或者也使用 ```npm -g config set user $USER``` 对我有用,因为我真的希望我的用户成为默认用户,而不是 root。 (4认同)

kai*_*ser 13

不要将用户设置为root或使用--unsafe-perm

\n

只需使用node当前官方提供的用户即可(例如alpine)图像即可。

\n

评论过Dockerfile如下:

\n
FROM node:15.5-alpine\n\n#  Security: do not use the `root` user.\nENV USER=node\n\n# You can not use `${USER}` here, but reference `/home/node`.\nENV PATH="/home/node/.npm-global/bin:${PATH}"\n#  The `--global` install dir\nENV NPM_CONFIG_PREFIX="/home/node/.npm-global"\n\n# All subsequent commands are run as the `node` user.\nUSER "${USER}"\n\n# Pre-create the target dir for global install.\nRUN mkdir -p "${NPM_CONFIG_PREFIX}/lib"\n\nWORKDIR /usr/src/app\n\nCOPY package.json package-lock.json ./\n\n#  Configure NPM, so pkg get installed with correct credentials.\n# Avoids `chmod u+x $DIR` and other workarounds.\nRUN npm --global config set user "${USER}" \\\n    && npm --global --quiet --no-progress install \\\n    && npm cache clean --force\n
Run Code Online (Sandbox Code Playgroud)\n

@gabriel-araujo 答案的扩展版本。

\n

您可以通过文件中进行配置来代替通过 CLI flags( )设置用户。放置在项目根文件中或直接从npm --global config set user "${USER}".npmrcuser=node.npmrcDockerfile.

\n
RUN echo "user=node" > "${NPM_CONFIG_PREFIX}/etc/.npmrc"\n
Run Code Online (Sandbox Code Playgroud)\n

如果您使用docker-compose.yml,您可以将其添加为environment: - \xe2\x80\xa6变量。

\n

希望这可以帮助您在某个地方运行更安全的 NodeJS 容器并获得一些很棒的东西。

\n


Gab*_*ujo 7

我可以通过更改默认的 npm-global 目录来使其工作。

现在这是我的 dockerfile:

FROM node:latest
USER node

RUN mkdir /home/node/.npm-global
ENV PATH=/home/node/.npm-global/bin:$PATH
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global

RUN npm install --quiet --no-progress -g @angular/cli@latest firebase-tools
RUN npm cache clean --force
Run Code Online (Sandbox Code Playgroud)

  • 你应该接受你自己的答案。目前接受的答案建议使用“root”,并获得了太多的赞成票。 (3认同)

Csa*_*oth 5

使用--unsafe-perm标志:

npm install --quiet --no-progress --unsafe-perm -g @angular/cli@latest firebase-tools
Run Code Online (Sandbox Code Playgroud)

我认为这比将npm用户永久设置为root 更好。您只能使用--unsafe-perm会导致问题的软件包