告别异地登录告警!用 GitHub Self-Hosted Runner 打造“零打扰”全栈自动化部署

前言

作为一个全栈开发者,最爽的时刻莫过于 git push 之后,端起咖啡,看着代码自动跑通测试、构建镜像、并在服务器上平滑更新。 但在实现这个目标的过程中,我经历了从"手动搬砖"到"SSH 自动登录",再到最终"Self-Hosted Runner"的三个阶段。特别是解决了云服务器频繁误报"异地登录安全告警"的痛点。

本文将以我的个人全栈项目 Fronty(React + Python FastAPI)为例,分享这套自动化部署体系的搭建过程。

🚧 第一阶段:痛苦的手动挡

最初,我的部署流程是这样的:

  1. 本地代码写完, ·git pull·
  2. 打开终端, SSH连上服务器
  3. cd /opt/fronty->git pull
  4. npm run build->docker build->docker rm->docker run...

后端项目也要重复一遍。这简直是体力和耐心的双重折磨,而且一旦命令输错,服务直接挂掉。

🚧 第二阶段:GitHub Actions + SSH (报警器响不停)

为了偷懒,我配置了 GitHub Actions,使用 appleboy/ssh-action 插件。原理是把服务器的 SSH 私钥交给 GitHub,每次 Push 代码,GitHub 的服务器(位于美国 Azure 机房)就会远程 SSH 连入我的云服务器执行脚本。

部署是自动化了,但烦恼来了: 每次部署,云服务器的安全系统都会疯狂报警:

[云服务器] 异地登录告警:检测到您的服务器在 美国 有 root 用户登录...

虽然我知道这是 GitHub 干的,但看着红色的告警心里总是不踏实。而且为了让 GitHub 能连进来,我不得不开放 SSH 端口,这始终是个安全隐患。

🚀 第三阶段:终极方案:GitHub Self-Hosted Runner

为了彻底解决安全告警和网络连接问题,我决定采用 Self-Hosted Runner 方案。

原理区别:
  • SSH模式: GitHub 主动推(Push)指令给服务器。需要开门(SSH端口),会有外部 IP 连入。
  • Runner模式: 在服务器装一个小助手(Runner),它主动去 GitHub 拉(Pull)任务。不需要开门,没有外部 IP 连入,完全走内部通道。
🛠️ 实施步骤

我的项目结构是前后端分离,两个独立的 GitHub 仓库:frontendProjectbackendProject

1. 服务器环境准备

由于我习惯使用 root 账户管理服务器(个人项目的特权),而 GitHub Runner 默认不建议 root 运行,这里有个关键坑需要避开。

2. 安装 Runner (遇到的网络坑)

在 GitHub 仓库 -> Settings -> Actions -> Runners -> New self-hosted runner 页面,官方提供了下载命令。

坑点 :服务器在国内,直接 curl 下载 GitHub 的 release 包经常超时或连接重置。

解决:采用"物理搬运法"。

  1. 在本地电脑(网络环境好)下载好 .tar.gz 包。
  2. 通过云服务器的文件上传功能,直接拖拽到服务器 /opt/runner-projectName 目录。
  3. 解压:tar xzf ./actions-runner-linux-x64-xxxx.tar.gz
3. 配置与注册 (遇到的权限坑)

在配置时,如果直接运行 ./config.sh,会报错不让用 root。必须加上环境变量:

bash 复制代码
# 允许 Root 用户运行 Runner
export RUNNER_ALLOW_RUNASROOT=1

# 执行配置 (URL 和 Token 从 GitHub 页面获取)
./config.sh --url https://github.com/yourname/projectName --token XXXXXX

配置过程中,我给后端的 Runner 起名为 runner-backendProjectName,前端的起名为 runner-frontendProjectName,分目录部署,互不干扰。

最后安装为系统服务,确保开机自启:

bash 复制代码
./svc.sh install
./svc.sh start

看到 Active: active (running) 的那一刻,感觉稳了。

4. 编写 Workflow 脚本

既然 Runner 已经在本地了,脚本里就不需要 SSH 连接了,直接写 Shell 命令即可。

后端部署脚本 .github/workflows/deploy.yml:

yaml 复制代码
name: Deploy Backend

on:
  push:
    # branch name
    branches: [ "master" ]

jobs:
  deploy:
    # [关键] 指定使用自己的服务器
    runs-on: self-hosted

    steps:
      - name: Deploy on Local Server
        run: |
          echo "🚀 Runner 接单,开始部署后端..."
          
          # 直接进入服务器目录操作
          cd /opt/projectName || exit
          
          # 拉取最新代码
          git fetch --all
          git reset --hard origin/master
          
          # 构建 Docker 镜像
          DOCKER_BUILDKIT=1 docker build -t projectName-app:latest .
          
          # 重启容器
          docker rm -f projectName-app || true
          docker run -d \
            --name projectName-app \
            -p 127.0.0.1:projectPort:projectPort \
            --restart unless-stopped \
            -e PYTHONPATH=/app \
            book-app:latest
          
          # 清理垃圾
          docker image prune -f
          echo "✅ 后端部署完成!"

前端的脚本逻辑类似,只是加上了 npm run build 和 Nginx 容器的启动(使用 --network host 模式配合宿主机 Nginx 反代)。

🎉 最终效果

现在,我在本地 VSCode 改完代码:

  1. git push
  2. GitHub Actions 页面立即显示任务被 runner-projectName 认领。
  3. 服务器悄悄地在后台完成了构建和重启。
  4. 云服务器没有任何告警! 因为全程没有外部 SSH 连接。

💡 总结与收获

  1. 安全感: 关闭了 SSH 密码登录,甚至可以限制 SSH 仅限内网访问,服务器固若金汤。
  2. 速度快: 因为 Runner 就在服务器本机,git pulldocker build 都是利用服务器带宽和 CPU,省去了 SSH 远程传输的开销。
  3. 灵活性: 想怎么改脚本就怎么改,拥有完全的 Root 权限控制。

如果你也是个人开发者,正在忍受云服务商的异地登录告警,强烈建议尝试 Self-Hosted Runner,这绝对是提升幸福感的最佳实践。

相关推荐
未知原色2 小时前
web worker使用总结(包含多个worker)
前端·javascript·react.js·架构·node.js
ttod_qzstudio2 小时前
CSS改变图片颜色方法介绍
前端·css
curdcv_po2 小时前
我接入了微信小说小程序官方阅读器
前端·微信小程序
无限大62 小时前
为什么"数据压缩"能减小文件大小?——从冗余数据到高效编码
后端
用户729429432232 小时前
kubernetes/k8s全栈技术讲解+企业级实战项目课程
后端
用户729429432232 小时前
基于Dubbo的分布式系统架构+事务解决方案
后端
程序员鱼皮3 小时前
什么是 RESTful API?凭什么能流行 20 多年?
前端·后端·程序员
+VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue健身房管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
用户729429432233 小时前
Shiro框架工作原理与实践精讲
后端
用户729429432233 小时前
uni-app实战在线教育类app开发
后端