You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重启Supervisor任务时Nuxt 3服务器未终止致端口占用求助

问题

我为Nuxt应用搭建了生产环境,通过Supervisor运行Nuxt服务器。端口未被占用时启动正常,但执行supervisorctl reload或supervisorctl restart production-frontend时,旧的Nuxt服务器进程经常无法退出,导致重启时因端口占用启动失败,不想用kill -9手动清理残留进程。

当前Supervisor配置文件/etc/supervisor/conf.d/production-frontend.conf内容:

[program:production-frontend]
command=/usr/bin/npm start
directory=/var/www/production/frontend
environment=NODE_ENV="production",PORT="3011"
autostart=true
autorestart=true
startretries=10
startsecs=30
user=www-data
stderr_logfile=/var/log/supervisor/production-frontend_error.log
stdout_logfile=/var/log/supervisor/production-frontend_out.log

项目目录/var/www/production/frontend包含npm run build生成的.output文件夹和package.json,npm run start实际执行node .output/server/index.mjs启动Nuxt服务器。

启动失败时错误日志:

[nitro] [dev] [uncaughtException] Error: listen EADDRINUSE: address already in use :::3011

执行netstat -pln | grep 3011能看到残留的Nuxt进程。


解决方案

1. 让Supervisor同步终止进程组

问题核心是npm start作为父进程,可能未将Supervisor的终止信号转发给Node子进程。在Supervisor配置中添加以下参数:

stopasgroup=true
killasgroup=true
  • stopasgroup=true:终止主进程时,连带所有子进程一起停止
  • killasgroup=true:若进程无响应,向整个进程组发送强制终止信号,避免残留

2. 直接启动Node进程,跳过npm中间层

npm作为中间进程会干扰信号传递,直接执行Node命令更可靠:
修改配置里的command字段:

command=/usr/bin/node .output/server/index.mjs

保留原环境变量配置,让Supervisor直接管理Node进程,信号传递无损耗。

3. 配置Nuxt/Nitro优雅关闭逻辑

Nuxt基于Nitro构建,默认优雅关闭机制可能不足。在nuxt.config.ts中添加配置:

export default defineNuxtConfig({
  nitro: {
    handlers: {
      'SIGTERM': () => {
        console.log('收到SIGTERM信号,开始优雅关闭');
        process.exit(0);
      }
    },
    shutdownTimeout: 5000 // 设置5秒优雅关闭超时时间
  }
});

修改后重新执行npm run build,让配置生效。

4. 明确Supervisor的终止规则

在配置中补充以下参数,规范终止流程:

stopsignal=TERM
stopwaitsecs=10
  • stopsignal=TERM:默认发送TERM信号,优先尝试优雅关闭
  • stopwaitsecs=10:等待10秒后,若进程未退出则强制终止

最终优化后的完整配置

整合所有优化点后的配置文件:

[program:production-frontend]
command=/usr/bin/node .output/server/index.mjs
directory=/var/www/production/frontend
environment=NODE_ENV="production",PORT="3011"
autostart=true
autorestart=true
startretries=10
startsecs=30
user=www-data
stderr_logfile=/var/log/supervisor/production-frontend_error.log
stdout_logfile=/var/log/supervisor/production-frontend_out.log
stopasgroup=true
killasgroup=true
stopsignal=TERM
stopwaitsecs=10

内容的提问来源于stack exchange,提问作者Sumurai8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:55:30