docker镜像上的npm全局安装没有访问权限错误

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

这是我的Dockerfile:

FROM node:latest USER root RUN npm install --quiet --no-progress -g @angular/cli@latest firebase-tools RUN npm cache clean --force 

这是输出:

 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) 

问题是因为当NPM作为nobody用户运行全局安装的模块脚本时,最新版本的NPM开始将节点模块的文件权限设置为root 。 因此模块脚本不再允许在其模块中创build文件和目录。

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

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

 npm -g config set user root 

之后你不应该有更多的EACCES错误。

我能够通过更改默认的npm全局目录来得到它的工作。

这是我的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