如何实现推送到GitHub仓库后自动在树莓派运行Docker实例?
合适的Stack Exchange板块
这个问题最适合发布在Stack Overflow,涉及GitHub Actions、Docker部署、树莓派网络配置这类DevOps与工程实践相关的技术问题,该板块的社区用户在这类场景下的经验更丰富。
解决方案步骤
方案一:用GitHub Actions直接触发树莓派执行命令(无需公网Webhook)
这种方式无需暴露树莓派端口,稳定性更高:
- 在树莓派生成SSH密钥对:
ssh-keygen -t ed25519 -C "github-actions-rpi",全程按回车用默认配置。 - 把树莓派公钥(
~/.ssh/id_ed25519.pub)内容、树莓派公网IP/域名、SSH用户名,分别添加到GitHub仓库的Secrets and variables > Actions中,命名为RPI_SSH_KEY、RPI_HOST、RPI_USER。 - 在仓库根目录创建
.github/workflows/deploy.yml,写入以下配置:
name: Deploy to Raspberry Pi on: push: branches: [ main ] # 可按需修改触发分支 jobs: deploy: runs-on: ubuntu-latest steps: - name: SSH to Raspberry Pi and manage Docker container uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.RPI_HOST }} username: ${{ secrets.RPI_USER }} key: ${{ secrets.RPI_SSH_KEY }} script: | # 停止并清理旧容器(不存在则忽略报错) docker stop my-container || true docker rm my-container || true # 拉取最新镜像(若为自定义镜像,需提前推送到Docker Hub或本地构建) docker pull your-docker-image:latest # 启动新容器 docker run -d --name my-container your-docker-image:latest
- 提交配置文件到仓库,后续每次向指定分支推送代码,GitHub Actions会自动SSH到树莓派执行Docker命令。
方案二:修复Webhook触发方式(适合必须用Webhook的场景)
若坚持使用Webhook,按以下步骤排查修复:
- 先验证端口映射有效性:在树莓派启动简单HTTP服务
python3 -m http.server 8080,用公网IP+端口在外网测试访问,无法访问则检查路由器端口转发规则(需同时转发UDP和TCP,目标IP为树莓派内网IP)。 - 使用NGROK时,确保启动命令正确:
ngrok http 8080(假设Webhook服务跑在8080端口),将NGROK生成的https://xxxx.ngrok.io设为GitHub Webhook的Payload URL,同时设置自定义Secret字符串(后续验证用)。 - 在树莓派部署Webhook服务,用Python写简单处理逻辑:
from flask import Flask, request, abort import subprocess import hmac import hashlib app = Flask(__name__) SECRET = "你设置的GitHub Webhook Secret" def verify_signature(payload, signature): mac = hmac.new(SECRET.encode(), msg=payload, digestmod=hashlib.sha256) return hmac.compare_digest(f"sha256={mac.hexdigest()}", signature) @app.route('/webhook', methods=['POST']) def webhook(): signature = request.headers.get('X-Hub-Signature-256') if not verify_signature(request.data, signature): abort(403) # 执行Docker操作 subprocess.run(["docker", "stop", "my-container"], check=False) subprocess.run(["docker", "rm", "my-container"], check=False) subprocess.run(["docker", "pull", "your-docker-image:latest"]) subprocess.run(["docker", "run", "-d", "--name", "my-container", "your-docker-image:latest"]) return "OK", 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)
- 安装依赖
pip install flask,启动服务后测试GitHub Webhook触发。若用NGINX反向代理,需确保配置不修改请求体(否则签名验证会失败),将请求转发到Flask服务端口。
通用注意事项
- 树莓派需提前安装Docker,且执行命令的用户需加入docker组:
sudo usermod -aG docker $USER,完成后重新登录生效。 - 若使用公网IP,需注意IP可能动态变化,可绑定动态域名解决。
内容的提问来源于stack exchange,提问作者MUSTANGBOSS8055
相关产品推荐
相关产品推荐

