托管平台部署指南

Hugo 作为静态站点生成器所带来的部署简便性、灵活性和自动化潜力,使其生成的网站能够被部署到几乎任何提供文件托管服务的平台。本文详细介绍各种内置和社区支持的部署方式。

部署核心机制

静态站点的优势

Hugo 生成的是完整的静态网站,具有以下特点:

  • 简化部署过程:不需要服务器端语言或数据库
  • 直接在浏览器运行:与任何集成 API 交互
  • 快速渲染:能在数秒内渲染出整个网站
  • 部署灵活性:可部署到任何支持文件托管的平台

发布机制

public 目录

运行 hugo 命令后,Hugo 会在项目根目录下的 public 目录中创建完整的静态网站:

hugo

生成的内容包括:

  • HTML 文件
  • 图像资源
  • CSS 样式文件
  • JavaScript 脚本
  • 其他静态资源

重要注意事项

  • 不自动清理:Hugo 默认不会清理 public 目录
  • 文件覆盖:会覆盖现有文件,但不删除旧文件
  • 手动清理:根据需要手动清理目录以避免文件残留
  • 内容过滤:默认不包含草稿、未来或过期内容
# 清理并重新构建
rm -rf public
hugo

# 构建时包含草稿内容
hugo --buildDrafts

开发与部署分离

开发阶段:

# 启动开发服务器
hugo server -D

# 带有调试信息的开发服务器
hugo server --debug --disableFastRender

部署阶段:

# 生产环境构建
hugo --environment production --minify

内置部署工具

hugo deploy 命令

Hugo 提供内置的 hugo deploy 命令,支持直接部署到主流云存储服务。

支持的服务

  • Amazon S3
  • Azure Blob Storage
  • Google Cloud Storage

版本要求

需要 Hugo 的 extended/deploy 版本。

配置示例

# hugo.toml
[deployment]
order = [".jpg$", ".gif$"]

[[deployment.targets]]
name = "production"
URL = "s3://my-bucket?region=us-east-1"

[[deployment.targets]]
name = "staging"
URL = "s3://my-staging-bucket?region=us-east-1"

# 缓存控制配置
[[deployment.matchers]]
pattern = "^.+\\.(js|css|svg|ttf)$"
cacheControl = "max-age=31536000, no-transform, public"
gzip = true

[[deployment.matchers]]
pattern = "^.+\\.(png|jpg)$"
cacheControl = "max-age=31536000, no-transform, public"
gzip = false

[[deployment.matchers]]
pattern = "^.+\\.(html|xml|json)$"
gzip = true

部署流程

  1. 文件列表创建:遍历本地 public 目录和远程存储桶
  2. 文件比较:比较文件名称、大小和 MD5 校验和
  3. 同步执行:上传缺失或更改的文件,删除远程多余文件
  4. 安全保护:默认不删除超过 256 个远程文件

使用命令

# 预览部署差异
hugo deploy --dryRun

# 确认部署
hugo deploy --confirm

# 部署到特定目标
hugo deploy --target staging

# 设置最大删除文件数
hugo deploy --maxDeletes 100

第三方部署工具

rclone 部署

rclone 是用于同步文件到多种云存储的命令行工具。

安装 rclone

# macOS
brew install rclone

# Linux
curl https://rclone.org/install.sh | sudo bash

配置示例

# 配置远程存储
rclone config

# SFTP 部署脚本
#!/bin/bash
hugo --minify
rclone sync public/ sftp:myserver/public_html/ \
  --delete-after \
  --exclude-from .rcloneignore

.rcloneignore 文件

.DS_Store
Thumbs.db
*.tmp

rsync 部署

rsync 是 Unix/Linux 系统上常用的文件同步工具。

部署脚本示例

#!/bin/bash

echo "开始构建网站..."
hugo --minify

echo "同步到服务器..."
rsync -avz --delete \
  --exclude '.DS_Store' \
  --exclude 'Thumbs.db' \
  public/ \
  [email protected]:/var/www/html/

echo "部署完成!"

SSH 密钥认证

# 生成 SSH 密钥对
ssh-keygen -t rsa -b 4096 -C "[email protected]"

# 复制公钥到服务器
ssh-copy-id [email protected]

# 测试连接
ssh [email protected]

主流托管平台

Netlify

手动部署

# 安装 Netlify CLI
npm install -g netlify-cli

# 登录
netlify login

# 构建并部署
hugo --minify
netlify deploy --prod --dir public

自动部署配置

创建 netlify.toml

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

[build.environment]
  HUGO_VERSION = "0.146.0"
  HUGO_ENV = "production"
  HUGO_ENABLEGITINFO = "true"

[context.production.environment]
  HUGO_BASEURL = "https://example.com/"

[context.deploy-preview]
  command = "hugo --gc --minify --buildDrafts --buildFuture"

[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"
    Content-Security-Policy = "frame-ancestors https://www.netlify.com/"

[[redirects]]
  from = "/old-path/*"
  to = "/new-path/:splat"
  status = 301

Vercel

vercel.json 配置

{
  "build": {
    "env": {
      "HUGO_VERSION": "0.146.0"
    }
  },
  "functions": {
    "app/api/**/*.go": {
      "runtime": "vercel-go@latest"
    }
  },
  "routes": [
    {
      "src": "/(.*)",
      "headers": {
        "cache-control": "s-maxage=31536000"
      },
      "continue": true
    }
  ]
}

部署脚本

#!/bin/bash
# build.sh

# 安装 Hugo
wget -O hugo.tar.gz https://github.com/gohugoio/hugo/releases/download/v0.146.0/hugo_extended_0.146.0_Linux-64bit.tar.gz
tar -xzf hugo.tar.gz
chmod +x hugo

# 构建网站
./hugo --minify --environment production

GitHub Pages

GitHub Actions 工作流

创建 .github/workflows/hugo.yml

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

defaults:
  run:
    shell: bash

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      HUGO_VERSION: 0.146.0
    steps:
      - name: Install Hugo CLI
        run: |
          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
          && sudo dpkg -i ${{ runner.temp }}/hugo.deb
      
      - name: Install Dart Sass
        run: sudo snap install dart-sass
      
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5
      
      - name: Install Node.js dependencies
        run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
      
      - name: Build with Hugo
        env:
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production
        run: |
          hugo \
            --gc \
            --minify \
            --baseURL "${{ steps.pages.outputs.base_url }}/"
      
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./public

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

GitLab Pages

.gitlab-ci.yml 配置

image: registry.gitlab.com/pages/hugo/hugo_extended:latest

variables:
  GIT_SUBMODULE_STRATEGY: recursive

before_script:
  - apk add --update --no-cache git

pages:
  script:
    - hugo --gc --minify --baseURL $CI_PAGES_URL
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

test:
  stage: test  
  script:
    - hugo --gc --minify --baseURL https://example.com --buildDrafts
  except:
    - master

Cloudflare Pages

自动部署配置

  1. 构建设置

    • 构建命令:hugo --gc --minify
    • 构建输出目录:public
    • 根目录:/
  2. 环境变量

    HUGO_VERSION=0.146.0
    HUGO_ENV=production
    
  3. 自定义域名设置

    # hugo.toml
    baseURL = "https://yourdomain.com"
    

Firebase Hosting

初始化配置

# 安装 Firebase CLI
npm install -g firebase-tools

# 登录
firebase login

# 初始化项目
firebase init hosting

firebase.json 配置

{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [
      {
        "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
        "headers": [
          {
            "key": "Access-Control-Allow-Origin",
            "value": "*"
          }
        ]
      }
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

部署脚本

#!/bin/bash

echo "构建 Hugo 网站..."
hugo --gc --minify

echo "部署到 Firebase..."
firebase deploy --only hosting

echo "部署完成!"

CI/CD 最佳实践

环境配置

# GitHub Actions 示例
env:
  HUGO_VERSION: 0.146.0
  HUGO_ENV: production
  HUGO_ENABLEGITINFO: true
  NODE_VERSION: '18'

缓存优化

# 缓存 Hugo 资源
- name: Cache Hugo resources
  uses: actions/cache@v3
  with:
    path: resources
    key: ${{ runner.os }}-hugo-resources-${{ hashFiles('**/hugo.toml') }}

# 缓存 Node.js 依赖
- name: Cache Node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

多环境部署

strategy:
  matrix:
    environment: [staging, production]
    
steps:
  - name: Deploy to ${{ matrix.environment }}
    run: |
      hugo --environment ${{ matrix.environment }} --minify
      # 部署逻辑...

部署前检查

#!/bin/bash

# 检查链接
hugo --gc --minify
htmlproofer public --check-html --check-opengraph --check-favicon

# 检查性能
lighthouse-ci autorun

# 安全检查
npm audit

故障排除

常见问题

  1. 构建失败

    • 检查 Hugo 版本兼容性
    • 验证主题子模块状态
    • 确认环境变量设置
  2. 资源加载问题

    • 检查 baseURL 配置
    • 验证相对路径设置
    • 确认资源文件路径
  3. 部署不完整

    • 检查忽略文件配置
    • 验证目录权限
    • 确认同步设置

调试技巧

# 详细日志输出
hugo --debug --log --verboseLog

# 检查配置
hugo config

# 验证环境
hugo env

通过选择合适的托管平台和部署策略,您可以实现高效、可靠的 Hugo 网站部署流程。

文章导航

章节内容

这是章节的内容页面。

章节概览