用 Hugo + GitHub Actions 做个人博客:写完 Markdown 自动发布到云服务器
个人博客最烦的不是写,是每次写完还要登服务器、传文件、改权限。这套方案把中间环节全删掉:本地写完 Markdown,git push 一下,几分钟后线上就自动更新。整站是纯静态文件,一台 2 核 4G 的服务器放几十个博客都绠绠有余,内存占用不到 20MB。
一、为什么选静态站而不是 WordPress
WordPress 功能全,但要 PHP、要 MySQL、要定期打补丁,一个插件漏洞就可能被挂马。个人博客的需求本质上只有三件事:写文章、按时间排列、能被搜到。这三件事 Hugo 用纯静态 HTML 就解决了。
静态站的好处很直接:没有数据库可被注入,没有运行时要维护,访问量再大也只是发文件,被攻击面几乎为零。代价是没有后台评论和动态搜索,评论区可以接第三方的,搜索可以用前端方案,对个人博客够用。
二、Hugo 安装与目录结构
Hugo 是单二进制工具,装起来比 Node 那套轻得多:Windows 用 scoop install hugo 或直接下 exe,macOS 用 brew install hugo,Linux 用 apt install hugo 或下载 release 包。
hugo new site myblog 生成骸架,目录结构值得先认清:content/ 放文章,posts/ 下一篇一个 md;layouts/ 放模板覆盖,不写就用主题自带的;static/ 放图片附件,构建时原样复制;config.toml 或 hugo.toml 是全局配置;themes/ 放主题。
站点配置里有两个字段必须改对:baseURL 写线上真实域名,末尾带斜杠;timeZone 要和写作习惯一致,否则文章时间会差几个小时。
三、写一篇能发布的文章
执行 hugo new posts/hello-world.md 会按模板生成头部,front matter 典型长这样:标题、日期带时区偏移、draft 标为 false、tags 列表、summary 一句话摘要。
draft 忘记改 false 是最常见的文章不出现原因;date 写成未来时间,Hugo 默认也不会渲染。正文就是普通 Markdown,代码块用三个反引号包起来并写上语言名,语法高亮会自动接管。
四、本地预览
hugo server -D 起本地服务,默认监听 1313 端口,-D 表示连草稿一起渲染。改文件浏览器会自动刷新,不用重启。这一步在本地做完再推,比线上调试省事得多。
五、GitHub Actions 自动构建与发布
仓库根目录建 .github/workflows/deploy.yml,核心内容分四步:拉代码、装 Hugo、构建、用 rsync 推到服务器。
第一步 checkout 时必须带 submodules: true,主题用 submodule 引入的话没这一项构建出来的页面就没样式。第二步用 peaceiris/actions-hugo,把 hugo-version 设为 latest、extended 设为 true,部分主题需要 extended 版本。第三步 hugo --minify 生成压缩后的 public/。第四步走 rsync-deployments,参数 -avzr --delete 保证线上与产物完全一致。
主机、用户、私钥全部从仓库 Secrets 读取,不写进 yml 文件。
六、服务器侧准备
三件事:目录、权限、Nginx。
mkdir -p /var/www/myblog,属主给部署用户;rsync 的 remote_path 要和 workflow 里的路径完全一致,多一层少一层都会传到错地方。
Nginx 一个 server 块就够:监听 80,server_name 写博客域名,root 指向 /var/www/myblog,index 设 index.html。location / 用 try_files 降级到 404;再给 js、css、png、svg、woff2 这类静态资源加 30 天缓存。静态站不需要 proxy_pass,只负责发文件。HTML 不缓存、资源长缓存,这样改文章立即生效、老资源仍然命中缓存。
七、密钥与安全
Actions 里的私钥必须放仓库 Secrets,绝不能写进代码。生成专用密钥对,公钥追加到服务器 ~/.ssh/authorized_keys,部署前固定 known_hosts 指纹,避免首次连接手动确认。
更稳的做法是给部署单独建用户,只授权 /var/www/myblog 目录写权限,权限收到最小,万一密钥泄露影响面也有限。
八、几个踩过的坑
1. --delete 让线上目录和产物完全一致,本地误删文章后推上去,线上文件真就没了。建议重要文章另存备份,或仓库开分支保护。
2. rsync 第一次传输慢是正常的,之后只传变化的文件,几秒就完。
3. baseURL 写错,站内链接全指向 localhost,文章点进去 404。
4. 中文文件名在 URL 里会被转义成一长串,建议文章文件名用英文或拼音。
5. 服务器时区和文章 front matter 时区不一致,首页时间会乱序。
九、这条路的价值
写完就推,推完就上线,中间不需要记住任何服务器命令。文章全在 Git 里,历史版本、误删恢复、多设备写作都能覆盖。服务器只承担一件事:把 HTML 发出去。对个人博客和文档站而言,这是目前成本最低、维护最轻的做法。
- 点赞
- 收藏
- 关注作者
评论(0)