我想在 Debian (Jessie) 上运行带有 daemontools 的 Node.js 服务器,但我运行的脚本supervise
不断重新启动。这是我正在使用的运行脚本 ( /etc/service/node/run
):
#!/bin/bash
exec setuidgid nodeuser bash -c './node'
该脚本以 user 身份执行以下脚本nodeuser
,我在其中加载 NVM,更改到我的代码目录,并执行 Node.js 服务器:
#!/bin/bash
# Load NVM because we are in a non-interactive shell
export NVM_DIR="/home/nodeuser/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
# Run server
cd /path/to/code
exec node server.js
当我使用 启动服务时sudo svc -u /etc/service/node
,进程始终重新启动并ps faux
显示以下进程层次结构(层次结构的深度始终在变化):
/bin/sh /usr/bin/svscanboot /etc/service/
\_ svscan /etc/service
\_ supervise node
\_ /bin/bash ./node
\_ /bin/bash ./node
\_ /bin/bash ./node
\_ /bin/bash ./node
\_ /bin/bash ./node
| \_ /bin/bash ./node
| \_ /bin/bash ./node
| | \_ /bin/bash ./node
| | \_ /bin/bash ./node
| \_ /bin/bash ./node
| \_ tail -n1
\_ /bin/bash ./node
\_ tail -n1
你知道那里发生了什么吗?当我使用 手动执行脚本时./run
,服务器按预期启动并在控制台中显示其输出。
编辑
我发现该服务只有在重新启动后才能工作。一旦我用 重新启动它sudo svc -du /etc/service/node
,它的行为就像上面描述的那样。
答案1
那个脚本是错误的。 daemontools 系列的格言是执行的程序./run
必须是服务进程本身,而不是其父母、祖父母或其他亲戚。服务是运行的,而不是生成的。
在最后一行使用exec
是正确的想法,但会被以下显式使用所破坏bash -c
。无论如何,这是不必要的,因为该./node
脚本已#!/bin/bash
指定脚本解释器并且(可能)可执行。更好的
#!/bin/bash 执行 setuidgid 节点用户 ./node
这当然可以是一个nosh
(从同名工具集)或一个execlineb
脚本,因为并不真正需要重量级的 Bourne Again shell 来运行一个setuidgid
命令。因此:
#!/bin/nosh setuidgid 节点用户 。/节点或者
#!/command/execlineb -P s6-setuidgid 节点用户 。/节点
然后,当服务管理器响应 来关闭服务时svc -d
,它会将信号发送到正确的实际服务进程。
进一步阅读
- 希姆德尔(2013-07-24)。 使用 apache 和 daemontools 部署 Node.js。分段故障。
- 史蒂夫·坎普 (2014-01-04)。使用runit来维护服务。 Debian 管理。