跳到主要内容

Vercel 部署 Hugo + Congo 完整教程:从 GitHub 推送到自定义域名

如果你已经把博客放在 Hugo + Congo 上,又不想在本地长期维护一整套构建环境,那么最省心的一条路,通常就是:

GitHub -> Vercel -> Cloudflare

这篇教程会把整条链路一次写完整:

  • 本地仓库推到 GitHub
  • Vercel 自动拉取并构建 Hugo + Congo
  • 自定义域名接到 Cloudflare
  • apex + www + HTTPS 一次配好

适用场景 #

这篇文章更适合下面这类情况:

  • 你已经有一个 Hugo 博客
  • 主题用了 Congo
  • 你希望以后只要 git push 就自动部署
  • 你的域名托管在 Cloudflare

前置准备 #

开始前先确认这些东西都已经有了:

  • 一个 GitHub 账号
  • 一个 Vercel 账号
  • 一个 Cloudflare 账号和一个可用域名
  • 一个已经能正常生成页面的 Hugo + Congo 仓库
  • 仓库根目录至少有 content/config/_default/go.modbuild.shvercel.json

如果你和我现在这套一样,把构建逻辑放进 build.sh,那么 vercel.json 可以保持成下面这样:

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "framework": null,
  "buildCommand": "chmod a+x build.sh && ./build.sh",
  "outputDirectory": "public"
}

按我在 2026-03-19 查的官方文档,Vercel 本身支持 Hugo,简单项目通常也能自动识别。
但像 Congo + Hugo Modules + 自定义 build.sh 这种组合,显式把构建命令和输出目录写清楚会更稳。

build.sh 里至少要负责这几件事:

  • 安装本次构建需要的 GoHugo
  • 处理 shallow clone,避免模块拉取出问题
  • 更新或拉取 Congo 模块
  • 最后执行 hugo --gc --minify

第一步:准备仓库并首次推送 #

先在 GitHub 创建一个空仓库,然后在本地仓库执行下面这几步:

git init
git add .
git commit -m "init blog"
git branch -M main
git remote add origin git@github.com:yourname/your-blog.git
git push -u origin main

这一步的重点不是命令本身,而是确认你的博客代码已经完整进入 GitHub,并且默认分支是 main

Git push and repo structure

推送完成后,建议回 GitHub 网页看一眼,至少确认这些文件和目录都在:

  • content/
  • config/_default/
  • go.mod
  • build.sh
  • vercel.json

第二步:在 Vercel 导入项目 #

打开 Vercel 后,按下面的顺序操作:

  1. Add New -> Project
  2. 选择刚才那个 GitHub 仓库
  3. Framework 选 Other
  4. Build Command 填 chmod a+x build.sh && ./build.sh
  5. Output Directory 填 public
  6. Deploy

Vercel import and build settings

如果你的 Hugo 项目完全走官方默认方式,Vercel 有时会直接识别出来。
但只要你用了自定义 build.sh,这里就尽量不要省,直接把构建参数写死。

第三步:验证首次部署 #

首次部署完成后,先不要急着去绑域名,先看这几件事:

  • .vercel.app 地址能正常打开
  • 首页、文章页、分类页渲染都正常
  • 重新 push 一次后会触发新部署
  • main 分支能生成 Preview 链接

后续日常更新其实非常简单,流程基本就是:

git add .
git commit -m "publish new post"
git push origin main

推送完成之后:

  • main 分支通常会更新生产环境
  • 其他分支会生成 Preview 链接

第四步:在 Vercel 里添加自定义域名 #

进入项目后打开:

Settings -> Domains

建议一次把这两个都加上:

  • example.com
  • www.example.com

如果这个域名之前在别的 Vercel 账号里用过,面板可能会要求你先做 TXT 验证。
这时候按面板提示加验证记录就行,而且如果有多个域名要验证,最好按 Vercel 的提示一条一条来。

这里还有一个取舍:

  • 如果你没有强偏好,按 Vercel 官方当前建议,把 www 设为主域名会更稳
  • 如果你更喜欢裸域,也可以把 example.com 设成主域名,只是这不是官方首选

第五步:到 Cloudflare 配 DNS #

回到 Cloudflare 的 DNS 页面,把 Vercel 面板要求的记录填进去。

Cloudflare DNS records

比较常见的写法是:

Type    Name      Value
A       @         76.76.21.21
CNAME   www       cname.vercel-dns-0.com
TXT     _vercel   vc-domain-verify=...

这里有两个细节最重要:

  • TXT 记录只在 Vercel 要求验证所有权时才需要加
  • 真正应该填什么值,以 Vercel 面板给你的推荐记录为准

按目前官方文档,76.76.21.21cname.vercel-dns-0.com 是通用值。
但项目实际也可能给你一个专属的 CNAME 目标,例如 xxxx.vercel-dns-017.com。只要面板给的值不同,就优先听面板。

如果你开了 Cloudflare 代理,验证阶段一旦卡住,可以先临时切到 DNS only,等 Vercel 状态正常后再决定要不要开回去。

第六步:回到 Vercel 看验证和 HTTPS #

DNS 改完之后,回到 Vercel 的 Domains 页面刷新状态,正常会经历:

  • Pending
  • Verifying
  • Valid Configuration

Vercel domain verification and SSL

当域名状态变成有效后,Vercel 会继续给你配 HTTPS。
只要一切正常,过一会儿就能直接用 https:// 打开了。

这一步顺手再检查三件事:

  • 主域名是不是你想要的那个
  • 另一个域名有没有正确跳转过去
  • 证书状态是不是已经激活

如果你没特别需求,我会建议把 www 设为主域名,再让裸域跳转过去。
这是 Vercel 目前的官方推荐,因为 wwwCNAME,弹性和容错会更好一些。

第七步:日常维护怎么做 #

前面这套跑通之后,后面的维护就很简单了:

  • 写文章或改模板
  • 提交到 Git
  • push 到 GitHub
  • 等 Vercel 自动构建

如果你想稳一点,我建议保留这几个习惯:

  • 每次只提交一类改动,文章和模板尽量不要混在一个 commit 里
  • 先看 Preview,再决定要不要合到 main
  • 新文章的 date 不要写到未来
  • 如果 build.sh 里会自动更新 Congo,就接受“上游更新后部署结果也可能变化”这件事

常见问题 #

Vercel 导入后直接构建失败 #

优先检查这些地方:

  • build.sh 有没有执行权限,或者构建命令里有没有先 chmod a+x
  • go.mod 是否存在,Congo 模块是不是能正常拉到
  • 仓库是不是 shallow clone,导致模块解析或 Git 信息不完整

Preview 链接能开,但绝对地址指到正式站 #

这种情况通常是 baseURL 处理得不对。
如果你在 build.sh 里手动传了 --baseURL,记得区分:

  • 生产环境
  • Preview 环境

不然 Preview 里的 canonical、RSS、跳转地址可能都会指回正式域名。

域名状态一直 Pending 或 Invalid #

先排查:

  • 记录类型对不对
  • @www_vercel 这些主机名有没有写错
  • Cloudflare 里有没有旧记录冲突
  • 你填的是不是 Vercel 面板当前推荐值

证书迟迟不签发 #

常见排查顺序是:

  • 先确认域名在 Vercel 里已经是 Valid Configuration
  • 检查是否有干扰签发的 CAA 记录
  • 如果验证过程不顺,先把 Cloudflare 代理临时切到 DNS only

小结 #

对个人博客来说,GitHub + Vercel + Cloudflare + Hugo + Congo 这套组合最大的优点不是“有多炫”,而是顺手:

  • 写文章像写代码一样可追踪
  • git push 就是部署
  • Preview 和生产环境分得很清楚
  • 域名、HTTPS、后续扩展都比较省心

前面这套走通之后,你的博客就已经是一个比较完整的公开站点了。
后面如果还要继续折腾,再去补评论系统、统计脚本、邮件推送或者缓存规则,会轻松很多。

参考 #