GitLab CI运行NodeJS服务器卡住:任务未终止但Express服务已启动求助
GitLab CI任务卡住不终止?Express启动后的坑解决指南
哈哈,这个问题我太熟了!之前用GitLab CI的shell执行器部署Express的时候也踩过一模一样的坑——任务卡着不结束,但服务器明明已经跑起来了,核心原因其实很简单:
GitLab CI的shell执行器会一直等待当前脚本里的所有前台进程结束,才会标记任务完成。而你用npm start启动Express时,默认是前台运行的,这个进程会一直挂着,自然就把CI任务给“卡”住了。
下面分测试和部署两个场景给你针对性的解决方案:
一、解决test:async任务卡住的问题
测试阶段我们只需要服务器临时启动,跑完测试就可以关掉,所以关键是把服务器后台启动,测试完成后主动杀掉进程:
方案1:基础版(后台启动+sleep+杀进程)
直接用&把服务器放到后台,给点启动时间后跑测试,最后杀掉进程:
test:async: stage: test script: - npm run build # 先完成构建 - npm start & # 后台启动Express服务器 - sleep 5 # 给服务器留够启动时间,根据你的项目调整时长 - npm run test:async # 执行异步测试用例 - pkill -f "node build/bundle.js" # 杀掉服务器进程
方案2:更靠谱的版本(用wait-on代替sleep)
sleep是硬等,有时候服务器启动慢会导致测试失败,用wait-on工具可以监听端口,等服务器真正就绪后再跑测试:
test:async: stage: test script: - npm install wait-on --save-dev # 安装端口监听工具 - npm run build - npm start & - wait-on http://localhost:3000 # 等待服务器3000端口就绪(改成你实际的端口) - npm run test:async - pkill -f "node build/bundle.js"
二、解决deploy_staging任务卡住的问题
部署阶段我们需要服务器一直运行,这时候不能用前台启动,得用进程管理工具把Express变成后台守护进程,让CI任务能正常结束:
推荐用pm2(最常用的Node.js进程管理器),配置如下:
deploy_staging: stage: deploy script: - npm install pm2 -g # 全局安装pm2(如果已经装过可以跳过) - npm run build - pm2 stop bundle || true # 先停止之前的同名进程,|| true避免进程不存在时报错中断任务 - pm2 start build/bundle.js --name bundle # 启动服务器并命名为bundle - pm2 save # 可选:保存进程列表,服务器重启后自动恢复
pm2会把Express进程放到后台运行,CI脚本执行完这些命令就会正常结束,而服务器会持续运行在你的服务器上。
额外注意点
- 如果服务器用户没有全局安装npm包的权限,可以用
npx pm2 ...代替全局安装 - 用
pkill的时候要确保进程名唯一,比如你的脚本是node build/bundle.js,这个标识要准确,避免误杀其他Node.js进程 - 测试阶段的端口要和Express实际监听的端口一致,不然wait-on会一直等下去
内容的提问来源于stack exchange,提问作者ManifoldFR
相关产品推荐
相关产品推荐

