【问题标题】:Running an update script from parent node process (PM2, NodeJS)从父节点进程(PM2、NodeJS)运行更新脚本
【发布时间】:2016-08-31 15:48:53
【问题描述】:

我有一个名为 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');
});

【问题讨论】:

  • 您可以尝试使用& or hupup 在子shell 中启动pm2 delete 命令,例如:pm2 delete "Some App" | tee update.log & 一旦文件被写入子进程,将被删除而不是原来的bash进程并希望执行将继续。

标签: node.js bash shell express pm2


【解决方案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 依次向后台运行的所有作业发送 SIGHUP。使用 nohup 运行作业可以防止它在终端死机时以这种方式被杀死(例如,如果您远程登录并且连接断开,或者您关闭了终端模拟器)。

参考:

更新 - 简单测试

我做了一个简单的测试,在pm2 delete之后bash没有退出。

dummy-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

【讨论】:

  • @iLoveUnicorns 我创建了一个简单的测试,pm2 delete 并没有杀死 bash
  • @iLoveUnicorns admin.js 是服务器的一部分吗??
  • @iLoveUnicorns 我在答案中添加了 3 个参考链接。
猜你喜欢
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多