这是本节的多页打印视图。 .

返回本页常规视图.

部署站点

一次构建 Oink,发布静态产物并验证结果。

OINK 部署包含两个独立阶段:Hugo 先生成完整的 public/ 目录,静态托管服务再发布该目录。请把构建验证与线上验证分开,避免把一次成功的本地命令误认为已经完成生产发布。

生产构建

在站点根目录使用固定版本的 Hugo Extended 运行:

hugo --gc --minify --cleanDestinationDir

--gc 会清理不再使用的缓存资源,--minify 生成生产资源,--cleanDestinationDir 删除上次构建残留的文件。如果 publishDir 不是站点专用输出目录,使用最后一个参数前必须先检查命令目标。

构建应顺利完成,并且不能用忽略告警的方式掩盖缺失内容、端点或资源。上传前请先在本地检查 public/

本地预览

编辑期间运行:

hugo server --disableFastRender

Hugo 开发服务器只能证明源码可以渲染;它不是生产托管服务,实时重载行为也不属于生成后的站点。每次发布前都应执行一次干净的生产构建。

构建环境与索引

普通 hugo 命令使用 production 环境。Oink 会把生产构建的 HTML 标记为允许索引,并使用经过优化和指纹处理的资源。公开预览如不应被搜索引擎索引,请改用其他环境构建:

hugo --environment preview --baseURL "https://preview.example.com/"

Oink 会在非生产环境输出 noindex, nofollow。托管层的 X-Robots-Tag 响应头可作为纵深防护,对非 HTML 文件尤其有用。发布到 canonical URL 前,应以 production 环境重新构建已经审查的源码;预览产物不等于生产产物。

静态托管

任何能够提供目录和文件的主机都可以发布 OINK:

  • 对象存储与 CDN;
  • GitHub Pages、GitLab Pages 或类似的 Git 驱动静态托管;
  • Netlify、Cloudflare Pages 或其他构建并发布的平台;
  • Nginx、Caddy、Apache 或内部文件服务器。

请把 baseURL 设置为生产环境 canonical URL。如果站点发布在 https://example.com/manual/ 之类的子路径下,应包含该路径并进行测试;OINK 的本地资源与组件 URL 设计为支持子路径部署。

Cloudflare Pages

让 Pages 直接连接源分支。OINK 不需要由 GitHub Actions 预先构建并推送孤立 Pages 分支。

Oink 站点可使用以下设置:

设置
生产分支 main,或经过审查的源分支
根目录 独立站点目录
构建命令 hugo --gc --minify
构建输出目录 public
HUGO_VERSION 0.164.0
SKIP_DEPENDENCY_INSTALL 1

截至 2026-08-08,Cloudflare Pages v3 构建镜像文档中的默认 Hugo 版本为 0.147.7,低于 OINK 最低要求 0.160.1。应当在 Production 与 Preview 中都显式设置 HUGO_VERSION,不要依赖持续变化的平台默认值。 SKIP_DEPENDENCY_INSTALL=1 可阻止平台的通用依赖安装器增加站点并不需要的前端安装步骤。

预览环境如需使用 Pages 生成的地址作为构建 canonical URL,可以运行:

hugo --gc --minify --baseURL "$CF_PAGES_URL"

Cloudflare 官方文档把 public 列为 Hugo 标准输出目录,并说明了 HUGO_VERSION 覆盖与 CF_PAGES_URL base URL 用法。调整构建镜像或固定 Hugo 版本时,请重新核对平台文档。

参阅 Cloudflare Hugo 指南Cloudflare 构建镜像

网络隔离部署

在断网环境中,应同时传入站点源码与已经验证的主题归档,而不是依赖首次构建时下载 Hugo Module:

  1. 验证主题归档附带的 SHA-256 文件;
  2. 在环境中安装受支持的 Hugo Extended 二进制文件;
  3. 把主题解压到站点的 themes/oink/ 目录;
  4. 设置 theme: oink,并在站点中运行 hugo --gc --minify
  5. public/ 发布到内部静态服务器。

除非已经配置隔离网络内可达的端点,否则请保持 PlantUML 与 Diagrams.net 关闭。外部链接与嵌入内容仍由内容作者负责。

响应头与缓存

带指纹的 CSS 与 JavaScript 可以使用长期 immutable 缓存。HTML、搜索索引、Feed 与站点地图应使用较短缓存或重新验证,以便新部署及时生效。

支持 _headers 约定的托管平台可以读取站点自有的 static/_headers 文件。这不是可移植标准;应根据站点实际使用的行内内容与集成审查安全响应头。

预览与生产 URL

canonical、hreflang、Open Graph、Feed 与绝对链接都依赖 baseURL。生产构建应使用生产 URL;如果链接验证或社交元数据需要准确,预览构建可以使用临时地址。

不要把针对预览地址生成的产物直接发布到生产环境;反过来,也不要因为预览中出现有意传入的预览域名就判定失败。

部署验收

每一层都要独立验证:

源码与配置

  • 预期提交与固定主题版本确实存在;
  • baseURL、语言、菜单、仓库元数据与可选端点正确;
  • 未发布草稿或秘密信息没有进入公开内容树。

构建产物

  • 使用固定版本的 Hugo Extended 完成干净生产构建;
  • 英文、中文、Feed、站点地图、搜索索引与 404.html 均存在;
  • 本地资源在根路径与配置的子路径下都能解析;
  • 产物包含所需许可证与归属说明。

托管站点

  • 生产 URL 返回新产物;
  • canonical 与备用语言 URL 使用生产域名;
  • 导航、搜索、语言切换、深色模式、打印和代表性组件在真实浏览器中工作;
  • 重定向、自定义响应头、缓存策略与 404 行为符合配置;
  • “支持网络隔离”的结论有浏览器网络审计作为依据。

绿色构建日志只完成产物阶段;托管检查全部通过后,部署才算完成。

回滚

保留上一份已知可用的静态产物或托管平台部署标识。新版本未通过线上验证时,应先恢复该产物,再诊断源码或平台行为。使用新的、未固定工具链重新构建旧提交,并不等同于恢复原产物。

1 - 在本地运行站点

使用 Hugo 开发服务器在本地预览内容。

根据所选部署方式,你可能需要在开发期间于本地运行站点,以便预览内容变更。具体步骤如下:

  1. 确认已经从代码仓库克隆站点文件,并将本地副本更新至最新状态。

  2. 按照前提条件与安装中的说明,安装 Hugo Extended,以及所选主题安装方式获取源码时需要的工具。Node.js 和 PostCSS 不是站点构建的前提条件。

  3. 在站点根目录运行 hugo server。默认情况下,可以通过 http://localhost:1313 访问站点。

站点在本地运行后,Hugo 会监视内容变更并自动刷新页面。如果本地有多个 Git 分支,切换分支后,本地站点也会随之反映当前分支中的文件。

2 - 部署到 GitHub Pages

使用 GitHub Actions 与 Pages 构建并发布 Oink 站点。

如果源码托管在 GitHub,只需一份 Actions 工作流,就能通过 GitHub Pages 构建并发布站点。消费站点需要 Hugo Extended,但不需要 Node.js、npm、PostCSS,也不需要生成专门的部署分支。

项目站点的 URL 形如 https://<OWNER>.github.io/<REPOSITORY>/;用户和组织站点使用 https://<OWNER>.github.io/。GitHub Pages 也支持自定义域名。

准备代码仓库

把完整的站点源码推送到 GitHub,并确认在仓库根目录执行以下命令能够成功:

hugo --gc --minify

将站点的 baseURL 设为生产 URL,或者在工作流中通过 Hugo 的 --baseURL 参数传入 Pages URL。项目站点必须包含仓库路径,否则 CSS、JavaScript 和其他资源会从错误的位置解析。

添加 Pages 工作流

创建 .github/workflows/pages.yml,内容如下。请让 HUGO_VERSION 始终与主题已经验证的版本保持一致。

name: Deploy Hugo site to Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: false

env:
  GO_VERSION: 1.25.5
  HUGO_VERSION: 0.164.0

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
          submodules: recursive
      - uses: actions/setup-go@v6
        with:
          go-version: ${{ env.GO_VERSION }}
      - name: Install Hugo Extended
        run: |
          curl -L -o hugo.deb \
            "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb"
          sudo dpkg -i hugo.deb
      - uses: actions/configure-pages@v6
        id: pages
      - name: Build
        run: >-
          hugo --gc --minify --baseURL "${{ steps.pages.outputs.base_url }}/"
      - uses: actions/upload-pages-artifact@v5
        with:
          path: public

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy
        id: deployment
        uses: actions/deploy-pages@v5

如果通过 Git submodule 安装主题,submodules: recursive 会在 Hugo 运行前检出主题。如果使用完整离线归档,则可以把站点内的 themes/oink/ 目录提交到仓库,或在构建输入中恢复该目录。

启用 GitHub Pages

在仓库设置中打开 Pages。在 Build and deployment 下,将 Source 设为 GitHub Actions。把工作流推送到 main,然后在仓库的 Actions 标签页中查看第一次运行。

工作流只上传生成的 public/ 目录,并通过 Pages 部署 API 发布,不会维护 gh-pages 分支。

有关其他身份验证、域名和权限选项,请参阅 GitHub 的 Pages 文档和 Hugo 的 GitHub 托管指南

3 - 部署到 Cloudflare Pages

使用 Cloudflare Pages 构建并发布 Oink 站点。

Cloudflare Pages 可以从关联的 GitHub 或 GitLab 仓库构建 Oink 站点,并为评审分支创建预览部署。消费端直接运行 Hugo Extended,无需安装前端软件包。

配置项目

Workers & Pages 中导入仓库,选择生产分支,并使用以下设置:

设置
生产分支 main,或经过评审的源码分支
构建命令 hugo --gc --minify
构建输出目录 public
HUGO_VERSION 0.164.0
SKIP_DEPENDENCY_INSTALL 1

请在 Production 与 Preview 环境中都设置 HUGO_VERSION。Cloudflare Pages 的 v3 构建镜像当前默认使用 Hugo 0.147.7,低于 Oink 要求的最低版本 0.160.1。固定已经验证的版本,可以避免构建镜像更新时静默改变工具链。SKIP_DEPENDENCY_INSTALL=1 会禁用 Oink 消费端不需要的通用依赖安装步骤。

如果 Hugo 站点不在仓库根目录,请把 Root directory 设置为站点目录。输出目录相对于这个根目录解析。

设置 base URL

生产构建应在 baseURL 中使用站点的规范自定义域名。如果预览需要在 canonical 与绝对链接中使用自动生成的 Pages URL,可以运行:

hugo --gc --minify --baseURL "$CF_PAGES_URL"

不得把这份预览产物直接发布到生产环境;生产发布前必须使用规范域名重新构建。

部署并验证

保存配置并检查第一次构建日志。正常的 Oink 消费端构建应该直接运行 Hugo,不执行 npm、PostCSS、Autoprefixer,也不下载主题自有 CDN 资源。部署后检查:

  • *.pages.dev 预览地址或自定义域名提供的是预期 commit;
  • 英文与译文路由使用预期的规范来源;
  • 搜索、语言切换、深色模式、打印与代表性组件正常工作;
  • 重定向、响应头、自定义域名与 404 行为符合 Pages 项目配置。

Cloudflare 的 Git 集成与 Direct Upload 是不同的项目模式。如果后续必须接入外部部署流水线,请在选择模式前核对当前 Pages 文档。

4 - 部署到 Netlify

仅使用 Hugo 将 OINK 站点部署到 Netlify。

Netlify 可以从 GitHub、GitLab 或 Bitbucket 构建站点,并为每个拉取请求发布预览。OINK 消费端会直接运行 Hugo Extended,不安装 Node.js 软件包,也不调用 PostCSS。

配置站点

把完整源码推送到 Git 服务商,在 Netlify 中导入仓库,然后使用以下构建设置:

设置
构建命令 hugo --gc --minify
发布目录 public
HUGO_VERSION 0.164.0 或主题验证过的其他版本

如果 Netlify 检测到仅供主题维护工具使用的软件包清单,请为站点关闭自动依赖安装。这些工具不属于消费端构建合同。

如果通过 Git submodule 安装主题,请启用递归 submodule 检出。如果使用 Hugo 模块,Netlify 还需要具备普通的 Git 和 Go 访问能力,以便在全新构建中下载已经固定版本的模块。完整离线发行包使用相邻的 themes/oink/ 目录,可避免首次构建时下载依赖。

将配置保存在仓库中

也可以把同样的设置写入 netlify.toml 并提交:

[build]
command = "hugo --gc --minify"
publish = "public"

[build.environment]
HUGO_VERSION = "0.164.0"

除非预览环境专门用于测试升级,否则生产环境和部署预览应使用同一个 Hugo 版本。如果预览构建需要把自动生成的 URL 作为 base URL,请在对应环境的 Hugo 命令中加入 Netlify 部署 URL。

如果不希望非生产部署被索引,请按照构建环境与索引中的说明使用非生产 Hugo 环境。

保存设置后触发一次部署,并检查构建日志。正常的消费端构建应该只出现一条 Hugo 命令,不应运行 npm、PostCSS、Autoprefixer、CDN 下载或构建期远程资源步骤。

5 - 使用 Amazon S3 和 CloudFront 部署

使用 Amazon S3 与 CloudFront 发布 Oink 构建产物。

通过 Amazon Web Services 发布网站有多种方案。本节介绍最基础的一种:把站点部署到 S3 存储桶,并启用 CloudFront CDN(内容分发网络)来加速已部署内容的传输。

  1. 完成 AWS 注册后,创建 S3 存储桶,将其关联到你的域名,再加入 CloudFront CDN。可以参考这篇博客文章,其中包含完整流程和易于操作的分步说明。

  2. 下载并安装最新版 AWS 命令行界面(CLI)v2。随后运行 aws configure 配置 CLI 实例(请提前准备 AWS Access Key ID 和 AWS Secret Access Key):

    $ aws configure
    AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
    AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    Default region name [None]: eu-central-1
    Default output format [None]:
    
  3. 运行 aws s3 ls 检查 AWS CLI 配置是否正确;命令应输出你的 S3 存储桶列表。

  1. hugo.tomlhugo.yamlhugo.json 中添加如下 [deployment] 分区:

    [deployment]
    [[deployment.targets]]
    name = "aws"
    URL = "s3://www.your-domain.tld"
    cloudFrontDistributionID = "E9RZ8T1EXAMPLEID"
    deployment:
      targets:
        - name: aws
          URL: 's3://www.your-domain.tld'
          cloudFrontDistributionID: E9RZ8T1EXAMPLEID
    {
      "deployment": {
        "targets": [
          {
            "name": "aws",
            "URL": "s3://www.your-domain.tld",
            "cloudFrontDistributionID": "E9RZ8T1EXAMPLEID"
          }
        ]
      }
    }
  1. 运行 hugo --gc --minify,将站点资源渲染到 Hugo 构建环境的 public/ 目录。

  2. 使用 Hugo 内置的 deploy 命令把站点部署到 S3:

    hugo deploy
    Deploying to target "aws" (www.your-domain.tld)
    Identified 77 file(s) to upload, totaling 5.3 MB, and 0 file(s) to delete.
    Success!
    Invalidating CloudFront CDN...
    Success!
    

    如输出所示,执行 hugo deploy 会自动使 CloudFront CDN 缓存失效

  3. 至此全部完成。今后只需使用 Hugo 内置的 deploy 命令,即可轻松部署到 S3 存储桶。

有关 Hugo deploy 命令及其命令行参数的更多信息,请参阅命令概览。其中,--maxDeletes int 和强制上传所有文件的 --force 参数可能会很有用。

如果 S3 无法满足需求,可以考虑 AWS Amplify Console。这是更高级的持续部署(CD)平台,内置对 Hugo 静态站点生成器的支持。Hugo 官方文档提供了相应的入门指南