使用GitHub Actions自动部署AI助手:无需人工干预的持续部署方案

在运维AI应用时,我们经常需要不断更新代码并重新部署。每次手动SSH登录服务器、拉取代码、编译并重启服务不仅繁琐,还容易出错。本文将分享如何利用GitHub Actions实现OpenHands(一个私有的AI编程助手)的全自动部署流程,让代码一旦推送到GitHub仓库就能自动部署到生产服务器,无需任何人工干预。

现状问题

目前,我们的部署流程相当繁琐:

1. ssh登录服务器
2. tmux a -t DaTou进入会话
3. Ctrl+C终止当前运行的程序
4. git pull拉取最新代码
5. make build编译代码
6. authbind --deep make run启动服务

这个过程完全是手动的,既浪费时间又容易因操作失误导致服务异常。如何实现全自动化呢?

解决方案对比

方案复杂度实时性可观测性适用场景
Cron定时检查★★☆☆☆★★☆☆☆★☆☆☆☆简单项目、低频更新
Webhook触发部署★★★☆☆★★★★★★★☆☆☆中型项目、需要即时部署
GitHub Actions★★★☆☆★★★★★★★★★★各种规模项目、需要完整部署流程
专业CI/CD平台★★★★★★★★★★★★★★★企业级应用、复杂部署需求

经过对比,GitHub Actions显然是最适合我们需求的解决方案:它能提供即时部署、完整记录,且与GitHub仓库无缝集成。

实施方案:使用GitHub Actions自动部署

第一步:准备服务器环境

首先,需要在服务器上设置SSH密钥,使GitHub Actions能够安全地连接:

# 在服务器上生成SSH密钥对
ssh-keygen -t ed25519 -C "github-actions-deploy"
# 一路回车即可,不要设置密码

# 将公钥添加到authorized_keys
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys

第二步:创建部署脚本

在服务器上创建一个脚本来处理代码拉取、编译和重启服务的过程:

# 创建部署脚本
nano ~/deploy_openhands.sh

填入以下内容:

#!/bin/bash

# 设置工作目录和日志文件
REPO_DIR="/path/to/your/openhands/repo"
LOG_FILE="/path/to/deploy_logs.log"
CONDA_ENV="DaTou"

# 记录日志函数
log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 切换到仓库目录
cd "$REPO_DIR" || { log "Failed to cd to $REPO_DIR"; exit 1; }

log "Starting deployment process"

# 拉取最新代码
log "Pulling latest code from repository"
git pull

# 初始化conda
log "Initializing conda environment"
# 以下行确保conda命令在bash中可用
source $(conda info --base)/etc/profile.d/conda.sh


# 激活conda环境
log "Activating conda environment: $CONDA_ENV"
conda activate $CONDA_ENV

# 编译代码
log "Building application"
make build
if [ $? -ne 0 ]; then
  log "Build failed"
  exit 1
fi

# 确保tmux会话存在
if ! tmux has-session -t DaTou 2>/dev/null; then
  log "Creating new tmux session: DaTou"
  tmux new-session -d -s DaTou
else
  # 停止当前运行的程序
  log "Stopping current application in tmux session"
  tmux send-keys -t DaTou C-c
  
  # 等待程序优雅退出
  sleep 5
fi

# 启动应用程序
log "Starting application"
tmux send-keys -t DaTou "cd $REPO_DIR && authbind --deep make run" C-m

log "Deployment completed successfully"

别忘了使脚本可执行:

chmod +x ~/deploy_openhands.sh

第三步:设置GitHub仓库密钥

在GitHub仓库中添加必要的密钥:

  1. 进入GitHub仓库页面
  2. 点击"Settings" > "Secrets and variables" > "Actions"
  3. 点击"New repository secret"
  4. 添加以下密钥:
    • SSH_PRIVATE_KEY: 服务器上生成的SSH私钥(cat ~/.ssh/id_ed25519的内容)
    • SSH_HOST: 服务器IP或域名
    • SSH_USER: 服务器用户名(例如ubuntu
    • SSH_PORT: SSH端口(通常为22)

第四步:创建GitHub Actions工作流

在你的仓库中创建一个工作流文件:

mkdir -p .github/workflows
nano .github/workflows/deploy.yml

填入以下内容:

name: Deploy OpenHands

on:
  push:
    branches: [ main ] # 替换为你的主分支名称
  # 手动触发选项
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SSH_PORT }}
          script: |
            ~/deploy_openhands.sh

第五步:确保系统重启后服务自动启动

创建一个systemd服务,确保服务器重启后应用自动启动:

sudo nano /etc/systemd/system/openhands.service

添加以下内容:

[Unit]
Description=OpenHands AI Assistant Service
After=network.target

[Service]
Type=oneshot
User=ubuntu  # 替换为你的用户名
ExecStart=/bin/bash -c "tmux has-session -t DaTou || tmux new-session -d -s DaTou"
ExecStart=/bin/bash -c "tmux send-keys -t DaTou 'cd /path/to/your/openhands/repo && authbind --deep make run' C-m"
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

启用服务:

sudo systemctl enable openhands.service
sudo systemctl start openhands.service

工作原理

整个自动部署流程工作流程如下:

  1. 代码推送触发:当开发者将代码推送到GitHub仓库的主分支时,GitHub Actions自动触发
  2. 安全连接服务器:Actions使用SSH密钥安全连接到服务器
  3. 执行部署脚本:执行预先定义的部署脚本,完成代码拉取、编译和应用重启
  4. 日志记录:整个过程的日志都被记录,方便问题排查
GitHub Actions自动部署流程图 (点击展开)

GitHub Actions自动部署流程图

高级配置与优化

添加部署通知

在工作流文件中添加部署通知:

steps:
  # ... 其他步骤
  - name: Send deployment notification
    if: always()
    uses: rtCamp/action-slack-notify@v2
    env:
      SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
      SLACK_COLOR: ${{ job.status }}
      SLACK_TITLE: OpenHands Deployment
      SLACK_MESSAGE: 'Deployment ${{ job.status }}'

添加部署前测试

确保代码质量后再部署:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run tests
        run: make test
        
  deploy:
    needs: test
    runs-on: ubuntu-latest
    # ... 部署步骤

区分环境配置

使用不同分支部署到不同环境:

on:
  push:
    branches:
      - main    # 生产环境
      - staging # 测试环境

常见问题与解决方案

1. SSH连接失败

检查以下几点:

  • 确保服务器防火墙允许SSH连接
  • 验证SSH密钥格式是否正确(复制时可能丢失换行)
  • 检查用户权限是否正确

解决方法:

# 检查SSH配置
sudo cat /etc/ssh/sshd_config | grep PubkeyAuthentication
# 确保值为yes

# 检查authorized_keys权限
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh

2. 部署脚本执行失败

常见原因是路径错误或权限问题:

# 检查脚本可执行权限
chmod +x ~/deploy_openhands.sh

# 手动执行脚本并查看错误
bash -x ~/deploy_openhands.sh

3. 应用启动但无法访问

可能是端口绑定问题或防火墙设置:

# 检查应用是否正在运行
ps aux | grep make

# 检查端口是否被正确监听
sudo netstat -tulpn | grep 80

使用体验与效果

实施GitHub Actions自动部署后,我们的开发流程显著改善:

  1. 节省时间:从手动部署的10分钟减少到完全自动化
  2. 减少错误:消除了人工操作可能导致的失误
  3. 提高可见性:可以在GitHub界面上清晰看到每次部署的状态和日志
  4. 团队协作:团队成员无需了解服务器细节即可完成部署

部署频率从原来的每周2-3次增加到每天多次,大大加快了功能迭代和问题修复的速度。

总结

通过GitHub Actions实现自动部署,我们将繁琐的手动部署过程转变为完全自动化的工作流。这不仅提高了开发效率,还增强了系统稳定性。对于任何需要频繁更新的Web应用或AI服务,这种自动部署方案都是极具价值的。

最重要的是,这套方案易于实施且维护成本低,即使是小型团队也能轻松应用。相比专业CI/CD平台,GitHub Actions为我们提供了一个免费且强大的自动化部署解决方案。

如果你有任何自动部署的经验或其他方案,欢迎在评论区分享!

留言与讨论