部署发布
完成 Hugo 站点开发后,需要将其部署到服务器上。本章将介绍多种部署方式。
构建站点
本地构建
使用 hugo 命令构建静态文件:
# 构建站点
hugo
# 构建包含草稿
hugo -D
# 构建未来日期的内容
hugo -F
# 指定输出目录
hugo -d public
# 指定配置文件
hugo --config config.production.toml
# 指定基础 URL
hugo -b https://example.org/
# 最小化输出
hugo --minify
构建完成后,所有静态文件会生成在 public/ 目录下。
构建环境
设置环境变量控制构建行为:
# 设置为生产环境
HUGO_ENV=production hugo
# 设置基础 URL
HUGO_BASEURL=https://example.org/ hugo
在模板中检测环境:
{{ if eq hugo.Environment "production" }}
<!-- 生产环境特定内容 -->
{{ template "_internal/google_analytics.html" . }}
{{ end }}
部署到 GitHub Pages
GitHub Pages 是最流行的免费静态网站托管服务之一。
准备工作
- 创建 GitHub 仓库
- 将站点代码推送到仓库
方法一:GitHub Actions(推荐)
创建 .github/workflows/deploy.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
jobs:
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.121.1
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
fetch-depth: 0
- name: Setup Pages
id: pages
uses: actions/configure-pages@v4
- 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
方法二:手动部署
# 构建站点
hugo --minify
# 切换到输出目录
cd public
# 初始化 Git
git init
git add .
git commit -m "Deploy"
# 推送到 gh-pages 分支
git push -f [email protected]:username/repo.git main:gh-pages
配置自定义域名
- 在仓库 Settings > Pages 中设置自定义域名
- 在站点根目录创建
static/CNAME文件:
www.example.com
- 更新
hugo.toml中的baseURL:
baseURL = 'https://www.example.com/'
部署到 Netlify
Netlify 提供了简单的部署流程和强大的功能。
通过 Netlify UI 部署
- 登录 Netlify
- 点击 "Add new site" > "Import an existing project"
- 连接 GitHub/GitLab/Bitbucket 仓库
- 配置构建设置:
- Build command:
hugo - Publish directory:
public
- Build command:
- 设置环境变量:
HUGO_VERSION:0.121.1
通过 netlify.toml 配置
在项目根目录创建 netlify.toml:
[build]
publish = "public"
command = "hugo --gc --minify"
[context.production.environment]
HUGO_VERSION = "0.121.1"
HUGO_ENV = "production"
[context.deploy-preview.environment]
HUGO_VERSION = "0.121.1"
[context.branch-deploy.environment]
HUGO_VERSION = "0.121.1"
[[redirects]]
from = "/old-url/"
to = "/new-url/"
status = 301
force = true
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
Netlify 功能
预览部署
每次推送代码都会生成预览链接,方便测试。
表单处理
<form name="contact" method="POST" data-netlify="true">
<input type="text" name="name">
<input type="email" name="email">
<textarea name="message"></textarea>
<button type="submit">发送</button>
</form>
函数支持
创建 netlify/functions/hello.js:
exports.handler = async function(event, context) {
return {
statusCode: 200,
body: JSON.stringify({message: "Hello World"})
};
};
部署到 Vercel
Vercel 是另一个流行的静态网站托管平台。
通过 Vercel UI 部署
- 登录 Vercel
- 点击 "New Project"
- 导入 Git 仓库
- Vercel 会自动检测 Hugo 框架
- 点击 "Deploy"
通过 vercel.json 配置
{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "@vercel/static-build",
"config": {
"distDir": "public"
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/$1"
}
]
}
设置环境变量
在 Vercel 项目设置中添加:
HUGO_VERSION:0.121.1
部署到 Cloudflare Pages
Cloudflare Pages 提供全球 CDN 和安全功能。
部署步骤
- 登录 Cloudflare Dashboard
- 进入 Pages > Create a project
- 连接 Git 仓库
- 配置构建设置:
- Framework preset: Hugo
- Build command:
hugo - Build output directory:
public
- 设置环境变量:
HUGO_VERSION:0.121.1
Cloudflare Functions
创建 functions/api/hello.js:
export async function onRequest(context) {
return new Response(JSON.stringify({message: "Hello World"}), {
headers: {'Content-Type': 'application/json'}
});
}
部署到自己的服务器
使用 rsync 同步
# 同步到服务器
rsync -avz --delete public/ user@server:/var/www/html/
# 使用 SSH 密钥
rsync -avz -e "ssh -i ~/.ssh/id_rsa" --delete public/ user@server:/var/www/html/
使用部署脚本
创建 deploy.sh:
#!/bin/bash
echo "Building site..."
hugo --minify
echo "Deploying to server..."
rsync -avz --delete public/ user@server:/var/www/html/
echo "Deployment complete!"
Nginx 配置
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 启用 Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# 缓存静态资源
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}
Apache 配置
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
<Directory /var/www/html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
# 启用 URL 重写
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /$1 [L]
</Directory>
# 缓存设置
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
</IfModule>
</VirtualHost>
部署到对象存储
AWS S3 + CloudFront
# 同步到 S3
aws s3 sync public/ s3://my-bucket/ --delete
# 使 CloudFront 缓存失效
aws cloudfront create-invalidation --distribution-id DISTRIBUTION_ID --paths "/*"
阿里云 OSS
# 使用 ossutil 同步
ossutil sync public/ oss://my-bucket/ --delete
腾讯云 COS
# 使用 coscmd 同步
coscmd upload -r public/ /
自动化部署
使用 Git Hooks
创建 .git/hooks/post-receive:
#!/bin/bash
GIT_REPO=/path/to/repo.git
WORKING_DIRECTORY=/path/to/working
PUBLIC_WWW=/var/www/html
git --work-tree=$WORKING_DIRECTORY --git-dir=$GIT_REPO checkout -f
cd $WORKING_DIRECTORY
hugo --minify
rsync -avz --delete public/ $PUBLIC_WWW/
使用 Makefile
.PHONY: build deploy clean
build:
hugo --minify
deploy: build
rsync -avz --delete public/ user@server:/var/www/html/
clean:
rm -rf public/
serve:
hugo server -D
持续集成配置
GitLab CI/CD
创建 .gitlab-ci.yml:
image: registry.gitlab.com/pages/hugo/hugo_extended:latest
variables:
GIT_SUBMODULE_STRATEGY: recursive
pages:
script:
- hugo --gc --minify
artifacts:
paths:
- public
only:
- main
CircleCI
创建 .circleci/config.yml:
version: 2.1
jobs:
build:
docker:
- image: cibuilds/hugo:latest
steps:
- checkout
- run: git submodule sync && git submodule update --init
- run: hugo --gc --minify
- persist_to_workspace:
root: .
paths:
- public
deploy:
docker:
- image: node:latest
steps:
- attach_workspace:
at: .
- run: npm install -g netlify-cli
- run: netlify deploy --prod --dir=public
workflows:
version: 2
build-deploy:
jobs:
- build
- deploy:
requires:
- build
性能优化
启用 HTTP/2
确保服务器支持 HTTP/2,大多数现代托管平台默认支持。
启用 CDN
使用 Cloudflare、AWS CloudFront 等加速全球访问。
资源优化
# hugo.toml
[minify]
disableCSS = false
disableHTML = false
disableJS = false
disableJSON = false
disableSVG = false
disableXML = false
minifyOutput = true
图片优化
<!-- 使用 Hugo 图片处理 -->
{{ $image := resources.Get "images/photo.jpg" }}
{{ $webp := $image.Resize "800x webp" }}
<img src="{{ $webp.Permalink }}" alt="Photo">
监控与分析
Google Analytics
<!-- 在 baseof.html 中添加 -->
{{ template "_internal/google_analytics.html" . }}
配置 Google Analytics 4
# hugo.toml
googleAnalytics = 'G-XXXXXXXXXX'
其他分析工具
- Plausible:隐私友好的分析工具
- Umami:开源的网站分析工具
- Cloudflare Analytics:免费且隐私友好
小结
本章介绍了 Hugo 站点的多种部署方式:
- GitHub Pages 适合个人项目,免费且简单
- Netlify 和 Vercel 提供更多功能和更好的体验
- Cloudflare Pages 提供全球 CDN 加速
- 自建服务器需要更多运维工作
- 对象存储适合纯静态站点
- 自动化部署提高效率
选择合适的部署方式取决于项目需求和预算。对于个人博客,GitHub Pages 或 Netlify 是不错的选择。