在向github提交代码后,我想将代码自动部署到一个开发板(没有公网IP)里

背景

最近准备把一个开发板用起来,想着做一个开发环境,用来部署前端和后端服务。于是开始调研如何在一块没有公网IP的开发板上做持续部署。

技术方案

由于代码时存储在github上的,部署是在办公室的开发板,连上了wifi,但没有公网ip,办法像服务器那样直接使用ssh进入服务器进行部署。

在开发板上做CD,我们主要解决两个问题,一是在提交代码后,如何触发部署的事件,可以使用GitHub Action,还有一种方法是使用GitHub的 WebHook。
另外一个难题是,在公网里如何知道开发板的IP,这个问题可以使用nodejs的包 localtunnel来解决。 https://localtunnel.github.io/www/

查看我之前的一篇文章 https://blog.csdn.net/github_35631540/article/details/139606085

配置

首先我们利用nodejs在 开发板里启动一个服务,
代码大致如下

// deploy-server.js
const express = require('express');
const crypto = require('crypto');
const { exec } = require('child_process');

const app = express();
const WEBHOOK_SECRET = '1234567'; // 需与GitHub设置一致
const PORT = 3300;

app.use(express.json());

app.post('/webhook', (req, res) => {
  // 1. 验证签名
  const sig = req.headers['x-hub-signature-256'];
  const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
  const digest = 'sha256=' + hmac.update(JSON.stringify(req.body)).digest('hex');
  console.log('webhook req: ')
  console.log(req)

  if (sig !== digest) {
    return res.status(403).send('Invalid signature');
  }

  // 2. 只处理push事件
  if (req.headers['x-github-event'] !== 'push') {
    return res.status(200).send('Ignored event');
  }

  // 3. 执行部署脚本
  exec('./deploy.sh', (error, stdout, stderr) => {
    if (error) {
      console.error(`部署失败: ${error}`);
      return res.status(500).send('Deployment failed');
    }
    console.log(`部署成功: ${stdout}`);
    res.status(200).send('Deployment succeeded');
  });
});

// 再写一个get请求
app.get('/hi', (req, res) => {
  res.send('Hello World!');
})

app.listen(PORT, () => {
  console.log(`Webhook服务运行在 http://localhost:${PORT}`);
});

deploy.sh 的内容

#!/bin/bash
echo "Deploying to devBoardCICD"
# cd /path/to/your/project
# git pull origin main
# npm install
# pm2 restart all # 如果使用pm2管理进程

启动服务,服务会在3300端口暴露出来。

然后再使用localtunnel 将其暴露到外网

运行 lt --port 3300

your url is: https://neat-walls-nail.loca.lt

这个地址是可以直接被webhook访问到的,并且不需要输入密码。

在github的仓库里 配置webhook,如https://github.com/PmcFizz/Lumos/settings/hooks
在这里插入图片描述

添加webhook时就这样配置,密钥,payload 地址。

在这里插入图片描述

测试

在webhook里 你可以获取非常多,非常详细的信息

 body: {
    ref: 'refs/heads/dev',
    before: '9287f85fd1655e359b63991436a730f6970d0af3',
    after: '2e6aca35db7f4d3ec433de794050d5f4d2498f09',
    repository: {
      id: 1007467682,
      node_id: 'R_kgDOPAy8og',
      name: 'xxxxx-admin',
      full_name: 'el-xxxxx/xxxxx-admin',
      private: true,
      owner: [Object],
      html_url: 'https://github.com/el-xxxxx/xxxxx-admin',
      description: null,
      fork: false,
      url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin',
      forks_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/forks',
      keys_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/keys{/key_id}',
      collaborators_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/collaborators{/collaborator}',
      teams_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/teams',
      hooks_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/hooks',
      issue_events_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/issues/events{/number}',
      events_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/events',
      assignees_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/assignees{/user}',
      branches_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/branches{/branch}',
      tags_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/tags',
      blobs_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/git/blobs{/sha}',
      git_tags_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/git/tags{/sha}',
      git_refs_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/git/refs{/sha}',
      trees_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/git/trees{/sha}',
      statuses_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/statuses/{sha}',
      languages_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/languages',
      stargazers_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/stargazers',
      contributors_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/contributors',
      subscribers_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/subscribers',
      subscription_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/subscription',
      commits_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/commits{/sha}',
      git_commits_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/git/commits{/sha}',
      comments_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/comments{/number}',
      issue_comment_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/issues/comments{/number}',
      contents_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/contents/{+path}',
      compare_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/compare/{base}...{head}',
      merges_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/merges',
      archive_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/{archive_format}{/ref}',
      downloads_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/downloads',
      issues_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/issues{/number}',
      pulls_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/pulls{/number}',
      milestones_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/milestones{/number}',
      notifications_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/notifications{?since,all,participating}',
      labels_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/labels{/name}',
      releases_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/releases{/id}',
      deployments_url: 'https://api.github.com/repos/el-xxxxx/xxxxx-admin/deployments',
      created_at: 1750736699,
      updated_at: '2025-06-24T06:35:57Z',
      pushed_at: 1750920872,
      git_url: 'git://github.com/el-xxxxx/xxxxx-admin.git',
      ssh_url: 'git@github.com:el-xxxxx/xxxxx-admin.git',
      clone_url: 'https://github.com/el-xxxxx/xxxxx-admin.git',
      svn_url: 'https://github.com/el-xxxxx/xxxxx-admin',
      homepage: null,
      size: 286,
      stargazers_count: 0,
      watchers_count: 0,
      language: 'TypeScript',
      has_issues: true,
      has_projects: true,
      has_downloads: true,
      has_wiki: false,
      has_pages: false,
      has_discussions: false,
      forks_count: 0,
      mirror_url: null,
      archived: false,
      disabled: false,
      open_issues_count: 0,
      license: [Object],
      allow_forking: false,
      is_template: false,
      web_commit_signoff_required: false,
      topics: [],
      visibility: 'private',
      forks: 0,
      open_issues: 0,
      watchers: 0,
      default_branch: 'main',
      stargazers: 0,
      master_branch: 'main',
      organization: 'el-xxxxx',
      custom_properties: {}
    },
    pusher: { name: 'PmcFizz', email: '13631686641@sina.cn' },
    organization: {
      login: 'el-xxxxx',
      id: 199537495,
      node_id: 'O_kgDOC-SzVw',
      url: 'https://api.github.com/orgs/el-xxxxx',
      repos_url: 'https://api.github.com/orgs/el-xxxxx/repos',
      events_url: 'https://api.github.com/orgs/el-xxxxx/events',
      hooks_url: 'https://api.github.com/orgs/el-xxxxx/hooks',
      issues_url: 'https://api.github.com/orgs/el-xxxxx/issues',
      members_url: 'https://api.github.com/orgs/el-xxxxx/members{/member}',
      public_members_url: 'https://api.github.com/orgs/el-xxxxx
      /public_members{/member}',
      avatar_url: 'https://avatars.githubusercontent.com/u/199537495?v=4',
      description: ''
    },
    sender: {
      login: 'PmcFizz',
      id: 13403284,
      node_id: 'MDQ6VXNlcjEzNDAzMjg0',
      avatar_url: 'https://avatars.githubusercontent.com/u/13403284?v=4',
      gravatar_id: '',
      url: 'xxxxx',
      html_url: 'https://github.com/PmcFizz',
      followers_url: 'xxxxx/followers',
      following_url: 'xxxxx/following{/other_user}',
      gists_url: 'xxxxx/gists{/gist_id}',
      starred_url: 'xxxxx/starred{/owner}{/repo}',
      subscriptions_url: 'xxxxx/subscriptions',
      organizations_url: 'xxxxx/orgs',
      repos_url: 'xxxxx/repos',
      events_url: 'xxxxx/events{/privacy}',
      received_events_url: 'xxxxx/received_events',
      type: 'User',
      user_view_type: 'public',
      site_admin: false
    },
    ...

最后打印出
在这里插入图片描述

如果shell脚本运行不了,记得加一下权限。
chmod +x ./deploy.sh

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拿我格子衫来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值