OpenShift构建Dockerfile时npm install报exit status 232(EMFILE: too many open files)求助
OpenShift构建Dockerfile时npm install报exit status 232(EMFILE: too many open files)求助
我太懂你这种本地跑好好的,一到OpenShift就出奇怪问题的挫败感了!这个EMFILE错误本质是构建容器里的文件句柄(file descriptor)上限太低,npm install过程中会并发打开大量缓存文件、包文件,超过限制就触发了这个报错。下面给你几个靠谱的解决方案,按从易到难的顺序试试:
1. 清理npm缓存+限制npm并发数
这是最直接的快速尝试方案,把你Dockerfile里的RUN npm i改成:
RUN npm cache clean --force && npm i --maxsockets 4
npm cache clean --force直接清空旧缓存,避免缓存目录里堆积过多文件句柄占用--maxsockets 4强制npm降低并发下载/安装的连接数,减少同时打开的文件数量,刚好避开OpenShift默认的句柄限制
2. 提高构建容器的文件句柄上限
如果上面的方法还不够,那就要直接调整OpenShift构建容器的资源限制了。用oc命令修改你的BuildConfig:
oc patch bc/你的构建配置名称 --type='json' -p='[{"op": "add", "path": "/spec/resources/limits", "value": {"openshift.io/file-descriptors": "8192"}}]'
这个操作会把构建容器的文件句柄上限调到8192(默认可能只有1024或者4096),足够npm install折腾了。你也可以直接编辑BuildConfig的YAML文件,在spec.resources.limits里添加这个配置。
3. 用npm ci代替npm i(如果你有package-lock.json)
npm ci的安装行为更可控,严格按照lock文件执行,不会生成新的lock文件,并发操作也比npm i更收敛,能进一步减少文件句柄的使用。修改成:
RUN npm cache clean --force && npm ci --maxsockets 4
注意前提是你的项目里已经有package-lock.json或者yarn.lock(如果用yarn的话)。
4. 切换到非root用户构建(符合OpenShift最佳实践)
OpenShift对root用户的资源限制会更严格,切换到node镜像自带的普通用户(一般是node用户),既能避开部分权限限制,也更安全。修改Dockerfile:
WORKDIR /usr/src/app # 先把工作目录权限改成node用户可写 RUN chown -R node:node /usr/src/app USER node COPY package.json ./ RUN npm cache clean --force && npm i --maxsockets 4
先从第一个方案试起,大多数情况下清理缓存+限制并发就能解决问题,如果不行再依次尝试后面的方法。
备注:内容来源于stack exchange,提问作者Haider Ali
相关产品推荐
相关产品推荐

