从父节点进程(PM2,NodeJS)运行更新脚本

时间:2016-08-31 15:48:53

标签: node.js bash shell express pm2

我有一个名为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

现在我使用node(快速路由)运行此脚本。

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');
});

1 个答案:

答案 0 :(得分:1)

更新 - 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在忽略SIGHUP信号的情况下运行特定程序。当终端关闭时,内核将SIGHUP发送到该终端(即shell)中的控制进程。 shell又将SIGHUP发送给后台运行的所有作业。使用nohup运行作业可以防止在终端死机时以这种方式被杀死(例如,如果您远程登录并且连接断开,或者您关闭了终端仿真器)。

参考:

更新 - 简单测试

我做了一个简单的测试,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 "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