我正在我的 Nodejs Express 服务器上实现零停机部署。
我使用此脚本来执行更新:
//部署.sh
#!/bin/bash
set -e
LOG_FILE="deploy.log"
echo '📦 Fetching changes from server' >> "$LOG_FILE"
git pull >> "$LOG_FILE" 2>&1
echo '🛠️ Building project' >> "$LOG_FILE"
npm run build >> "$LOG_FILE" 2>&1
echo '♻️️ Reloading server' >> "$LOG_FILE"
pm2 reload server >> "$LOG_FILE" 2>&1
当我从终端运行它时,效果非常好。我的应用程序的所有工作和所有实例都已重新启动。
但是,当我从 Github 收到新代码可用的 Webhook 时,我想运行它。我这样做:
app.post('/git-push', async (req, res) => {
let start = new Date().toISOString();
console.log(`🚢 Server deployment started ${start}`)
const deployScript = spawn('bash', ['scripts/deploy.sh'], {
cwd: process.cwd(),
detached: true,
stdio: 'ignore'
});
deployScript.unref()
res.status(200).json({message: `ok ${start}`});
})
bash 脚本运行到
pm2 reload server
时没有问题。但在重新加载期间,我看到请求开始但没有完成。
部署.log
// other logs from the other commands
♻️️ Reloading server
Use --update-env to update environment variables
[PM2] Applying action reloadProcessId on app [server](ids: [
0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11,
12, 13, 14, 15
])
如果我这样做
pm2 list
,我还会看到只有少数实例重新启动,但不是全部。如果我从终端手动执行 pm2 reload server
(在 Webhook 之后),我会收到此错误,表明重新加载尚未完成,我应该稍后再试一次。
如何确保我的 bash 脚本在 pm2 重新加载期间不会被中断?
通过创建一个专用的单独服务器来处理 Webhook 并部署新更改来解决此问题。
更新了
ecosystem.config.js
:
module.exports = {
apps: [
{
"name": "server",
"script": "./dist/src/server.js",
"instances": "3",
"exec_mode": "cluster",
"env": {"NODE_ENV": "production",},
out_file: "./logs/out.log",
error_file: "./logs/error.log",
merge_logs: true,
instance_var: 'APP_INSTANCE_SEQ',
},
{
"name": "autodeploy",
"script": "./dist/src/autodeploy.js",
"instances": "1",
out_file: "./logs/out.log",
error_file: "./logs/error.log",
merge_logs: true,
env: {
NODE_ENV: "production",
PORT: 4000,
}
}
]
}