从父节点进程(PM2,NodeJS)运行更新脚本
我有一个名为update.sh的脚本更新服务器。
问题在于; 当我停止PM2进程时,它结束了bash进程(?)。
我无法弄清楚如何从没有链接到父级的父级产生一个进程。 :-S
update.sh
#!/bin/bash # Check we are not already updating. if [ -f update.lock ]; then echo "Already updating. Locked." exit fi # Make the log file. rm update.log touch update.log # Create update lock. touch update.lock echo "Cleaning up" | tee update.log rm -rf the-last-word rm -rf Server echo "Retreving files from BitBucket" | tee update.log git clone git@bitbucket.org:dotdot/dot-project.git # Remove all directories except Server (So we don't have game source code on the Server) echo "Removing game source code" | tee update.log cd the-last-word # Move the Server directory one up. mv Server ../ cd ../ rm -rf the-last-word # Stop the previous server. # == PM2 stop some server name. echo "Stopping server & removing" | tee update.log pm2 delete "Some App" | tee update.log # Update the current & run. echo "Installing node modules" | tee update.log cd Server npm install | tee update.log # Start the server again # == PM2 start some server name. echo "Starting node server" | tee update.log NODE_ENV=production pm2 start bin/www.js --name "Some App" | tee update.log # Remove lock file. cd .. rm update.lock
现在我使用节点(express route)运行这个脚本。
admin.js
// Update server app.use("/admin/update", authMiddleware, function(req, res, next) { console.log('Updating server from script.'); const { spawn } = require('child_process'); const deploySh = spawn('sh', [ 'update.sh' ], { cwd: '/www/thelastword/', env: Object.assign({}, process.env, { PATH: process.env.PATH + ':/usr/local/bin' }) }); res.status(200).json('Updating Server'); });
更新 – nohup
如果admin.js
是服务器进程的一部分,请尝试nohup
const deploySh = spawn('sh', [ 'nohup ./update.sh' ], { cwd: '/www/thelastword/', env: Object.assign({}, process.env, { PATH: process.env.PATH + ':/usr/local/bin' }) });
nohup
甚至允许subprocess运行,甚至父母被杀害。
从https://unix.stackexchange.com/questions/137759/why-use-nohup-rather-than-exec引用:
nohup运行SIGHUP信号被忽略的特定程序。 当一个terminalclosures时,内核发送SIGHUP给该terminal的控制进程(即shell)。 Shell将SIGHUP发送到在后台运行的所有作业。 使用nohup执行作业可防止terminal死机(例如,如果您已远程login且连接断开或closuresterminal仿真程序),以此方式终止该作业。
参考:
更新 – 简单的testing
我做了一个简单的testing,bash在pm2 delete
后没有退出。
伪server.js
var pid = require('process').pid; var server = require('net').createServer().listen();
test.sh
echo "start dummy." pm2 start ./dummy-server.js --name 'Dummy' echo "stop dummy." pm2 delete 'Dummy' echo "Sleep 5sec" sleep 5 echo "Done."
输出:
start dummy. [PM2] Starting ./dummy-server.js in fork_mode (1 instance) [PM2] Done. ┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ ├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤ │ Dummy │ 0 │ fork │ 9328 │ online │ 0 │ 0s │ 15.219 MB │ disabled │ └──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘ Use `pm2 show <id|name>` to get more details about an app stop dummy. [PM2] Applying action deleteProcessId on app [Dummy](ids: 0) [PM2] [Dummy](0) ✓ ┌──────────┬────┬──────┬─────┬────────┬─────────┬────────┬────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ └──────────┴────┴──────┴─────┴────────┴─────────┴────────┴────────┴──────────┘ Use `pm2 show <id|name>` to get more details about an app Sleep 5sec Done.
update.sh
在停止之前删除/更改服务器目录。 有时候会造成意想不到的/奇怪的行为。
我修改update.sh
如下:
#!/bin/bash # Check we are not already updating. if [ -f update.lock ]; then echo "Already updating. Locked." exit fi # Make the log file. rm update.log touch update.log # Create update lock. touch update.lock # --- Stop server before deleting its directory! # Stop the previous server. # == PM2 stop some server name. echo "Stopping server & removing" | tee update.log pm2 delete "Some App" | tee update.log echo "Cleaning up" | tee update.log rm -rf the-last-word rm -rf Server echo "Retreving files from BitBucket" | tee update.log git clone git@bitbucket.org:dotdot/dot-project.git # Remove all directories except Server (So we don't have game source code on the Server) echo "Removing game source code" | tee update.log cd the-last-word # Move the Server directory one up. mv Server ../ cd ../ rm -rf the-last-word # Update the current & run. echo "Installing node modules" | tee update.log cd Server npm install | tee update.log # Start the server again # == PM2 start some server name. echo "Starting node server" | tee update.log NODE_ENV=production pm2 start bin/www.js --name "Some App" | tee update.log # Remove lock file. cd .. rm update.lock