在软件开发中,CI/CD(持续集成 / 持续部署)是一种自动化流程:每当代码更新,系统会自动构建、测试并部署应用,避免手动操作的繁琐与错误。作为 DevOps 的核心实践,CI/CD 有力支撑了敏捷开发“快速交付、持续反馈”的理念,让团队既能灵活响应变化,又能保障交付质量。
如果代码托管在 GitHub 上,那么可以通过 GitHub Actions 来实现 CI/CD 部署。其实 GitHub Actions 的实现原理很简单,就是通过 SSH 登录到目标主机,然后执行一键安装部署脚本。
由于 GitHub Actions 的原理是 Github 主机登录到目标主机(Ubuntu)来执行命令,因此最好先生成一对专用于 CI/CD 新的 SSH 密钥。笔者的开发环境是 Windows,因此通过 PowerShell 来生成:
ssh-keygen -t rsa -b 4096 -f ./github_cicd_key然后会提示输入密码:
Enter passphrase (empty for no passphrase):CI/CD 场景下一般用无密码密钥,直接按回车。结束运行后就可以看到两个密钥文件:
将公钥内容添加到 Ubuntu 服务器的 ~/.ssh/authorized_keys:
# 在 Ubuntu 服务器上执行
echo "粘贴 github_cicd_key.pub 的全部内容" >> ~/.ssh/authorized_keys回到 GitHub 仓库页面:
Name | Value(值) |
|---|---|
SERVER_HOST | 目标主机 IP(如 123.123.123.123) |
SERVER_USER | 登录用户名(如 ubuntu、root 等) |
SSH_PRIVATE_KEY | 打开 github_cicd_key 文件,复制全部内容粘贴进来 |
在本地项目根目录(Windows 上)创建文件:
.github/workflows/build-and-deploy.yml内容如下所示:
name: Deploy Blog
# 支持两种触发方式
on:
# 1. 手动触发(GitHub UI 上点击 "Run workflow")
workflow_dispatch:
# 2. 自动触发:仅当推送到 main 分支 且 提交信息含 [deploy]
push:
branches: [main]
jobs:
deploy:
if: >
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'push' && contains(github.event.head_commit.message, '[deploy]'))
runs-on: ubuntu-latest
steps:
- name: Run remote script via SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /home/ubuntu/
bash -l -c './build-and-deploy.sh'这段工作流配置的意思是:
SERVER_HOST、SERVER_USER 和 SSH_PRIVATE_KEY 登录目标主机 。build-and-deploy.sh 。build-and-deploy.yml 需要提交并推送到 GitHub:
git add .
git commit -m "Add simple CI/CD workflow"
git push origin main最后,通过打开 GitHub 仓库 → Actions 标签页,就可以看到是否有 workflow 正在运行(绿色 ✔ 表示成功),还可以查看具体的 CI/CD 日志。
CI/CD 的配置文件 build-and-deploy.yml 中执行任意 shell 命令,不过还是推荐封装好一键构建部署脚本,直接调用这个脚本。很多情况下可以使用这个脚本来进行手动部署。
另外 GitHub Actions 使用的是 非交互式、非登录式 shell,不会加载 .bashrc 或 .profile,环境变量(尤其是 PATH)与手动登录时不同。因此,有两种方案:
# 用于CI/CD环境配置
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
export LD_LIBRARY_PATH=/home/ubuntu/GISBasic/lib/:/home/ubuntu/GISBasic/lib64/:${LD_LIBRARY_PATH:-} #支持变量 LD_LIBRARY_PATH 未定义或为空bash -l -c,表示以登录用户的身份启动一个新 shell,并在这个环境中运行脚本。例如这里的:bash -l -c './build-and-deploy.sh'其实 CI/CD 配置远不是那么简单,随着项目复杂度提升,还可以逐步引入更多工程实践: