Jenkins在Docker镜像内执行npm install返回exit code 243报错
问题背景
在Docker镜像内运行的Jenkinsfile中执行命令sh "cd ./src/common && npm install"时失败,相同命令在非Docker环境可正常运行,业务要求必须基于Docker镜像执行。
执行失败时Jenkins输出日志如下:
18:56:46 + cd ./src/common 18:56:46 + npm install 18:56:46 [Pipeline] } 18:56:46 $ docker stop --time=1 02b60e1ac63b72e7a57356249d7ba48b720bf6f0c7df2addd20b7a2d45201ef5 18:56:48 $ docker rm -f 02b60e1ac63b72e7a57356249d7ba48b720bf6f0c7df2addd20b7a2d45201ef5 [Pipeline] // withDockerContainer [Pipeline] } [Pipeline] // stage [Pipeline] echo 18:56:48 Exception: hudson.AbortException: script returned exit code 243 [Pipeline] error [Pipeline] } [Pipeline] // node [Pipeline] } [Pipeline] // timestamps [Pipeline] End of Pipeline ERROR: hudson.AbortException: script returned exit code 243
本次使用的Docker镜像对应Dockerfile内容如下:
FROM node:16 ENV PROJECT_DIR /usr/local/bin/src/oppt WORKDIR ${PROJECT_DIR} RUN apt-get update -y RUN apt-get install zip -y RUN apt-get install curl -y RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" RUN unzip awscliv2.zip RUN ./aws/install COPY . ${PROJECT_DIR}/
已完成的初步排查:
- 尝试将执行命令修改为
sh(script: """ #!/bin/bash pushd ./src/common && npm install && popd"""),切换目录执行后仍然失败 - 确认故障点出在
npm install步骤,但该步骤无任何错误信息输出,Jenkins日志无相关报错记录 - 通过
ls命令确认./src/common目录下存在预期的package.json和package-lock.json文件 - 正常执行
npm install应当生成node_modules目录并安装依赖,当前执行后未生成该目录 - 常规IO权限问题、包文件损坏问题都会输出对应错误提示,但当前日志无相关记录
排查方向与解决方案
1. 优先解决日志无输出问题
非交互tty环境下npm默认开启输出缓冲,进程异常退出时缓冲内容不会刷出,是看不到报错的核心原因。
先修改执行命令,打开npm全量调试日志、关闭进度条缓冲,同时打印当前执行身份、目录权限信息方便定位:
sh ''' # 打印当前执行用户、目录权限 id ls -la ./src/common # 配置npm参数,关闭缓冲、打开全量日志 npm config set loglevel silly npm config set progress false # 切换目录执行安装,root用户下追加--unsafe-perm参数 cd ./src/common npm install --unsafe-perm '''
执行后即可看到npm的完整运行日志,直接定位具体报错点。
2. 修复Docker与Jenkins挂载的权限问题
Jenkins的withDockerContainer步骤默认会将Jenkins节点的当前工作区,挂载到Dockerfile中定义的WORKDIR路径,直接覆盖Dockerfile里COPY到该路径的所有文件,原Dockerfile里的COPY步骤实际不会生效,只会增加镜像体积。
此时常见权限问题分两种:
- 容器默认以root用户执行npm:npm默认禁止root用户执行安装生命周期脚本,不加
--unsafe-perm参数会静默退出,上述命令里已经追加该参数即可解决 - 容器默认以node用户(node:16镜像内置的普通用户,uid=1000)执行npm:如果挂载的工作区目录属主是Jenkins节点上的其他uid用户,会导致npm无写入权限,此时选一种方式修复即可:
- 在Jenkins流水线配置docker运行参数,指定以root用户运行:
docker { image '你的镜像地址' args '-u root' } - 在Dockerfile中提前给工作目录授权,新增对应行:
RUN chown -R node:node ${PROJECT_DIR}
- 在Jenkins流水线配置docker运行参数,指定以root用户运行:
3. 排查进程被异常终止的问题
日志中npm install执行后立刻触发docker stop --time=1,exit code 243为进程收到终止信号后的退出码,常见触发原因:
- 容器内存配额不足:npm安装依赖时内存占用较高,如果容器配置的内存小于2G很容易被系统OOM杀掉,且不会留下应用层日志,在docker运行参数中追加内存配置即可,例如
args '-u root --memory=4g'分配4G内存 - 网络超时:默认npm公网源在企业内网/受限网络环境下容易出现连接超时,进程僵死后被Jenkins的超时机制杀掉,执行安装前切换到内部可用的npm镜像源即可
- 插件版本bug:旧版本的Docker Pipeline插件存在误判步骤执行完成、提前终止容器的问题,升级插件到最新稳定版即可验证。
内容的提问来源于stack exchange,提问作者Kenobi
相关产品推荐
相关产品推荐

