运行 来自父节点进程(PM2、NodeJS)的更新脚本
Running an update script from parent node process (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 "Retrieving 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
现在我运行这个脚本使用节点(快速路由)。
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
允许子进程 运行 即使父进程被杀死。
引自https://unix.stackexchange.com/questions/137759/why-use-nohup-rather-than-exec :
nohup runs the specificed program with the SIGHUP signal ignored. When a terminal is closed, the kernel sends SIGHUP to the controlling process in that terminal (i.e. the shell). The shell in turn sends SIGHUP to all the jobs running in the background. Running a job with nohup prevents it from being killed in this way if the terminal dies (which happens e.g. if you were logged in remotely and the connection drops, or if you close your terminal emulator).
参考:
更新 - 简单测试
我做了一个简单的测试,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
是 deleting/changing 停止前的服务器目录。有时这会造成 unexpected/strange 行为。
我修改了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 "Retrieving 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
我有一个名为 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 "Retrieving 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
现在我运行这个脚本使用节点(快速路由)。
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
允许子进程 运行 即使父进程被杀死。
引自https://unix.stackexchange.com/questions/137759/why-use-nohup-rather-than-exec :
nohup runs the specificed program with the SIGHUP signal ignored. When a terminal is closed, the kernel sends SIGHUP to the controlling process in that terminal (i.e. the shell). The shell in turn sends SIGHUP to all the jobs running in the background. Running a job with nohup prevents it from being killed in this way if the terminal dies (which happens e.g. if you were logged in remotely and the connection drops, or if you close your terminal emulator).
参考:
更新 - 简单测试
我做了一个简单的测试,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
是 deleting/changing 停止前的服务器目录。有时这会造成 unexpected/strange 行为。
我修改了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 "Retrieving 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