前言
假如你经常更新博客内容,每次写完文章后还要手动登录服务器执行 rsync 命令来部署,就显得非常麻烦了。更理想的情况是:每次 push 代码到 GitHub 后,GitHub Actions 自动帮我们构建 Hugo 站点并同步到服务器上,这样我们就可以专注于写作,而不必担心部署细节。
什么是 GitHub Actions
GitHub Actions 是 GitHub 提供的一套 CI/CD(持续集成/持续部署)工具,允许我们在代码仓库中定义自动化工作流程。当特定事件发生时(例如 push、pull request、release 等),GitHub Actions 就会触发相应的工作流程,执行预定义的任务。我们可以使用 GitHub Actions 来自动化构建 Hugo 站点,并将生成的静态文件部署到远程服务器上。
准备工作
要使用 GitHub Actions 自动部署 Hugo 博客,我们需要准备以下几个方面:
- 远程服务器:你需要有一台远程服务器,已经安装了 Nginx 或 Apache,并且配置好了网站根目录(例如
/var/www/html/)。 - GitHub 仓库:你需要在 GitHub 上创建一个仓库,用来存放你的博客源码。这个仓库将作为 GitHub Actions 的触发源,当你 push 代码到这个仓库时,GitHub Actions 就会自动执行部署流程。
- SSH 密钥:为了让 GitHub Actions 能够安全地连接到你的远程服务器并执行部署操作,你需要生成一对 SSH 密钥,并将公钥添加到服务器的
~/.ssh/authorized_keys文件中,同时将私钥存储在 GitHub 仓库的 Secrets 中。
什么是 SSH 密钥
首先,我们需要知道什么是 SSH 协议。SSH(Secure Shell)是一种网络协议,用于在不安全的网络上安全地访问远程计算机。SSH 使用公钥加密技术来验证用户身份和保护数据传输的安全性。 SSH 密钥对由两部分组成:公钥和私钥。公钥可以公开分享,而私钥必须保密。使用 SSH 密钥对进行身份验证时,用户将私钥保存在本地计算机上,并将公钥上传到远程服务器。当用户尝试连接到服务器时,服务器会使用公钥来验证用户的身份,如果验证成功,用户就可以访问服务器。
在我们的部署流程中,GitHub Actions 需要使用 SSH 密钥来连接到远程服务器并执行部署命令。因此,我们需要生成一对 SSH 密钥,并将公钥添加到服务器的 ~/.ssh/authorized_keys 文件中,同时将私钥存储在 GitHub 仓库的 Secrets 中,以便 GitHub Actions 可以安全地访问服务器。生成 SSH 密钥的方法将在下面介绍。
配置 SSH 密钥
接下来,我们在远程服务器上生成 SSH 密钥对,并将公钥添加到 ~/.ssh/authorized_keys 文件中。同时,我们将私钥存储在 GitHub 仓库的 Secrets 中,以便 GitHub Actions 可以使用它来连接服务器。
生成密钥对
- 在服务器上执行以下命令生成 SSH 密钥对:
ssh-keygen -t rsa -b 4096 -C "github-actions"- 给公钥授权
生成完成后,公钥会保存在
~/.ssh/id_rsa.pub文件中。你需要将这个公钥的内容添加到服务器的~/.ssh/authorized_keys文件中,以授权 GitHub Actions 访问服务器。
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys- 获取私钥内容
私钥会保存在
~/.ssh/id_rsa文件中。你需要将这个文件的内容复制到 GitHub 仓库的 Secrets 中,命名为DEPLOY_KEY。 首先,使用以下命令查看私钥内容:
cat ~/.ssh/id_rsa(请妥善保管并记录私钥内容,不要泄露。)
配置 GitHub Secrets
为了让 GitHub Actions 能够安全地访问你的服务器,你需要将私钥存储在 GitHub 仓库的 Secrets 中。按照以下步骤操作:
进入 Secrets 设置 在浏览器中打开你的代码仓库(例如
你的用户名/你的仓库名),点击顶部的 Settings 选项卡。 在左侧菜单栏向下滑动,找到 Secrets and variables,点击展开后选择 Actions。添加三个机密变量 点击页面上绿色的 New repository secret 按钮,我们需要依次添加以下三个变量(注意 Name 必须全部大写,不能有拼写错误):
第一个变量(服务器 IP):
Name: SERVER_IP
Secret: (你的服务器 IP 地址)
点击 Add secret 保存。
第二个变量(登录用户名):
Name: SERVER_USER
Secret: root(如果你使用非 root 用户登录,请填写对应的用户名)
点击 Add secret 保存。
第三个变量(私钥):
Name: DEPLOY_KEY
Secret: (将刚才保存的那一整段私钥原封不动地粘贴进来)
点击 Add secret 保存。
编写 GitHub Actions Workflow
接下来,我们需要定义 GitHub Actions 的工作流程,告诉它在每次 push 代码到 main 分支时,如何构建 Hugo 站点并将生成的静态文件部署到服务器上。在项目根目录创建 .github/workflows/deploy.yml,并添加以下内容:
name: Deploy Hugo Site to Aliyun
# 触发条件:当你将代码推送到 main 分支时,自动触发此工作流
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 1. Checkout Code
uses: actions/checkout@v4
with:
submodules: true # 必须为 true,否则无法拉取到你配置的主题文件
fetch-depth: 0 # 拉取所有历史记录,保证文章的修改日期等功能正常读取
- name: 2. Setup Hugo Environment
uses: peaceiris/actions-hugo@v3
with:
hugo-version: 'latest'
extended: true # 必须为 true,你的主题需要 Hugo 扩展版来编译样式
- name: 3. Build Web Static Files
run: hugo --minify
- name: 4. Deploy to Aliyun Server
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_KEY }}
ARGS: "-avz --delete" # --delete 参数确保本地删除的文章,服务器端也会同步删除
SOURCE: "public/" # 本地需要上传的成品文件夹
REMOTE_HOST: ${{ secrets.SERVER_IP }}
REMOTE_USER: ${{ secrets.SERVER_USER }}
TARGET: "/var/www/html/" # 你的 Nginx 网站根目录推送测试
提交代码后,去 GitHub 仓库的 Actions 标签页查看运行状态。每次 push 到 main 分支都会自动触发构建和部署。如果部署成功,你的博客就会自动更新了!
如果遇到 Permission denied (publickey) 错误,检查公钥是否正确追加到服务器的 authorized_keys、私钥是否完整存入 GitHub Secrets(注意不要遗漏开头和结尾的 ----- 行)。
结语
通过以上步骤,我们成功地使用 GitHub Actions 实现了 Hugo 博客的自动部署。每次更新内容后,只需 push 代码,GitHub Actions 就会自动构建并同步到服务器上,让我们专注于写作,而不必担心部署细节了。希望这篇教程能帮助你搭建自己的 CI/CD 流水线,提升博客的维护效率!