博客程序由 Wordpress 迁移至 Ghost

为了配合路由器科学上网,于是买了个 VPS 来自行搭建 V.P.N,再加上最近在折腾 Node.js,于是打算把博客从 Wordpress 迁移至 Ghost

Ghost 为 Wordpress 的前员工开发,基于 Node.js,非常轻快,而且后台为 Markdown 编辑器,再加上数据库是 SQLite(也可使用 MySQL),深得我心,下面简单记录一下迁移过程。

首先选择一个合适的 VPS,之后安装 Ghost

迁移评论

评论迁移至 Disqus非常简单,Wordpress 安装 Disqus 插件后简单几步就能完成。

迁移文章图片

Ghost 的迁移指引上给出了一个用来存放图片的网站 Cloudinary,同样有 Wordpress 插件,安装后即可把所有图片转移至 cloudinary 并替换文章中的图片 url 为 cloudinary 的 url。

迁移文章

等上面的数据全部迁移完了就可以迁移文章了。

正常的情况下,Wordpress 安装 Ghost 插件,在 Wordpress 中导出 JSON 格式的数据,再进入 Ghost 后台导入即可。

这一步我遇到了一个问题,就是导入后的文章乱码了,而标题没乱码!

搜索一圈没找到解决方案,于是给 Ghost 提了个 issue,得到回复说可能是 Wordpress 的 MySQL 数据库的编码问题,于是我在本机搭建了一个 Wordpress(详见 Mac下如何安装Wordpress?),将线上 Wordpress 的数据导入到本地搭建的 Wordpress 中(使用 Wordpress 内置的导入、导出工具即可),再将本地 Wordpress 的数据导出,再上传至 Ghost 后台,乱码问题搞定!

另外,导入的文章可能会出现一些错误,尤其是包含代码的,需要手动修复。

URL 重定向

Wordpress 导入 Ghost 之后,文章的 URL 规则发生了变化,为了更加无缝的体验,需要对 URL 进行 301 重定向。

中文标题下,Ghost 导入进来的文章 URL 为一长串字符,重定向规则变得没有规律,我想要的是方便重定向的,比如老的 URL 是 http://www.99css.com/archives/542/,新的为 http://www.99css.com/542/。念在只有 100 多篇文章,手动修改未尝不可:

  • 将 Ghost 的数据库 content/data/ghost.db 下载到本地
  • 用 SQLite 编辑工具(比如 SQLite professional、Firefox 扩展 SQLite Manager)打开
  • 在本地的 phpMyAdmin 中执行如下 SQL 语句筛选出文章标题及 ID SELECT post_title, guid FROM `wp_posts` WHERE post_status = 'publish' ORDER BY post_date DESC
  • 修改数据库 ghost.db 中 posts 表中的数据,将 slug 字段修改为上面查询到的对应文章 ID 即可

Tag 的 URL 也可以顺手修改一下,打开 tags 表,修改 slug 字段。

修改完成之后,ghost.db 上传覆盖 content/data/ghost.db

接下来配置一下 nginx,新建一个 conf 文件,丢到 nginx 配置目录即可

server {  
    listen 80;
    server_name www.99css.com;
    location / {
        proxy_pass http://127.0.0.1:2368;
        if ($args ~* "p=[0-9]*") {
            rewrite ^ /$arg_p? last;
        }
        if ($arg_tag) {
            rewrite ^ /tag/$arg_tag? last;
        }
        if ($arg_replytocom) {
            rewrite ^(.*) $1? redirect;
        }
    }
    location /archives {
        rewrite ^/archives/([0-9-]+)$ /$1 permanent;
        rewrite ^/archives/tag/(.*)$ /tag/$1 permanent;
        rewrite ^/archives/category/(.*)$ / permanent;
        rewrite ^/archives/date/(.*)$ / permanent;
    }
    location /category {
        rewrite ^/category/(.*)$ / permanent;
    }
    location /demo {
        alias /var/www/ghost/content/demo;
        access_log off;
        expires max;
    }
    location /static {
        alias /var/www/ghost/content/static;
        access_log off;
        expires max;
    }
}
server {  
    server_name 99css.com;
    rewrite ^(.*) http://www.99css.com permanent;
}

后面一段规则是将不带 www 的域名(99css.com)跳转到带 www 的域名(http://www.99css.com)

合并评论

进入 Disqus 的后台管理,点击 Tools 标签,找到 Redirect Crawler (Advanced),点击 Start Crawler,即可把重定向 URL 前后的文章评论合并。不知为何,这一步一直没有成功,最后采取的是手动修改 URL map

将 Disqus 集成到 Ghost 中

注:可以使用更加方便的 Code Injection 功能来添加 Disqus,详见 http://www.99css.com/code-injection-of-ghost/

用编辑器打开主题中的 post.hbs 文件,将下面代码段拷贝至 </article> 前(记得修改一下 disqus_shortname 变量),重启即可生效

<div id="disqus_thread"></div>  
<script type="text/javascript">  
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'disqus_shortname'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>  
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>  
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>  

使用 PM2 守护 Ghost 进程

安装 PM2,以 Ubuntu 为例

npm install pm2@latest -g  

生成 PM2 自启动脚本

pm2 startup ubuntu  

以生产模式启动 Ghost

NODE_ENV=production pm2 start index.js --name ghost  

保存

pm2 save  

以后这样就可以重启了

pm2 restart index.js  

设置完成之后 VPS 重启或者 Ghost 崩溃都能自动重新运行了