news 2026/10/8 13:13:41

宝塔 Docker Compose + GitHub Actions CI/CD 完整教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
宝塔 Docker Compose + GitHub Actions CI/CD 完整教程

宝塔 Docker Compose + GitHub Actions CI/CD 完整教程

  • 宝塔面板官网
  • 写字台开源项目地址
  • 甲骨文部署结果
  • 腾讯云部署结果

适用场景:宝塔面板 + Docker Compose 编排部署 + Docker Hub 镜像仓库 + GitHub Actions 自动部署
本文以实际项目为例:镜像zhongdaiqi/xiezitai,服务器 Oracle Cloud,编排文件由宝塔管理。


一、整体架构

开发者 push 代码到 GitHub │ ▼ GitHub Actions ├─ 构建 Docker 镜像 ├─ 推送到 Docker Hub └─ SSH 登录服务器 │ ▼ 服务器 authorized_keys 限制 command="/data/xiezitai_deploy/deploy.sh" │ ▼ deploy.sh 执行 docker compose pull && up -d │ ▼ 容器更新完成

二、前置条件

项要求
服务器已装 Docker + Docker Compose(插件版docker compose)
宝塔面板已用「Docker 编排」跑起项目
镜像仓库Docker Hub 账号,镜像已能 push
GitHub仓库已关联代码,Actions 可用
本地有 SSH 客户端(Windows PowerShell / macOS / Linux 均可)

三、服务器端配置

3.1 确认 Docker 环境

docker-vdockercompose version

应输出类似:

Docker version 29.8.2 Docker Compose version v5.6.0

3.2 确认宝塔编排文件位置

宝塔编排文件通常在:

/www/server/panel/data/compose/<项目名>/docker-compose.yaml

本例中项目名为xiezitai,所以:

/www/server/panel/data/compose/xiezitai/docker-compose.yaml

确认内容里image:是你的 Docker Hub 镜像:

cat/www/server/panel/data/compose/xiezitai/docker-compose.yaml

3.3 创建部署脚本

本例脚本路径为/data/xiezitai_deploy/deploy.sh。

mkdir-p/data/xiezitai_deploycat>/data/xiezitai_deploy/deploy.sh<<'EOF' #!/bin/bash set -e COMPOSE_DIR="/www/server/panel/data/compose/xiezitai" cd "$COMPOSE_DIR" echo "===== $(date) 开始部署 =====" docker compose pull docker compose up -d --remove-orphans docker image prune -f echo "===== 部署完成 =====" EOFchmod+x /data/xiezitai_deploy/deploy.sh

说明:

  • set -e:任何一步失败立即退出,CI 能感知。
  • docker compose pull:拉取最新镜像。
  • up -d --remove-orphans:重建容器并清理孤立容器。
  • image prune -f:清理悬空镜像。

3.4 手动验证脚本

bash/data/xiezitai_deploy/deploy.sh

预期输出:

===== ... 开始部署 ===== [+] pull 2/2 ✔ Image zhongdaiqi/xiezitai:latest Pulled ✔ Image mariadb:11.4 Pulled [+] up 2/2 ✔ Container xiezitai Running ✔ Container xiezitai-db Healthy ===== 部署完成 =====

确认容器状态:

dockerps--format"table {{.Names}}\t{{.Status}}\t{{.Image}}"

这一步必须手动跑通,再继续。


四、SSH 密钥配置

4.1 生成专用密钥(服务器上执行)

ssh-keygen-ted25519-f~/.ssh/github_deploy-N""

生成:

  • ~/.ssh/github_deploy(私钥,给 GitHub)
  • ~/.ssh/github_deploy.pub(公钥,留服务器)

4.2 把公钥加入授权列表并加限制

cat~/.ssh/github_deploy.pub>>~/.ssh/authorized_keyschmod700~/.sshchmod600~/.ssh/authorized_keys

编辑~/.ssh/authorized_keys:

vi~/.ssh/authorized_keys

找到刚加的那行(ssh-ed25519 AAAA...),在行首加上限制:

restrict,command="/data/xiezitai_deploy/deploy.sh" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... root@instance-xxx

说明:

  • restrict:禁用端口转发、X11、PTY 等所有危险功能。
  • command=...:无论客户端发什么命令,只执行指定脚本。
  • 这样即使私钥泄露,攻击者也只能触发部署,无法执行任意命令。

4.3 查看私钥内容(复制到 GitHub)

cat~/.ssh/github_deploy

完整复制-----BEGIN OPENSSH PRIVATE KEY-----到-----END OPENSSH PRIVATE KEY-----的全部内容。

⚠️ 私钥只能填到 GitHub Secrets,绝不要提交到仓库或贴到聊天里。

4.4 本地验证登录

在你本机(把私钥下载到本机后):

chmod600~/.ssh/github_deployssh-i~/.ssh/github_deploy-p22root@ip地址

预期:直接执行 deploy.sh,打印部署日志,然后自动断开,不给你 shell。

看到PTY allocation request failed是正常的(因为加了no-pty)。

如果看到Please login as the user "opc",说明 root 被 Oracle 禁了,需要改用opc用户(见附录)。


五、GitHub 配置

5.1 添加 Secrets

仓库 →Settings → Secrets and variables → Actions → New repository secret:

Secret 名称值
SSH_HOSTip地址
SSH_USERroot
SSH_PORT22
SSH_KEYgithub_deploy私钥全文

如果镜像构建也在 GitHub Actions 里做,再加:

  • DOCKERHUB_USERNAME
  • DOCKERHUB_TOKEN(Docker Hub → Account Settings → Security → New Access Token)

5.2 创建 workflow

在项目仓库创建.github/workflows/deploy.yml。

情况 A:镜像已由其他 workflow 构建推送,只需要部署
name:Deployon:push:branches:[main]workflow_dispatch:jobs:deploy:runs-on:ubuntu-lateststeps:-name:Deploy via SSHuses:appleboy/ssh-action@v1with:host:${{secrets.SSH_HOST}}username:${{secrets.SSH_USER}}port:${{secrets.SSH_PORT}}key:${{secrets.SSH_KEY}}script_stop:truescript:|echo "trigger deploy"

因为服务器authorized_keys里加了command=,这里的script内容会被服务器忽略,真正执行的是deploy.sh。

情况 B:构建推送 + 部署 一条龙
name:Build and Deployon:push:branches:[main]workflow_dispatch:jobs:build-and-push:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-uses:docker/setup-buildx-action@v3-uses:docker/login-action@v3with:username:${{secrets.DOCKERHUB_USERNAME}}password:${{secrets.DOCKERHUB_TOKEN}}-uses:docker/build-push-action@v6with:context:.push:truetags:|zhongdaiqi/xiezitai:latest zhongdaiqi/xiezitai:${{ github.sha }}deploy:needs:build-and-pushruns-on:ubuntu-lateststeps:-name:Deploy via SSHuses:appleboy/ssh-action@v1with:host:${{secrets.SSH_HOST}}username:${{secrets.SSH_USER}}port:${{secrets.SSH_PORT}}key:${{secrets.SSH_KEY}}script_stop:truescript:|echo "trigger deploy"

六、触发验证

  1. 提交并 push 到main。
  2. 打开 GitHub 仓库 →Actions标签页。
  3. 点进 workflow,能看到部署日志,与手动 SSH 时一致:
===== ... 开始部署 ===== ... ===== 部署完成 =====
  1. 服务器确认:
dockerps--format"table {{.Names}}\t{{.Status}}\t{{.Image}}"

七、安全加固(强烈建议)

7.1 锁 appleboy 版本到 commit SHA

@v1是浮动 tag,作者发新版会自动用上。想更稳,锁到具体 SHA:

uses:appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2# v1.2.0

到 https://github.com/appleboy/ssh-action/releases 查最新版本对应 SHA。

7.2 用专用用户替代 root(可选,更安全)

useradd-m-s/bin/bash deployusermod-aGdockerdeploymkdir-p/home/deploy/.sshcat~/.ssh/github_deploy.pub>/home/deploy/.ssh/authorized_keyschown-Rdeploy:deploy /home/deploy/.sshchmod700/home/deploy/.sshchmod600/home/deploy/.ssh/authorized_keys

GitHub Secrets 里SSH_USER改成deploy。

7.3 禁用 root 密码登录

/etc/ssh/sshd_config:

PasswordAuthentication no PermitRootLogin prohibit-password

重启 SSH:

systemctl restart sshd

7.4 修改默认 SSH 端口

/etc/ssh/sshd_config改Port 2222,云安全组和宝塔防火墙同步放行,GitHub Secrets 里SSH_PORT改成2222。


八、回滚机制

构建时同时打latest和 commit sha 两个 tag(见情况 B)。回滚时:

cd/www/server/panel/data/compose/xiezitai# 临时把 image 改成某个 shased-i's|zhongdaiqi/xiezitai:latest|zhongdaiqi/xiezitai:<sha>|'docker-compose.yamldockercompose up-d

或更规范的方式,用.env控制版本:

# docker-compose.yamlimage:zhongdaiqi/xiezitai:${IMAGE_TAG:-latest}

部署时:

IMAGE_TAG=<sha>dockercompose up-d

九、常见问题排查

现象原因解决
Permission denied (publickey)私钥不对/不全重新cat ~/.ssh/github_deploy,完整粘贴到SSH_KEY
Load key ... error in libcrypto用了.pub公钥登录改用私钥(无.pub后缀)
PTY allocation request failed正常(no-pty)忽略
Please login as the user "opc"Oracle 禁用 root改用opc用户,见附录
dial tcp ... i/o timeout网络/防火墙检查 Oracle 安全组、宝塔防火墙放行 SSH 端口
Host key verification failedknown_hostsappleboy默认跳过,一般不会遇到
Action 成功但容器没更新脚本未执行检查authorized_keys的command=路径
Conflict. container name already in use同名容器残留docker rm -f 容器名后重试

十、附录:Oracle Cloud 用 opc 用户

如果 root 被禁,改用opc:

# 1. 公钥放到 opcsudomkdir-p/home/opc/.sshsudochmod700/home/opc/.sshsudovi/home/opc/.ssh/authorized_keys# 加入:# restrict,command="/data/xiezitai_deploy/deploy.sh" ssh-ed25519 AAAA...sudochown-Ropc:opc /home/opc/.sshsudochmod600/home/opc/.ssh/authorized_keys# 2. opc 加入 docker 组sudousermod-aGdockeropc# 3. deploy.sh 里 docker 命令加 sudo,并配置免密echo"opc ALL=(ALL) NOPASSWD: /usr/bin/docker"|sudotee/etc/sudoers.d/opc-docker

GitHub Secrets 里SSH_USER改成opc。


十一、完整检查清单

服务器端

  • Docker / Docker Compose 已装
  • 宝塔编排文件就位,服务正常运行
  • deploy.sh已创建并chmod +x
  • 手动bash deploy.sh成功

SSH

  • github_deploy密钥已生成
  • 公钥加入authorized_keys并加restrict,command=...
  • 权限 700 / 600 正确
  • 本地用私钥 SSH 登录成功(自动触发部署)

GitHub

  • SSH_HOST/SSH_USER/SSH_PORT/SSH_KEY已加 Secrets
  • .github/workflows/deploy.yml已创建
  • push 后 Actions 运行成功
  • 服务器容器确认已更新

安全

  • 私钥只存 GitHub Secrets
  • authorized_keys已加restrict,command=
  • (可选)锁 appleboy commit SHA
  • (可选)专用用户替代 root
  • (可选)禁用密码登录

十二、流程总结

① 服务器:deploy.sh 手动跑通 ② 服务器:生成 SSH 密钥,公钥加 restrict,command= 限制 ③ 本地:用私钥 SSH 验证能自动触发部署 ④ GitHub:配置 4 个 Secrets ⑤ GitHub:创建 deploy.yml ⑥ push 触发,Actions 自动 SSH 执行 deploy.sh ⑦ 服务器:容器自动更新,数据卷复用,不丢数据

至此,代码 push → 镜像构建推送 → 服务器自动更新的完整 CI/CD 链路就跑通了。


有任何一步卡住,把报错原文和当前执行的命令贴出来,我帮你定位。记住:私钥永远不要贴出来。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 13:13:32

AI反电诈怎么做?腾讯云天御风控Agent方案与落地解析

AI反电诈怎么做&#xff1f;腾讯云天御风控Agent方案与落地解析 金融反电诈正在从"事后堵漏"转向AI智能体驱动的主动治理。据公安部2026年1月发布的数据&#xff0c;2025年全国公安机关共侦破电信网络诈骗案件25.8万起&#xff0c;拦截诈骗电话36亿次、短信33亿条&am…

作者头像 李华
网站建设 2026/10/8 13:13:26

AI Agent 框架怎么选:从一次制度查询拆出技术边界

AI Agent 框架怎么选&#xff1a;从一次制度查询拆出技术边界 适用范围&#xff1a;应用侧模型调用、工具执行、状态编排与检索组件的选型方法。框架关系按当前 Python LangChain Agent、LangGraph、LlamaIndex 及 Spring AI 的能力边界解释&#xff0c;不表示所有历史版本均相…

作者头像 李华
网站建设 2026/10/8 13:13:25

B11_ContentProvider与内容访问

Android 基础补强 B11&#xff5c;ContentProvider&#xff1a;从一个 URI 读懂跨应用内容访问 发布摘要&#xff1a;读取用户选中文档的名称和大小&#xff0c;区分 ContentResolver、Cursor、内容 URI、临时访问与持久授权。标签&#xff1a;ContentProvider、ContentResolve…

作者头像 李华
网站建设 2026/10/8 13:11:36

高密最新招聘信息正规机构

在高密找工作&#xff0c;很多人会先搜“高密最新招聘信息”“正规机构”。 但招聘信息渠道多&#xff0c;真假混杂&#xff0c;求职者和招工企业都需要多留个心眼。想及时看本地岗位&#xff0c;可以关注高密招聘网。 它主要面向高密本地求职者和招工企业&#xff0c;提供岗位…

作者头像 李华