本站正式从之前基于 Wordpress 搭建的 https://blog.donggan.info 搬到基于 Hugo 搭建的 https://donggan.me, 也就是现在的这里。

博客搬家就像真实世界搬家一样折腾。不过当你下定决心彻底搬完之后,看着满意的新家,顿时觉得其中的折腾和付出还是值得的。

Photo by Erda Estremera

生活本不易,何苦再折腾

谈一点人生经验

我用过的博客平台不算多,但是各种类型基本也都接触过一些。深度搭过网站的有下面这些:

  • Wordpress

    老牌博客平台了,基于 PHP 的开源内容管理系统。我用它搭过个人博客包括本站的前身 (https://blog.donggan.info ,没写几篇就断更了)、一个美食博客(https://pepperpi.com ,也是断更了),还有几个企业门户网站。 Wordpress 优点呢就是主题多,插件多,基本上你能想到的想不到的都可以用插件解决。缺点呢就是很臃肿,比较重。基本上做个像样的企业门户网站,没个十几个插件都不好意思叫门户网站。另外,Wordpress 是 PHP + MySQL 的部署方式,也就是说是个动态网站,在部署和运维上还是需要花一些精力和成本的。

  • Ghost

    一个基于 NodeJS 的有设计感的开源内容管理系统。我用它搭过微服务部落 (http://blog.idevfun.io ,在写本文的时候发现因为欠费一个月销毁了,文章都没了。平复了几天心情后决定改天专门写一下这段血泪史……),还有 AKI 优选 (https://akischoice.com/ ,哭了,和 blog.idevfun.io 放一个主机上了,也被销毁了)。Ghost 相对 Wordpress 来说交互更简约、现代一些,它的后台内容管理系统是个基于 EmberJS 开发的单页式应用,体验还是可以的。缺点是插件较少,内容编辑工具对中文支持不太友好,需要从别地地方编辑好再粘贴到里面。另外,它也是个动态网站,不过部署起来较为方便,自带的命令行工具基本可以交互式地很方便就搭起一个网站。

  • 其他静态网站生成工具

    用过几个静态网站生成工具,主要使用场景是公司内项目主页和开源项目的主页。包括:

    • Docusaurus - Facebook 开源的一个文档网站生成工具。使用 ReactJS 作为模版和页面的开发框架。唯一缺点是名字太长不太好记。另外,虽然使用 React,但是只是渲染时的引擎,并不是运行在前端页面的,也就是说最终还是生成一个静态的网站,如果想自己加一些页面动态的逻辑,比如通过 JS 调用接口渲染数据等功能,还是需要使用普通 JS 编写。不过,听闻 Docusaurus 的 v2 的提案已经在讨论中,也许第二个大版本就会像 VuePress 支持在前端渲染 Vue 代码一样支持在 Docusaurus 前端渲染 React 代码了。
    • Hugo - 基于 Go 的一个静态网站生成工具。我在开源项目 gRPC Mate 主页 (https://grpcmate.io/) 使用了 Hugo,参考的是 gRPC 项目的官网。当然,本站也是使用 Hugo 生成的,目前使用体验还不错。相比较于 Docusaurus 来说,Hugo 因为使用 Go 做渲染和编译的工具,在本地安装比较简单,只需要安装相应平台的命令行工具即可。而 Docusaurus 就得用 npm 或者 yarn 下载一堆依赖来安装了。

    除了这两个静态网站生成工具,我还接触过 Jekyll, Hexo 等静态网站生成工具,都是大同小异,使用 Markdown 文件管理内容,可以安装和定制不同的主题等,只是工具本身的语言不同。

静态网站相比动态网站的第一个优势,就是部署简单,节省资源。

你可以在本地编译生成最终网站的静态文件,然后就可以打包部署到目标机器上,目标机器只需要运行一个 NGINX 即可,不需要额外搭建配置一个数据库。甚至,你连目标主机都不需要有,只需要通过 Github Pages, Netlify, Heroku 等服务就可以很方便地免费承载你的静态网站。客观地说,对于技术小白,可能动态网站第一次搭建会很折腾,但以后每次更新文章比较方便。但对于懂一点技术稍微有点 git 操作知识的人来讲,只要搭建起静态网站更新的流程,不管是首次搭建还是更新都是比较方便的。另外,因为最多只需要运行一个 NGINX,不需要 MySQL,你可能搭建动态网站需要一两个 VPS 实例,但是用静态网站可能这个钱就省了。

静态网站的第二个优势,访问速度快,性能更好。

纯静态页面没有和数据库的交互,本身就更快。而且因为是静态页面,你可以使用 CDN 来做图片、JS、CSS 甚至 HTML 页面的缓存。对于终端用户来说,是可以根据接入点就近访问的。

静态网站的第三个优势,不用担心数据备份的问题。

动态网站,比如前面的 Wordpress 和 Ghost ,除了文章的内容和一些配置信息是保存在数据库中,如果不特殊设置图片上传到云端,默认图片是保存在主机文件系统上的。也就是说,备份整个网站的数据,除了要定期 dump 一份数据库,还要把网站目录的静态文件也保存下来。也可以定期把整个主机打镜像快照保存下来,但要迁移一个主机总归还是很麻烦的。

谈起数据备份,我真的是有血泪史,上面提到的两个用 Ghost 搭建的网站,因为 VPS 提供商账号欠费,直接把我的主机销毁了,目前还在找技术支持看能不能把我两个网站找回来。所以如果不想使用动态网站还像我一样直接把网站的数据弄丢,那就一定要定期经常备份数据。

不过,如果使用的是静态网站,就不太用担心数据备份的问题了。因为通常来说,网站的内容文件一般都是由 Git 管理的,可以放在 GitHub 上。这些内容数据不仅可以随时放在本地或者远端,所有更改的历史记录也会保存下来。这样一来就完全不用担心数据会丢了——你可以 GitHub 放一份,GitLab 放一份,自己电脑上还有一份。

为什么一定要折腾

就本站来说,我为什么要从 Wordpress 迁移到 Hugo 呢?从现实角度,每月要花15美元维护一个 AWS 最小的实例,上面运行两个 WordPress 外加一个 MySQL,花钱不算多,但是其实不是很省心。其中遇到的一个问题就是每隔一段时间就内存满然后 MySQL 进程被系统杀掉。可能因为我对 PHP 还是不很熟悉,也懒得去看怎么调优参数让两个网站外加 MySQL 花尽量少的内存。我仍然是每次重启 php-fpm 来解决,可以一下子就释放很多内存,然后再重启 mysql。内存不够用的问题理论上可以通过扩容实例来解决,不过我实在是太懒了,可能扩容还要迁移主机,想想就头疼。其实,如果迁移到其他 VPS 厂商,同样规格的实例可以控制到5美元每月。但是想到反正都要迁移,还不如干脆直接迁移到 Hugo 算了,反正总共也没几篇文章。

一方面因为上面说的总是需要手动维护,另一方面 Wordpress 编辑器的使用体验其实没有那么好,连 Markdown 支持都不怎么样。这也直接影响到我写文章的产出,几年才写了两三篇(???WP:这个锅我不背)。印象笔记中 buffer 了几十上百篇可以用来写文章的素材,但是却懒得发表出来。如果迁移到新的平台,也希望能经常写一写。

这才有了本站,和本文。

那么,我为什么要改域名呢?之前的域名 donggan.info 是早些年买的,当时申请了 .info 而没有用 .me 这种更适合个人博客的顶级域名。我现在也不是很理解当时是怎么想的,大概是想 .info 除了发表个人博客,还可以做成一个资讯或是什么类型的技术博客,现在想想就是想太多。所以这次趁着搬家干脆重新申请了新域名 donggan.me,专门用来做个人博客。因为原来的博客由于上面说的数据库老挂的原因经常数天不能访问,所以也没什么 SEO,换了就换了,当成从零开始,也很好。有那么两三篇早些年写的不成熟的文章,也可以一并迁了过来。

开山凿石,添砖加瓦,终于喜迎乔迁

打定了主意要搬家,那就找个独居的周末开始动手吧,这样的时机对我来说可能一年也就只有那么一两次。

选平台

首先我肯定是要自建,所以要找一个静态网站生成的工具,这里我还是继续选择 Hugo,原因上面有详细说明。这里没怎么花时间,Mac 上运行 brew install hugo 即可在本地安装 Hugo,可以体验一下。

选主题

选个合适的主题很重要,这里我花了些时间。Hugo 官方有个主题的列表, 但要选一个功能强大或者热门的不是很方便。所以我搜了几个主题推荐的网站,找了下排名靠前的几个主题,最终选定了 Even,简洁大方,比较符合我的口味。Even 应该是从 Hexo 的一个主题移植过来的,作者是个国人,想必对中文支持应该会好一些。另外排名很靠前的另一个主题 Academic 看起来也不错,不过似乎略微复杂一些,本站没有采用,打算后面其他的站点试用一下。

内容迁移

因为之前博客上发表的文章很少,所以迁移比较简单,连导出工具都不用,可以用复制粘贴大法手动搞定。这样也能确保图片之类的相对路径引用是没问题的。

多语言

之前的博客文章几篇都是先有英文,再翻译成中文发出来的,使用了 WordPress 的多语言支持插件。迁移后,由于 Hugo 和我选用的这个主题对于文章内容多语言和站点本身 i18n 都有原生支持,对于中英文都有的文章就方便多了。主题的菜单栏对多语言的支持需要略微调整一下,不过最终的效果还是不错的。

部署

本站使用 GitHub Pages 搭建,也就是说不需要额外花每个月的 VPS 机器成本,也省了每次更新要自己部署到机器上的麻烦。

装修

对于新家来说,一套完整的自动化流程将会减少发布的难度,进一步降低写作的阻碍和成本。

目前的最终效果,简要描述就是通过 git 提交一篇文章,运行一个部署脚本构建静态文件并提交到 GitHub。以下以本博客为例,介绍一下搭建的大概流程:

  1. 创建一个名为 donggan.me 的仓库,即博客主仓库,存放 markdown 源文件和模版文件等静态源文件。这个仓库可以是私有仓库,也可以叫其他任何名字。这个仓库将是存放博客所有数据的地方。为了避免搜索引擎爬取 GitHub 源文件而将搜索结果排在本站的前面,我暂时把这个仓库设成了私有仓库。

  2. Fork 了主题 Even 的仓库到自己 GitHub 名下。Hugo 本身对主题的扩展机制比较灵活,需要改主题的某个文件其实可以在项目目录里直接覆盖,渲染模版的时候优先级顺序会比主题目录的高,不过我还是 fork 了我所选主题的项目到自己名下。这样不是为了定制自己的版本,而是为了可以控制什么时候集成上游的更新。

  3. 添加 fork 项目成为自己博客主仓库的一个 submodule。这样在本地可以在一个视图中操作主仓库工程和主题工程。将 submodule 放在 themes 目录下。

    1
    2
    
    $ git submodule add git@github.com:gdong42/hugo-theme-even.git themes/even
    $ git submodule update --init --recursive
  4. 我们可以在项目里按照 Hugo 的方式添加一些 Markdown 文件了,运行 hugo server -D 后可以通过浏览器预览包括草稿的所有文章渲染后的样子。满意后就可以随时提交内容并推到 GitHub 上保存。记得提交前删掉渲染的目标静态文件目录:rm -rf public

上面的步骤只是将源文件存放到 git 中。我们还需要将渲染后的静态页面也放到 GitHub 中,正式发布这些文章使大家都能访问到。步骤如下:

  1. 在自己 GitHub 名下创建一个 gdong42.github.io 仓库,命名符合 GitHub Pages 的规则,因此这个仓库中存放的静态文件会呈现在地址 gdong42.github.io 这个地址中。
  2. 回到我们的博客主仓库 donggan.me ,添加上述仓库为 submodule:

    1
    
    $ git submodule add -b master git@github.com:gdong42/gdong42.github.io.git public

    现在,生成的目录 public 就会指向我们刚创建的 gdong42.github.io 这个仓库。

  3. 在博客主仓库 donggan.me 根目录中添加文件 deploy.sh 并给文件添加可执行权限, 内容如下:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    #!/bin/sh
        
    # If a command fails then the deploy stops
    set -e
        
    printf "\033[0;32mDeploying updates to GitHub...\033[0m\n"
        
    # Build the project.
    hugo # if using a theme, replace with `hugo -t <YOURTHEME>`
        
    # Go To Public folder
    cd public
        
    # Add changes to git.
    git add .
        
    # Commit changes.
    msg="Rebuilding site $(date)"
    if [ -n "$*" ]; then
            msg="$*"
    fi
    git commit -m "$msg"
        
    # Push source and build repos.
    git push origin master

至此,整个就已经搭建完毕。日常更新文章的操作步骤会像这样:

  1. donggan.me 仓库中撰写添加文章
  2. 可以在本地运行 hugo server -D 实时预览效果,觉得完成且适合发表后,运行下面的命令一键发布:

    1
    
    $ . ./deploy.sh
  3. 发布确认没问题后,可以提交本地 donggan.me 仓库的改动并推送保存。

此时,你应该可以通过 https://gdong42.github.io/ 来访问上面部署后的网站。 那么下一部分,介绍下如何配置自定义域名。

挂牌、上线

首先在 gdong42.github.io 这个仓库的设置页面里,设置自定义域名为 donggan.me。然后在域名服务商处设置解析,GitHub Pages 支持使用 ALIAS 或 ANAME 的 DNS 解析类型,理论上可以直接指向 gdong42.github.io 这个域名即可。不过我是在 GoDaddy 注册的域名,似乎不支持这两种类型的记录,所以需要使用 A 记录,指向 GitHub 的几个 IP 即可。

设置好域名过一段时间后 GitHub 会自动为自定义域名申请 Let’s Encrypt 的 HTTPS 域名证书并部署好,所以证书我们也不用担心了。

听起来复杂,但其实整个过程还是很简单的,下面这张图可以简单总结一下。

How Everything Works Behind https://donggan.me/

搞定,一切完美,喝个咖啡放松一下吧。