如何通过 systemctl 部署 Nodejs Eggjs?

如何通过 systemctl 部署 Nodejs Eggjs?

通过命令行可以启动:

cqh[@cqh-MS-7A74](/user/cqh-MS-7A74):~/local_code/tscode/local_alarm$ npm run start

> [email protected] start /home/cqh/local_code/tscode/local_alarm
> egg-scripts start --daemon --title=egg-server-local_alarm

[egg-scripts] Starting egg application at /home/cqh/local_code/tscode/local_alarm
[egg-scripts] Run node /home/cqh/local_code/tscode/local_alarm/node_modules/egg-scripts/lib/start-cluster {"title":"egg-server-local_alarm","framework":"/home/cqh/local_code/tscode/local_alarm/node_modules/egg","baseDir":"/home/cqh/local_code/tscode/local_alarm"} --title=egg-server-local_alarm
[egg-scripts] Save log file to /home/cqh/logs
[egg-scripts] Wait Start: 1...
[egg-scripts] egg started on http://127.0.0.1:7001

service 文件

[Unit]
Description= local alarm service write by lua

[Service] Type=simple WorkingDirectory=/home/cqh/local_code/tscode/local_alarm ExecStart=/home/cqh/git/nvm/versions/node/v10.3.0/bin/npm run start User=cqh Restart=on-failure ExecStop=/home/cqh/git/nvm/versions/node/v10.3.0/bin/npm run stop

[Install] WantedBy=multi-user.target

但是通过 systemctl 无法启动 journalctl -xe显示

-- Subject: local_alarm_lua.service 单元已结束停止操作
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- local_alarm_lua.service 单元已结束停止操作。
8 月 06 10:51:01 cqh-MS-7A74 systemd[1]: Started local alarm service write by lua.
-- Subject: local_alarm_lua.service 单元已结束启动
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- local_alarm_lua.service 单元已结束启动。
-- 
-- 启动结果为“ done ”。
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]: /home/cqh/git/nvm/versions/node/v10.3.0/lib/node_modules/npm/bin/npm-cli.js:79
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:       let notifier = require('update-notifier')({pkg})
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:       ^^^
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]: SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at exports.runInThisContext (vm.js:53:16)
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at Module._compile (module.js:374:25)
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at Object.Module._extensions..js (module.js:417:10)
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at Module.load (module.js:344:32)
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at Function.Module._load (module.js:301:12)
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at Function.Module.runMain (module.js:442:10)
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at startup (node.js:136:18)
8 月 06 10:51:01 cqh-MS-7A74 npm[4792]:     at node.js:966:3
8 月 06 10:51:01 cqh-MS-7A74 systemd[1]: local_alarm_lua.service: Main process exited, code=exited, status=1/FAILURE
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]: /home/cqh/git/nvm/versions/node/v10.3.0/lib/node_modules/npm/bin/npm-cli.js:79
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:       let notifier = require('update-notifier')({pkg})
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:       ^^^
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]: SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at exports.runInThisContext (vm.js:53:16)
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at Module._compile (module.js:374:25)
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at Object.Module._extensions..js (module.js:417:10)
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at Module.load (module.js:344:32)
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at Function.Module._load (module.js:301:12)
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at Function.Module.runMain (module.js:442:10)
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at startup (node.js:136:18)
8 月 06 10:51:01 cqh-MS-7A74 npm[4808]:     at node.js:966:3
8 月 06 10:51:01 cqh-MS-7A74 systemd[1]: local_alarm_lua.service: Control process exited, code=exited status=1
8 月 06 10:51:01 cqh-MS-7A74 systemd[1]: local_alarm_lua.service: Unit entered failed state.
8 月 06 10:51:01 cqh-MS-7A74 systemd[1]: local_alarm_lua.service: Failed with result 'exit-code'.
8 月 06 10:51:01 cqh-MS-7A74 systemd[1]: local_alarm_lua.service: Service hold-off time over, scheduling restart.
8 月 06 10:51:01 cqh-MS-7A74 systemd[1]: Stopped local alarm service write by lua.
-- Subject: local_alarm_lua.service 单元已结束停止操作
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 

所以, 这个 service 到底该怎么写呢?


15 回复

你的 service 应该是放到 system 里的,然而你系统里默认 node 版本比较低,而你通过 nvm 安装的最新版本的 node 无法直接在 systemctl 里被用到,所有出现报错了。
解决方式,要么把最新版的 node 安装在全局里,要么把这个 service 放到 systemctl user 里,然后在设置正确的环境变量。

BTW: 你最好把项目里 package.json 里的 --daemon 参数去掉,由 systemctl 来管理。


如何吧 nvm 的 node 添加到环境变量里面呢?加 path 变量?但是我还是出错了。。

我现在已经加入了 PATH 变量, 但是还是出问题了, 大佬, 能给份 systemctl 启动 eggjs 的 demo 给我吗?

贴下最新的 service 和失败的日志

既然 npm 的路径都写死了,为什么不把 node 的路径一起写死呢 …

ExecStart=/path/to/node /path/to/npm run start

不过既然都用 systemd 了,不如直接把 ExecStart 的命令改成 npm script 中的 start 对应的命令

[Service]
Type=fork

推荐 Arch Wiki 和阮一峰的博客

已添加新的配置和错误日志

<br>[Unit]<br>Description= local alarm service write by eggjs<br><br>[Service]<br>Type=simple<br>WorkingDirectory=/home/cqh/local_code/tscode/local_alarm<br>ExecStart=npm run start<br>User=cqh<br>Restart=on-failure<br>ExecStop=npm run stop<br>Environment=PATH=/home/cqh/git/nvm/versions/node/v10.3.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin<br><br>[Install]<br>WantedBy=multi-user.target<br>

还是不行, 还是报,
<br>Executable path is not absolute, ignoring: npm run start<br><br>

呃,/尴尬

把 ExecStart 和 ExecStop 改回用绝对路径,PATH 里加上 /bin

<br>ExecStart=/home/cqh/git/nvm/versions/node/v10.3.0/bin/npm run start<br>ExecStop=/home/cqh/git/nvm/versions/node/v10.3.0/bin/npm run stop<br>Environment=/home/cqh/git/nvm/versions/node/v10.3.0/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin<br>

知道是怎么回事了, 原来 path 要加 /bin/sh 的 /bin;

有些发行版不需要加,比如 Arch Linux,它所有 bin 都是在 /usr/bin 里,/bin 只是一个指向 /usr/bin 的链接而已。

谢谢大佬指点

要通过 systemctl 部署 Node.js 和 Egg.js 应用,你可以按照以下步骤进行:

  1. 准备应用: 确保你的 Egg.js 应用已经开发完毕,并能在本地运行。通常,你的应用会有一个 npm startnpm run dev 命令来启动。

  2. 创建 systemd 服务文件: 在你的服务器上,创建一个 systemd 服务文件,比如 /etc/systemd/system/eggjs-app.service,内容如下:

    [Unit]
    Description=Egg.js Application
    After=network.target
    
    [Service]
    Type=simple
    User=your-username
    WorkingDirectory=/path/to/your/eggjs-app
    ExecStart=/usr/bin/node /path/to/your/eggjs-app/node_modules/.bin/egg-scripts start --title=egg-server-eggjs-app
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    

    注意替换 your-username/path/to/your/eggjs-app 为你的实际用户名和应用路径。

  3. 重新加载 systemd 配置

    sudo systemctl daemon-reload
    
  4. 启动并启用服务

    sudo systemctl start eggjs-app
    sudo systemctl enable eggjs-app
    
  5. 检查服务状态

    sudo systemctl status eggjs-app
    

这样,你的 Egg.js 应用就会通过 systemctl 来管理,包括启动、停止和重启。这种方式非常适合在生产环境中部署 Node.js 应用。

回到顶部