如何在系统启动时启动Node.js应用程序?

14

我正在使用运行Raspbian的树莓派上运行Node.js应用程序,并尝试在树莓派启动时启动它。我找到了一些例子,但好像无法使其正常工作。我的当前代码如下:

#! /bin/sh
# /etc/init.d/MyApp

### BEGIN INIT INFO
# Provides:          MyApp.js
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts MyApp.js
# Description:       Start / stop MyApp.js at boot / shutdown.
### END INIT INFO

# If you want a command to always run, put it here

# Carry out specific functions when asked to by the system
case "$1" in
   start)
    echo "Starting MyApp.js"
    # run application you want to start
    node /home/pi/app/MyApp/MyApp.js
   ;;
   stop)
    echo "Stopping MyApp.js"
    # kill application you want to stop
    killall MyApp.js
    ;;
  *)
    echo "Usage: /etc/init.d/MyApp {start|stop}"
    exit 1
    ;;
esac

exit 0

我把脚本放在 etc/init.d 文件夹下,并运行了 chmod +x /etc/init.d/MyApp 命令,能够手动运行脚本,在运行了sudo update-rc.d MyApp defaults命令后重启,但脚本从未运行。我查看了一些不同的示例,做出了一些调整,但仍然没有成功。

3个回答

32

我通过首先检查RaspberryPi上安装了node.js的位置来解决这个问题:

which node

这让我感到:

/usr/local/bin/node

打开crontab配置:

sudo crontab -e

然后在我的crontab中:

@reboot sudo /usr/local/bin/node <complete path to your .js app> &

保存,重新启动,问题解决!


愚蠢的问题:>> & 是什么意思?它对我来说会导致错误。 - JeffThompson
@JeffThompson,">>" 是一个打字错误。请省略尖括号。 - Mister Tea

11

Mohit是正确的,但只是为了澄清,您可以使用readlink来查找Node.js应用程序的完整路径,因为稍后需要将其添加为cron作业。

readlink -f <<name of file >>

例如,readlink -f HAP-NodeJS/Core.js 的结果是 /home/pi/HAP-NodeJS/Core.js

您还可以使用 which node 查找安装node.js的完整路径

接下来,使用sudo crontab -e创建一个新的cron作业,并在最后添加以下代码:

@reboot sudo /usr/local/bin/node <<.js application path>> &

例如,我的代码看起来像这样。

@reboot sudo /usr/local/bin/node /home/pi/HAP-NodeJS/Core.js &

在重新启动(或开机)后,您的Node.js应该运行。希望这可以澄清问题。


感谢您详细解答! - Mar
它对我不起作用,我完全按照相同的步骤操作了。我正在使用xrdp远程工作,这会有任何影响吗? - Tony

4
如果您正在使用类似 0.10.24 的预构建 Pi 版本,则可能会遇到 PATH 问题。
您可以在 start 命令中提供 node 二进制文件的完整路径,或者确保在运行 /etc/init.d/MyApp 之前设置了指向 node 二进制文件的 PATH。我也遇到了同样的问题,并尝试了这两种方法都成功了。此外,您现有的 stop 命令可能无法正常工作。
#! /bin/sh
# /etc/init.d/test

### BEGIN INIT INFO
# Provides:          test
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO

# Carry out specific functions when asked to by the system
case "$1" in
   start)
    echo "Starting test.js"
    # run application you want to start
    #node /home/pi/test.js > /home/pi/test.log
    /home/pi/downloads/node-v0.10.24-linux-arm-pi/bin/node /home/pi/test.js >> /home/pi/test.log
   ;;
   stop)
    echo "Stopping test.js"
    # kill application you want to stop
    killall -9 node
    # Not a great approach for running
    # multiple node instances
    ;;
  *)
    echo "Usage: /etc/init.d/test {start|stop}"
    exit 1
    ;;
esac

exit 0

如果您想要执行sudo node,可以使用sudo visudo将路径添加到Defaults secure_path中。此外,我建议使用类似forever的工具,在崩溃后保持进程运行。

当您尝试手动启动时,是否执行sudo /etc/init.d/MyApp start命令?这就是我确定我遇到了路径问题的方法。 - Kevin Reilly
正确。我正在调用 sudo /etc/init.d/MyApp start - user2650875
尝试了两种方式 Provides: MyApp.jsProvides: MyApp,但行为没有改变。 - user2650875
糟糕,我没什么头绪了。除非尝试一个超级简单的应用程序,比如一个小型Web服务器示例。我有一个经过验证工作的测试示例,如果你想尝试一下可以给你。也许只有通过init.d启动应用程序时才会出现错误。 - Kevin Reilly
1
哦,我刚意识到在这种情况下使用 >> 比 > 更好,因为它会将日志附加到现有的日志文件中,而不是创建一个新的。这可能可以解释你所说的覆盖场景。 - Kevin Reilly
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接