Docker中运行nodemon按Ctrl+C无法立即退出,求解决方案
Docker中使用nodemon按下Ctrl+C无法立即关闭容器的问题解决
我的项目在Docker中使用nodemon运行正常,但按下Ctrl+C停止进程时,容器无法立即关闭,需等待10秒才会终止。以下是最小复现示例:
复现文件
docker-compose.yml
version: "3.8" services: node: build: ./ volumes: - ./src:/app/src
Dockerfile
FROM node:18-bullseye-slim WORKDIR /app COPY package.json . RUN npm i CMD [ "npm", "run", "start" ]
package.json
{ "scripts": { "dev": "docker compose up --build", "start": "nodemon src/script.js" }, "devDependencies": { "nodemon": "^3.0.2" } }
src/script.js
console.log("Hello world!");
现象说明
正常运行情况
执行npm run dev时运行正常:
$ npm run dev > dev > docker compose up --build [+] Building 0.1s (9/9) FINISHED docker:desktop-linux => [node internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [node internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 136B 0.0s => [node internal] load metadata for docker.io/library/node:18-bull 0.0s => [node 1/4] FROM docker.io/library/node:18-bullseye-slim 0.0s => [node internal] load build context 0.0s => => transferring context: 183B 0.0s => CACHED [node 2/4] WORKDIR /app 0.0s => CACHED [node 3/4] COPY package.json . 0.0s => CACHED [node 4/4] RUN npm i 0.0s => [node] exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:49c76459b45682e7c3fd7005371f53df516b52ee 0.0s => => naming to docker.io/library/test-node 0.0s [+] Running 1/1 ✔ Container test-node-1 Recreated 0.1s Attaching to test-node-1 test-node-1 | test-node-1 | > start test-node-1 | > nodemon src/script.js test-node-1 | test-node-1 | [nodemon] 3.0.2 test-node-1 | [nodemon] to restart at any time, enter `rs` test-node-1 | [nodemon] watching path(s): *.* test-node-1 | [nodemon] watching extensions: js,mjs,cjs,json test-node-1 | [nodemon] starting `node src/script.js` test-node-1 | Hello world! test-node-1 | [nodemon] clean exit - waiting for changes before restart
关闭时的问题
按下Ctrl+C退出时,需等待10秒:
^CGracefully stopping... (press Ctrl+C again to force) Aborting on container exit... [+] Stopping 1/1 ✔ Container test-node-1 Stopped 10.1s canceled
问题根源
当用npm run启动nodemon时,npm会作为父进程,它不会默认转发SIGINT信号给子进程nodemon,导致Docker发送的终止信号无法被nodemon捕获,最终Docker只能等待默认10秒超时后强制杀死容器。
解决方案
方案1:直接启动nodemon,绕过npm
修改Dockerfile的CMD,直接调用nodemon,让它成为容器的PID 1进程,直接接收信号:
FROM node:18-bullseye-slim WORKDIR /app COPY package.json . RUN npm i CMD [ "npx", "nodemon", "src/script.js" ]
方案2:让npm转发信号
修改package.json的start脚本,用exec命令替换当前npm进程为nodemon进程,确保信号能传递:
{ "scripts": { "dev": "docker compose up --build", "start": "exec nodemon src/script.js" }, "devDependencies": { "nodemon": "^3.0.2" } }
方案3:缩短Docker超时时间
在docker-compose.yml中添加stop_grace_period参数,缩短等待时长,作为临时解决手段:
version: "3.8" services: node: build: ./ volumes: - ./src:/app/src stop_grace_period: 1s
内容的提问来源于stack exchange,提问作者dodov
相关产品推荐
相关产品推荐

