Nodejs 有没有好的方案从 Github 自动检测更新自动 pull 和部署应用?
Nodejs 有没有好的方案从 Github 自动检测更新自动 pull 和部署应用?
Git 管理代码比较习惯了, 每次都是手动 pull
和 forever restart
挺麻烦…
加上还要 ssh
服务器, VPS 网络有不稳定的时候,
学校里用的是 Gitlab… 部署和开发可能也不会是同一个人操作.
于是觉得 Git 自动部署会不错…
我原来想的办法只有 crontab
循环进行 pull
和 restart
, 但总重启不合适,
请问大家有用到有什么方案?
当然可以。你提到的需求可以通过使用 GitHub Actions 或者第三方服务如 Jenkins、Travis CI 来实现自动化部署。不过,如果你想用 Node.js 来实现一个自定义的解决方案,可以考虑以下方法。
方法一:使用 GitHub Webhooks
GitHub Webhooks 可以让你在仓库发生变化时自动触发事件。你可以设置一个 Webhook,当你的 GitHub 仓库有新的提交时,GitHub 会向你的服务器发送一个 POST 请求。然后,你的服务器接收到请求后可以执行一系列脚本,例如 git pull
和重启应用。
示例代码
- 创建一个简单的 Express 服务器 来接收 Webhook 请求:
const express = require('express');
const bodyParser = require('body-parser');
const { exec } = require('child_process');
const app = express();
app.use(bodyParser.json());
app.post('/github-webhook', (req, res) => {
const payload = req.body;
// Check if the event is a push event
if (payload.action === 'pushed') {
exec('cd /path/to/your/repo && git pull', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
// Restart your application
exec('pm2 restart your-app-name', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
});
}
res.status(200).send('OK');
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
- 在 GitHub 上配置 Webhook:
- 进入你的 GitHub 仓库的设置页面。
- 选择 “Webhooks” 选项卡。
- 点击 “Add webhook”。
- 在 “Payload URL” 中输入你的服务器地址(例如:
http://your-server.com/github-webhook
)。 - 选择 “Content type” 为
application/json
。 - 选择 “Just the push event”。
- 点击 “Add webhook”。
解释
- Express 服务器:我们使用 Express 创建了一个简单的 HTTP 服务器来监听来自 GitHub 的 POST 请求。
- GitHub Webhook:当仓库有新的提交时,GitHub 会向服务器发送一个 POST 请求。
- 执行命令:服务器接收到请求后,执行
git pull
命令拉取最新的代码,并使用pm2
重启应用。
这种方法简单且灵活,可以根据需要调整脚本逻辑。
github有提供一个服务,在项目有更新时,会自动回调指定的URL。
点项目的“Admin”按钮 => Service Hooks => WebHook URLs
搜了下 Git 可以设置 bare repo 从本地通过 ssh 直接推送到服务器, 并触发挂钩 http://yuguo.us/weblog/push-git-repository-to-server/ http://blog.meiweier.com/2012/08/09/利用git的hooks自动部署网站实践.html http://icyleaf.com/2010/09/apps-auto-deploy-with-git 不如一楼的 Git 好用, 但可以作为备选方案看下…
这么说是自己写 Shell 脚本, 然后用监听着 URL 的服务器调用脚本, 搜了下觉得比较考验人对 Bash 的熟悉度…
写了个小东西http://www.fancycoding.com/automatic-deploy-task-using-github-hooks/
钩子呗
要实现从 GitHub 自动检测更新、自动拉取并部署应用的功能,可以使用 GitHub Webhooks 结合 Node.js 来实现。这种方式不仅更高效,而且减少了手动操作的复杂性。
方案概述
- GitHub Webhook: 在 GitHub 仓库中设置一个 webhook,当有新的提交时,GitHub 会向你的服务器发送一个 HTTP POST 请求。
- Node.js 应用: 编写一个 Node.js 应用来接收 GitHub 的 webhook 请求,并处理相应的逻辑(如拉取最新代码、重启服务等)。
示例代码
以下是一个简单的 Node.js 示例代码,展示如何实现这一功能:
const express = require('express');
const { exec } = require('child_process');
const app = express();
app.use(express.json());
// 设置 GitHub webhook 的 secret,用于验证请求
const GITHUB_SECRET = 'your-secret';
app.post('/webhook', (req, res) => {
const signature = req.headers['x-hub-signature-256'];
const hmac = crypto.createHmac('sha256', GITHUB_SECRET);
const digest = `sha256=${hmac.update(JSON.stringify(req.body)).digest('hex')}`;
if (signature !== digest) {
return res.status(401).send('Unauthorized');
}
// 拉取最新的代码
exec('git pull', (error, stdout, stderr) => {
if (error) {
console.log(`Error: ${stderr}`);
return res.status(500).send('Failed to pull code');
}
console.log(`Pull successful: ${stdout}`);
// 重启应用
exec('pm2 restart your-app-name', (error, stdout, stderr) => {
if (error) {
console.log(`Error: ${stderr}`);
return res.status(500).send('Failed to restart app');
}
console.log(`App restarted successfully: ${stdout}`);
res.send('Deployed successfully!');
});
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
解释
- Express 应用: 使用 Express 创建一个简单的 HTTP 服务器来接收 GitHub 的 webhook 请求。
- 验证签名: 验证 GitHub 发送的 webhook 请求是否合法,以防止非法请求。
- 执行命令: 使用
exec
方法执行git pull
命令拉取最新代码,然后使用pm2 restart
命令重启应用。
GitHub Webhook 设置
- 登录到你的 GitHub 仓库。
- 进入
Settings
->Webhooks
。 - 添加一个新的 webhook,URL 设置为你的服务器地址(例如:
http://your-server.com/webhook
),Secret 设置为你在代码中配置的值。
通过这种方式,你可以实现自动化的代码部署流程,减少人工干预的复杂性和错误。