发布于 2026-01-06 6 阅读
0

✨ GitHub Actions 实用指南:推送后构建并部署静态 11ty 网站到远程虚拟服务器

✨ GitHub Actions 实用指南:推送后构建并部署静态 11ty 网站到远程虚拟服务器

介绍

嘿,开发者社区🖖好久不见了!

我想和大家分享一个来自 CI/CD 领域的好消息:GitHub 终于面向所有用户发布了自动化工具!让我们来看一个全面而真实的案例,这将帮助你更快地理解并开始使用 GitHub Actions!👍

📝 目录

🤔 什么是 GitHub Actions?

GitHub Actions现在,借助世界一流的 CI/CD,您可以轻松实现所有软件工作流程的自动化。直接在 GitHub 上构建、测试和部署代码,按照您想要的方式进行代码审查、分支管理和问题分类……而且对于开源公共仓库来说完全免费!

GitHub Actions

❤️ 你为什么也会喜欢它呢?

  • 支持 Linux、macOS、Windows、ARM 和容器。适用于所有主流操作系统的托管运行器,让您轻松构建和测试所有项目。您可以直接在虚拟机或容器内运行。使用自托管运行器,您可以将虚拟机部署在云端或本地。
  • 矩阵构建。利用矩阵工作流,可以同时跨多个操作系统和运行时版本进行测试,从而节省时间。
  • 支持任何语言。GitHub Actions 支持多种语言Node.js,包括PythonC#、JavaC# Ruby、 C# PHPGoC#、RustC#.NET等。使用您选择的语言构建、测试和部署应用程序。
  • 实时日志。通过颜色和表情符号实时查看您的工作流运行情况。只需单击一下即可复制突出显示特定行号的链接,以便共享 CI/CD 故障。
  • 内置秘密存储库。通过将工作流文件编码到存储库中,实现软件开发流程自动化,并遵循 Git 工作流。
  • 多容器测试。只需在工作流文件中添加一些 docker-compose 配置,即可在工作流中测试您的 Web 服务及其数据库。

↑ 目录

📚 准备阶段

好了,希望现在大家的问题少了。那么,我们要部署什么,部署在哪里呢?正如你可能已经从文章标题中了解到的,答案是:

  • 11ty(或 Eleventy),作为静态网站生成器
  • DropletDigitalOcean作为远程虚拟服务器
  • Ubuntu 18.04 LTS,作为服务器操作系统

让我们以这样一个项目为例:

.
├── .eleventy.js
├── .gitignore
├── .github
│   └── workflows
│       └── ssh_deploy.yml
├── package.json
└── src
    ├── _includes
    │   ├── css
    │   │   └── style.css
    │   └── layouts
    │       └── base.njk
    ├── images
    │   └── logo.svg
    └── index.njk
Enter fullscreen mode Exit fullscreen mode

☝️提示:和往常一样,您可以从这个GitHub仓库获取可用于生产环境的项目代码→ https://github.com/koddr/example-github-actions

听起来很简单,让我们看看实际情况如何👀

↑ 目录

11ty

✅ 11ty 又名 Eleventy

Eleventy 是一个更简单的静态网站生成器,旨在成为 JavaScript 版的替代方案Jekyll。它默认情况下无需配置,但也提供了灵活的配置选项。Eleventy不是一个 JavaScript 框架,这意味着它不需要任何客户端 JavaScript 样板代码,并且支持多种模板语言:

模板语言

在所有模板引擎中,我比较喜欢使用Nunjucks。它与 非常相似jinja2,但由 Mozilla 提供支持。此外,我希望所有 CSS 样式都能得到优化、最小化并包含在最终的 HTML 文档中。CleanCSS包可以帮助我实现这一点。

我的 Eleventy 配置如下所示:

// .eleventy.js

const CleanCSS = require("clean-css"); // npm i --save-dev clean-css

module.exports = function (eleventyConfig) {
  // Copy all images to output folder
  eleventyConfig.addPassthroughCopy("src/images");

  // Optimized, minimized and included CSS to final HTML
  eleventyConfig.addFilter("cssmin", function (code) {
    return new CleanCSS({}).minify(code).styles;
  });

  return {
    dir: { 
      input: "src",                  // input folder name
      output: "dist",                // output folder name
    },
    passthroughFileCopy: true,       // allows to copy files to output folder
    htmlTemplateEngine: "njk",       // choose Nunjucks template engine
    templateFormats: ["njk", "css"],
  };
};
Enter fullscreen mode Exit fullscreen mode

基本布局模板:

<!-- src/_includes/layouts/base.njk -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{{ title }}</title>
    {% set css %}{% include "css/style.css" %}{% endset %}
    <style>
      {{ css | cssmin | safe }}
    </style>
  </head>
  <body>
    {{ content | safe }}
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

示例首页:

<!-- src/index.njk -->

---
layout: layouts/base.njk
title: "Hello, World!"
---

<main>
  <section>
    <img src="/images/logo.svg" alt="logo" />
    <article>
      <h1>{{ title }}</h1>
      <p>It works via GitHub Actions 👍</p>
    </article>
  </section>
</main>
Enter fullscreen mode Exit fullscreen mode

以及 CSS 样式:

/* src/_includes/css/style.css */

:root {
  --font-face: sans-serif;
  --font-size: 18px;
  --black: #444444;
  --gray: #fafafa;
}

* {
  box-sizing: border-box;
}

body {
  font-family: var(--font-face);
  font-size: var(--font-size);
  color: var(--black);
  background-color: var(--gray);
}

h1 {
  font-size: calc(var(--font-size) * 2.5);
  margin-bottom: var(--font-size);
}

main {
  display: grid;
  grid-template-columns: max-content;
  row-gap: 24px;
  align-items: center;
  justify-content: center;
  text-align: center;
}

main > * > img {
  width: 320px;
}
Enter fullscreen mode Exit fullscreen mode

↑ 目录

✅ DigitalOcean 上的 Droplet

我想应该没人会对另一个无法实际使用的“Hello, World!”示例感兴趣吧?所以,我决定向大家展示如何配置这个远程虚拟服务器:

  1. Nginx带有Brotli模块和最佳实践配置
  2. www从到重定向non-www和从http到重定向https
  3. Certbot为域名自动续订 SSL 证书
  4. UFW带有保护规则的防火墙

没错,到了 2020 年,如果你的 Web 服务器不使用 Brotli(谷歌出品)压缩格式,那简直就是犯罪!😉

创建 Droplet

  • 登录您的DigitalOcean帐户

还没有账号?通过我的推荐链接加入 DigitalOcean 吧(你赚100 美元,我赚 25 美元)。这是我给你的奖励!🎁

  • 点击顶部的绿色按钮“创建” ,然后选择“水滴”。
  • 选择Ubuntu 18.04 LTS、套餐和服务器区域:

执行液滴 1

  • “身份验证”部分,点击“新建 SSH 密钥”按钮:

执行液滴 2

☝️提示:我建议为每个新服务器创建一个新的 SSH 密钥,因为这样比所有服务器使用同一个密钥更安全!

  • 按照说明(在本表单右侧)生成 SSH 密钥
  • 重新检查 Droplet 的选项,然后单击“创建 Droplet”。
  • 转到“网络”部分(左侧菜单),然后添加您的域名:

执行液滴 3

  • 最后,向该域名添加两条A记录(分别对应@www)。

太棒了!👌 您已准备好设置远程虚拟服务器。

设置远程虚拟服务器

我就不赘述那些枯燥的控制台命令了。因为我有一个很棒的 GitHub 代码库,它能让你通过配置 GNU/Linux 服务器(使用Ansibleplaybook)来自动化一些日常任务👇

GitHub 标志 koddr /实用剧本

🚚 实用的 Ansible playbook,助您轻松将网站或 Web 应用部署到全新的远程虚拟服务器,并实现众多流程的自动化。从运行 playbook 到完成服务器设置并启动,仅需 3 分钟。

我只需要将所有需要的剧本下载到本地计算机并运行它(加上一些额外的变量):

# Configure VDS
ansible-playbook \
                  new_server-playbook.yml \
                  --user <USER> \
                  --extra-vars "host=<HOST>"

# Install Brotli module for Nginx
ansible-playbook \
                  install_brotli-playbook.yml \
                  --user <USER> \
                  --extra-vars "host=<HOST>"

# Get SSL for domain
ansible-playbook \
                  create_ssl-playbook.yml \
                  --user <USER> \
                  --extra-vars "host=<HOST> domain=<DOMAIN>"
Enter fullscreen mode Exit fullscreen mode

现在,您只需等待5-10分钟。这样,我上面提到的所有任务都已成功完成。

搞定了!真的管用!

↑ 目录

✅ 私钥

让我们为虚拟服务器创建一个私有 SSH 密钥,这样我们就可以无需输入root密码即可登录。此外,您还需要此密钥来配置 GitHub Actions 以通过 SSH 进行部署(本文稍后将对此进行介绍)。

☝️请注意:密钥必须在您的本地计算机上创建!

  • 打开终端并运行以下命令:
ssh-keygen
Enter fullscreen mode Exit fullscreen mode

☝️提示:Windows用户可以安装并使用PuTTY它。

  • 系统会提示您保存并命名密钥。为了便于理解,我们将其命名为 `<key_name>`gha_rsa并将其放置在~/.ssh您本地计算机的文件夹中(~/.ssh/gha_rsa)。
  • 接下来,您将被要求创建并确认密钥的密码短语。
  • 这将生成两个文件,分别命名为gha_rsagha_rsa.pub

继续在您的虚拟服务器上

  • 复制文件内容gha_rsa.pub(在本地计算机上):
cat ~/.ssh/gha_rsa.pub
Enter fullscreen mode Exit fullscreen mode
  • 登录到远程虚拟服务器,并创建一个文件~/.ssh/authorized_keys,内容如下gha_rsa.pub
sudo nano ~/.ssh/authorized_keys
Enter fullscreen mode Exit fullscreen mode
  • 将 SSH 密钥粘贴到~/.ssh/authorized_keys文件中
  • 点击Ctrl + O保存更改并Ctrl + X退出编辑器

返回本地计算机完成该过程。

好的!👌 让我们立即添加设置,以便使用 SSH 密钥从本地计算机快速登录到远程服务器。

  • 打开本地 SSH 配置文件:
sudo nano ~/.ssh/config
Enter fullscreen mode Exit fullscreen mode
  • 在文件末尾添加以下内容~/.ssh/config(不要忘记将 `<value>` SERVER_SHORTCUTSERVER_IP`<value>` 和`<value>` 替换SERVER_USER为您自己的值):
Host SERVER_SHORTCUT
  HostName SERVER_IP
  Port 22
  User SERVER_USER
  IdentityFile ~/.ssh/gha_rsa
  AddKeysToAgent yes
Enter fullscreen mode Exit fullscreen mode
  • 点击Ctrl + O保存更改并Ctrl + X退出编辑器
  • 现在,您可以像这样轻松登录到远程虚拟服务器:
ssh SERVER_SHORTCUT
Enter fullscreen mode Exit fullscreen mode

🎉 恭喜!您现在可以开始配置 GitHub Actions 了!

↑ 目录

GitHub Actions 插件

🔍 GitHub Actions 的实用插件

愿上帝保佑开源社区!🙏

如今,GitHub Actions市场已经拥有许多action对各种生活场景都非常有用的插件(在这里被称为)。

☝️请注意:部分操作与 GitHub 无关。使用这些操作前,请务必查看其源代码!

但就目前而言,只有两种方法对我们有用:

GitHub 标志 TartanLlama / actions-eleventy

使用 Eleventy 生成静态网站的 GitHub Action

GitHub 标志 appleboy / SCP行动

通过 SSH 复制文件和工件的 GitHub Action。

↑ 目录

⚙️ GitHub Actions 配置

这是我们工作流程的配置文件。您可以自己查看,但我会在下面解释一些不太明显的设置。

# .github/workflows/ssh_deploy.yml

name: Deploy Eleventy via SSH

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, 
      # so your workflow can access it
      - uses: actions/checkout@master

      # Build your static website with Eleventy
      - name: Build Eleventy
        uses: TartanLlama/actions-eleventy@master
        with:
          args: --output html
          install_dependencies: true

      # Copying files and artifacts via SSH
      - name: Copying files to server
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.REMOTE_HOST }}
          username: ${{ secrets.REMOTE_USER }}
          key: ${{ secrets.SSH_KEY }}
          passphrase: ${{ secrets.SSH_KEY_PASSPHRASE }}
          rm: true
          source: "html/"
          target: "${{ secrets.REMOTE_DIR }}"
Enter fullscreen mode Exit fullscreen mode

基本设置

  • on— 此设置告诉您如何运行工作流master(在我们的例子中,当您向存储库的分支发出推送或拉取请求时,它将运行)。
  • runs-on— 允许您定义工作流将在哪个系统上启动(在我们的例子中,是最新的 Ubuntu 系统)。
  • steps— 本节将定义 GitHub Actions 工作流的所有任务(步骤),并按顺序逐一执行。

Build Eleventy步骤设置

  • args: --output html— 定义一个输出文件夹,以便在 SSH 复制设置中指定一个正确的文件夹,该文件夹对应于远程服务器上的一个文件夹(在我们的例子中,它是/var/www/<domain>/html)。
  • install_dependencies: true由于我们使用了第三方 NPM 包clean-css,此设置允许工作流在构建项目时考虑到这些因素dev-dependencies

Copying files to server步骤设置

  • rm: true为了保持环境整洁,我建议启用此设置,以便在下载新文件之前彻底清理远程服务器上的目标文件夹。
  • source: "html/"— 定义要上传到远程服务器的文件夹(将使用有效的数据压缩机制,因此上传过程将尽可能快……即使是大型项目)
  • target: "${{ secrets.REMOTE_DIR }}"— 远程服务器上文件夹的完整路径,文件source将从该文件夹上传。

🤔 等等!什么是${{ secrets }}变量?它们从何而来?别担心,接下来你就会明白一切。继续往下读吧。

💭 了解 GitHub 的秘密

密钥是环境变量,经过加密,仅对特定操作可见。任何拥有协作权限(访问您的代码库)的人都可以在工作流中将这些密钥用作变量,例如${{ secrets.MY_SECRET }}

转到“设置” ,然后在存储库的“密钥”部分旁边:

GitHub 机密 1

您可以点击“新建密钥”按钮来创建新密钥

GitHub 秘籍 2

请创建相同名称的密钥,但使用您自己的值:

  1. REMOTE_DIR— 远程文件夹应该是/var/www/<domain>/html(别忘了定义你的域名,而不是<domain>占位符)
  2. REMOTE_HOST— 您的远程虚拟服务器 IP 地址
  3. REMOTE_USER~/.ssh/authorized_keys— 远程虚拟服务器用户的名称,我们之前已在该用户的设置中添加了SSH 密钥的公钥部分。~/.ssh/gha_rsa.pub
  4. SSH_KEY—本文“SSH 私钥”部分中生成的 SSH密钥的私钥部分的内容~/.ssh/gha_rsa
  5. SSH_KEY_PASSPHRASE— 我们在生成 SSH 密钥时输入的 SSH 密钥密码

↑ 目录

🚀 通过 SSH 部署到服务器

只需git push对您的代码仓库进行更改,等待 GitHub Actions 完成操作,并在操作菜单中获取正在运行的作业的成功状态:

通过 SSH 部署到服务器。

好的!🔥 访问您的全新 11ty 网站:

最终结果

↑ 目录

💬 问题以加深理解

  1. 为什么使用 GitHub Secrets 被认为是一种良好的实践?
  2. 如果未install_dependencies在 GitHub Action 配置中为Eleventy build步骤指定设置,会发生什么情况?
  3. 为什么需要一个使用操作的步骤actions/checkout@master
  4. 如何更改步骤的名称?工作流程的名称又该如何更改?
  5. GitHub Action 配置中最多可以设置多少个步骤?请自行上网查找相关限制
  6. 如果在通过 SSH 将文件复制到远程虚拟服务器的步骤设置中rm启用该选项,会发生什么(或不会发生什么) ?false
  7. 现在使用我在文章的“自动化”章节中提到的脚本来部署新服务器有多容易Droplet on DigitalOcean
  8. 能否通过调度器(例如,通过CRON)配置触发操作?请在 GitHub Actions文档中查找答案。

↑ 目录

✏️ 独立完成的练习

  • 请尝试将文章中提到的所有内容应用到你的项目中。请在本文评论区分享你的结果!
  • 在 GitHub Actions 市场中寻找有趣的操作并进行测试。

↑ 目录

照片/图像由

  • GitHub Actions推广网站(链接
  • 11ty 网站(链接
  • DigitalOcean 控制面板(链接
  • GitHub 仓库设置(链接
  • 真正的网络艺术家代码片段部署库(链接

PS

如果你想在这个博客上看到更多类似的文章,请在下方留言并订阅我。谢谢!😻

❗️您可以通过Boosty平台支持我,既可以长期支持,也可以一次性支持。所有收益都将用于支持我的开源软件项目,并激励我为社区创作新的产品和文章。

在Boosty上支持我

当然,您也可以帮助我让开发者的工作变得更好!只需以贡献者的身份加入我的项目即可。很简单!

我最需要你帮助(和点赞)的项目👇

  • 🔥 gowebly:一款新一代 CLI 工具,可轻松使用 Go 在后端创建出色的 Web 应用程序,使用 htmx、hyperscript 或 Alpine.js 以及最流行的 CSS 框架在前端进行开发。
  • create-go-app:通过运行一条 CLI 命令,创建一个包含 Go 后端、前端和部署自动化功能的新生产就绪项目。

我的其他一些小项目:yatrgosljson2csvcsv2api

文章来源:https://dev.to/koddr/automate-that-a-practical-guide-to-github-actions-build-deploy-a-static-11ty-website-to-remote-virtual-server-after-push-d19