CentOS 7 云服务器部署踩坑记(六):Hugo 主题迁移与远程部署工作流

背景#

博客从 Vercel 迁到阿里云服务器后,一直用 PaperMod 主题。觉得风格不够适合,决定换成 hugo-book——左侧固定导航栏、白底极简、可读性好,接近 Simon Willison 的风格。

这篇记录换主题过程中遇到的问题,以及最终确定的部署工作流。

本系列文章:

  1. SSH 连接与服务器初始化
  2. Python 3.11 编译与 SSL 模块配置
  3. Hugo 博客部署与 Nginx 配置
  4. Python 包安装与 GCC 版本问题
  5. Supervisor 进程管理与应用启动
  6. Hugo 主题迁移与远程部署工作流(本篇)

SSH 连接服务器#

先确认能连上服务器,后续所有操作都依赖这一步。

首次连接#

ssh root@你的服务器IP

第一次连接会提示确认指纹,输入 yes 回车,服务器指纹会保存到本地 ~/.ssh/known_hosts

配置免密登录(推荐)#

每次输密码很麻烦,用 SSH 密钥一劳永逸。

本地生成密钥:

ssh-keygen -t ed25519 -C "your@email.com"

上传公钥到服务器:

ssh-copy-id root@你的服务器IP

之后直接 ssh root@你的IP 即可,无需输密码。

查看服务器公网 IP#

登录阿里云 ECS 控制台,实例列表里「公网 IP」一列即是。也可以在服务器上执行:

curl ifconfig.me

GitHub 认证问题#

在服务器上 git clone 私有仓库时,用账号密码会报 Authentication failed

原因: GitHub 从 2021 年 8 月起禁止用账号密码认证,必须用 SSH 密钥或 Personal Access Token。

解决方案:配置 SSH 密钥

# 服务器上生成密钥
ssh-keygen -t ed25519 -C "your@email.com"

# 查看公钥
cat ~/.ssh/id_ed25519.pub

复制输出内容,去 GitHub Settings → SSH and GPG keys → New SSH key 添加。

# 测试连接
ssh -T git@github.com
# 看到 "Hi xxx! You've successfully authenticated" 即成功

# 用 SSH 协议克隆
git clone git@github.com:你的用户名/my-blog.git blog-source

主题迁移:PaperMod → hugo-book#

安装主题#

# 本地执行,删除旧主题
cd F:\ECS_PJS\my-blog
Remove-Item -Recurse -Force themes/PaperMod

# 用 submodule 安装 hugo-book
git submodule add https://github.com/alex-shpak/hugo-book.git themes/hugo-book

问题一:主题文件夹无法上传到 GitHub#

现象: themes/PaperMod 推到 GitHub 后是空文件夹,服务器 clone 后主题不存在。

原因: themes/PaperMod 里有 .git 文件夹,Git 把它识别为嵌套仓库(submodule),不追踪里面的文件。

# 错误提示
warning: adding embedded git repository: themes/PaperMod

解决方案:

# 删除主题内的 .git
Remove-Item -Recurse -Force themes/PaperMod/.git

# 从 Git 索引中移除缓存
git rm -r --cached themes/PaperMod

# 重新添加并推送
git add themes/PaperMod/
git commit -m "add: PaperMod theme"
git push

使用 hugo-book 时直接用 git submodule add 安装,就不会有这个问题,submodule 是 Hugo 主题的推荐管理方式。

问题二:服务器构建报 SCSS 编译错误#

报错信息:

TOCSS: failed to transform "book.scss" (text/x-scss).
Check your Hugo installation; you need the extended version to build SCSS/SASS.

原因: hugo-book 主题使用 SCSS,需要 Hugo extended 版本编译。但 CentOS 7 上的 extended 版本有 CGO 兼容性问题(会触发 pthread_create failed),只能用普通版本。

解决方案:改为本地构建,上传静态文件。

服务器不再负责构建,只负责提供静态文件:

本地(extended 版本)→ hugo 构建 → public/
scp 上传 public/* 到服务器 /var/www/blog/
Nginx 对外提供访问

问题三:栏目页面空白#

现象: 点击首页的 /portfolio//posts/ 等链接,打开是空白页。

原因: hugo-book 默认只渲染 content/docs/ 目录。其他目录需要:

  1. hugo.toml 里设置 BookSection = "*"
  2. 每个文件夹有 _index.md

解决方案:

hugo.toml 加上:

[params]
  BookSection = "*"

每个栏目文件夹创建 _index.md(以 portfolio 为例):

---
title: "📁 作品集"
weight: 1
bookFlatSection: true
---
我做过什么 — 核心项目与成果展示

问题四:栏目页没有文章列表#

现象: /portfolio/ 能打开,但只显示 _index.md 的内容,没有文章列表。

原因: hugo-book 是文档树导航风格,本身不支持博客列表页。

解决方案: 自定义 layouts/_default/list.html

{{ define "main" }}
<div class="book-page">
  <h1>{{ .Title }}</h1>

  {{ with .Content }}
    <div class="book-content">{{ . }}</div>
  {{ end }}

  <div class="article-list">
    {{ range .Pages.ByDate.Reverse }}
    <a href="{{ .Permalink }}" class="article-item">
      <div class="article-title">{{ .Title }}</div>
      <div class="article-meta">
        <span class="article-date">{{ .Date.Format "2006-01-02" }}</span>
        {{ with .Params.tags }}
          {{ range . }}
          <span class="article-tag">{{ . }}</span>
          {{ end }}
        {{ end }}
      </div>
    </a>
    {{ end }}
  </div>
</div>
{{ end }}

最终部署工作流#

目录说明#

服务器上有两个目录:

目录 用途
/var/www/blog-source/ 博客源码(md 文件、主题、配置)
/var/www/blog/ 构建后的静态文件(Nginx 读这里)

日常更新流程#

本地操作:

# 1. 写完文章,本地预览
cd F:\ECS_PJS\my-blog
hugo server    # 访问 http://localhost:1313 确认效果

# 2. 构建静态文件
hugo           # 生成 public/ 目录

# 3. 上传到服务器
scp -r public/* root@你的服务器IP:/var/www/blog/

如果同时更新了源码(想保持 blog-source 同步):

# 本地推送到 GitHub
git add .
git commit -m "新增:文章标题"
git push

# 服务器拉取源码(可选,不影响访问)
ssh root@你的IP
cd /var/www/blog-source
git pull origin main

一键上传脚本(本地)#

在博客根目录创建 deploy.ps1(Windows PowerShell):

# deploy.ps1
param(
    [string]$SERVER = "root@你的服务器IP"
)

Write-Host "=== 构建博客 ===" -ForegroundColor Cyan
hugo --cleanDestinationDir

Write-Host "=== 上传到服务器 ===" -ForegroundColor Cyan
scp -r public/* "${SERVER}:/var/www/blog/"

Write-Host "=== 部署完成!===" -ForegroundColor Green
Write-Host "访问 https://misaku.site 查看效果"

以后执行:

.\deploy.ps1

即可一键构建并上传。


关键配置备忘#

hugo.toml 核心参数#

baseURL = "https://misaku.site/"
theme = "hugo-book"

[params]
  BookSection = "*"      # 渲染所有 section 到侧边菜单
  BookToC = true         # 显示文章内目录
  BookTheme = "auto"     # 跟随系统深色/浅色
  BookSearch = true      # 开启搜索
  BookCustomCSS = "css/custom.css"  # 自定义样式

Nginx 配置(已有,备忘)#

server {
    listen 443 ssl;
    server_name misaku.site;

    ssl_certificate /etc/nginx/ssl/misaku.site.pem;
    ssl_certificate_key /etc/nginx/ssl/misaku.site.key;

    root /var/www/blog;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

问题汇总#

问题 根因 解决方案
GitHub 认证失败 不再支持密码认证 配置 SSH 密钥
主题文件夹上传为空 嵌套 .git 被识别为 submodule 删除主题内 .git,重新 add
服务器构建 SCSS 报错 CentOS 7 不兼容 extended 版本 改为本地构建,SCP 上传
栏目页空白 Book 主题默认只渲染 docs/ BookSection = "*" + 各栏目加 _index.md
栏目页无文章列表 Book 主题无博客列表功能 自定义 layouts/_default/list.html

上一篇:Supervisor 进程管理与应用启动