GHOST 搭建个人站点完整流程
Ghost 是一个类似于 WordPress 的一个新兴的内容管理系统。相比与 WordPress,Ghost 更加强调轻量与纯粹。本文主要介绍了作者从零开始完整搭建 Ghost 个人站点的全流程。

前言
环境要素
- 时间:2018 年 6 月 28 日;
- Ghost CLI 版本:1.8.1;
- Ghost 版本:1.24.6;
- VPS OS:Ubuntu 16.04;
背景
当前自己的生活有点过于封闭,为了在感兴趣的事情上深入研究、保持记录,并且能够帮助他人以及扩大自己在这些领域的社交圈,同时也为了能够通过搭建运行 Ghost 这样的 Node.js 应用从中学习 Node.js,因此想再次使用 Ghost 搭建一个个人站点。
说是再次,是因为之前搭建过,但是只是技术上的尝试。这次的重点主要放在了内容的记录和分享,因此如何能够保持站点的延续也是一个很重要的努力方向。
流程概述
- 选购 VPS 主机;
- 配置系统之安全篇;
- 配置系统之程序篇;
- 安装 Ghost;
- 绑定域名;
- 开启 https 和 http2;
- 网站加速;
- SEO;
- 增加评论功能;
- 备份;
- 其他;
流程详述
一开始每个环节我都是在网上单独搜索的,后来仔细看了 Ghost 官方文档以后才发现,基本流程都在上面。
选购 VPS 主机
市面上的 VPS 主机供应商多如牛毛,有大的如 AWS、Azure、Aliyun,小的如 Conoha、HostUS、Bandwagon 等等。我当时的选择要素有两个,支持支付宝付款和便宜,因此选择了 HostUS,KVM 的主机,一年才 150$。
如果大家也想买的话,建议先测试一下自己网络环境下主机的网速如何。因为我本身在这上面是吃了一点亏的,我之前有个主机是在洛杉矶的,速度不错,所以又买了一台,结果发现网段不一样,速度相差了一倍以上,还丢包。后来才转成了洛杉矶的。所以选购之前一定要测试一下网速如何,官方的测试页面在此。
配置主机
支付完成以后主机就创建好了,步骤很简单,购买的时候也没有让选择系统。创建好以后可以在控制台上选择 rebuild 功能,因为当前 Ghost-CLI 只支持 Ubuntu 16.04,所以就选择了该系统。
需要注意的是一定要记住 root 的密码,否则没法用了。为了方便以后免输密码直接登录,可以在 SSH Key 框里面输入自己机器的 SSH 公钥,具体内容在 ~/.ssh/id_rsa.pub
的文件里面。具体生成 SSH 密钥的方式在此就不赘述了。
配置系统之安全篇
系统重建完成以后,通过控制台登录主机,如果配置了 SSH Key 的话,可以不用输入密码直接登录成功。
$ ssh root@<remote_host>
保持系统更新
好歹也在大学的时候用过 Ubuntu,最基本的软件更新的命令还是知道的。
$ sudo apt-get update
$ sudo apt-get upgrade
运行完以上两个命令,软件就会更新最新了。软件源我个人没有换,如果觉得更新慢的童鞋可以自己找个合适的软件源。
减少 root 用户使用频率
和 Windows 不一样,Linux 尽量避免经常使用 root 账户做操作。
创建新用户
$ adduser <user>
和 CentOS 不一样,创建完以后以后直接提示输入密码,不需要再单独运行 passwd
命令输入密码。
需要注意的是,这里千万不要用 ghost 做用户名,因为后面安装 Ghost 的时候会自动创建一个 ghost 用户,所以如果在这里创建的话,后面就会导致安装失败。
禁止 root 用户远程登录
很多方式可以避免被密码泄露或者被暴力破解,比如禁止 root 用户远程登录,或者修改 ssh 的默认端口 22。
在禁止 root 远程登录之前,需要验证一下新创建的客户是否可以登录了,否则就把自己拦在主机外面了。
使用 root 权限打开 /etc/ssh/sshd_config
文件,找到 PermitRootLogin yes
,将 yes 修改成 no,然后保存。
最后重启一下 ssh 服务。
$ sudo service ssh restart
最后再用 root 用户远程登录验证一下是否已经生效。
使用 ssh 公钥登录主机
一开始在重建的时候可以在 HostUS 的官网上直接粘贴 ssh 公钥,但是因为创建了新的用户,需要为新的用户也做配置。
配置并不复杂,只需要将 ~/.ssh/id_rsa.pub
里面的公钥直接复制到主机的某个文件中即可,但是还是需要手工操作,有一个叫做 copy-ssh-id
的工具可以直接自动配置。
安装 copy-ssh-id
首先使用 brew 安装。
$ brew install copy-ssh-id
配置主机公钥
$ ssh-copy-id <username>@<remote_host>
等出现几句提示,然后按照提示输入密码以后,本机的 ssh 公钥就自动复制到了目标主机上,然后就可以连接一下试试了。
配置防火墙
首先允许 ssh 协议通过,否则会被自己关在门外,我就犯了这种低级错误。
$ sudo ufw allow ssh
然后再启用防火墙。
$ sudo ufw enable
关于 Ubuntu 16.04 防火墙 ufw 的说明可以自己在网上搜索一下。
配置系统之程序篇
安装 Node.js
先配置安装源。本来当前最新版本是 10,但是 Ghost-CLI 要求安装 6。
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash
然后直接安装。
$ sudo apt-get install -y nodejs
安装 MySQL
非常简单,直接安装。
$ sudo apt-get install mysql-server
安装时会提示设置 MySQL root 用户的密码,必须要设置,否则 Ghost 可能会配置不正确。
安装 Nginx
直接安装。
$ sudo apt-get install nginx
安装完成后需要在设置一下防火墙,允许 Nginx 通过防火墙。
$ sudo ufw allow 'Nginx Full'
安装 Ghost
安装 Ghost-CLI
通过 npm 全局安装 ghost-cli。
$ sudo npm i -g [email protected]
创建一个新的文件夹
$ sudo mkdir -p /var/www/ghost
要求最好是在这里创建,如果在用户下面的文件夹创建的话,会因为权限导致安装失败。
然后修改文件夹的所有者。
$ sudo chown <user>:<user> /var/www/ghost
<user>
修改成安装过程中所要使用的用户名。
然后再设置一下文件夹的权限。
$ sudo chmod 775 /var/www/ghost
然后进入到当前创建的文件夹中,就准备安装了。
$ cd /var/www/ghost
安装 Ghost
$ ghost install
然后根据提示,输入相关信息。
绑定域名
购买域名
可以从很多域名服务商那里购买域名,我是在 GoDaddy 上面购买的,如果在国内的域名服务商购买还要备案,很麻烦。
配置 Nginx
我一开始是在 /etc/nginx/conf.d
文件夹下面新建一个 <domain-name>.conf
的文件,<domain-name>
修改为自己购买的域名,然后编辑内容。
后来发现 Ghost-CLI 本身就支持生成 Nginx 配置文件的功能,因为一开始在设置域名的时候没有填写,所以就没有自动生成。但是 Ghost-CLI 支持在自动安装并且运行以后,再单独设置任意一项。
$ ghost setup nginx
该命令在 ./system/files/
下面创建了一个 Nginx 的配置文件,并在 /etc/nginx/sites-enabled/
下面创建了一个符号链接。
我之前都是在 /etc/nginx/conf.d
文件夹下面创建配置文件的,从来没有见过 /etc/nginx/sites-enabled
文件夹。本来以为是 Ghost 自己建的,后来上网查了一下,发现其实是 Nginx 默认就有的。这两个文件夹的主要区别是 /etc/nginx/sites-enabled
可以放置保存在别处的配置文件的符号链接,想清除配置的话,直接删除链接文件就行,而原文件还会保留。
开启 https 和 http2
开启 https
原本打算使用 Let's Encrypt 来手动配置 https 的,发现 Ghost-CLI 也集成了这个功能。
$ ghost setup ssl
同样使用 Let's Encrypt 的服务生成了证书,然后和上面一样,生成了对应的 Nginx 的配置文件。
因为 Let's Encrypt 证书的有效期是 90 天,一般情况下需要手动更新,或者设置计划任务定期更新。担心 Ghost-CLI 没有配置自动更新,于是查了一下 crontab,发现已经设置好了每 48 天自动更新的计划任务。
$ sudo crontab -l
开启 http2
本来想手动开启,后来看了一下 ssl 对应的 Nginx 配置文件,发现默认就已经开启了 http2。
网站加速
因为网站放在了国外的节点,访问速度于是成为了很重要的一个问题。
图片
相比文字,图片所占用的大小更大,传输时间也更长,因此当务之急是先优化图片的网络传输速度。方便的是,Ghost 把图片的存储功能单独出来一个模块,可以通过配置很方便的进行修改。
选择图床
我之前用过七牛的云服务,但是记得好像如果域名没有备案的话,使用起来比较麻烦,所以就不太想用,但是又不知道其他的图床。正好在 Ghost 的文档 - 使用定制存储模块 上看到了很多流行图床的适配器,有 AWS S3、七牛、又拍云、Azure 等等很多主流的图床的适配器。AWS S3 就算了,虽然最主流,但是在 GFW 的围剿之下基本没有速度,要是用了它就成了负优化了。我记得好像 Cloudinary 是一个比较主流和专业的图床,而且我以前还注册过,就想试试看这个的速度,然后登录上去找到示例图片的链接,ping 了一下,节点是在香港,延迟才 40ms,就决定用它了!
配置图床
官网文档上有两个关于 Cloudinary 的适配器,看更新日期 ghost-storage-cloudinary 的比较新一些,于是就采用了这个。
安装适配器
$ git clone https://github.com/eexit/ghost-storage-cloudinary.git
安装依赖
$ cd ghost-storage-cloudinary
$ npm install --production
安装完毕。然后就是配置 Cloudinary 的相关参数。
{
"storage": {
"active": "ghost-storage-cloudinary",
"ghost-storage-cloudinary": {
"useDatedFolder": false,
"auth": {
"cloud_name": "",
"api_key": "",
"api_secret": ""
},
"upload": {
"use_filename": true,
"unique_filename": false,
"overwrite": false,
"folder": "blog-images",
"tags": ["blog"]
},
"fetch": {
"quality": "auto",
"secure": false,
"cdn_subdomain": true
}
}
}
}
auth
属性里面填写 Cloudinary 账户的相关参数,一登录进 Cloudinary 的首页就能找到。其他的保持默认就可以。
SEO
关于 SEO 我是第一次接触,不过为了不让我的 Blog 再次成为个人备忘录😂,那么如何能够让搜索引擎收录就很关键了。
配置 Google Analytics
首先,为了以后能够看到 SEO 的效果,统计网站的 PV、UV、来源、客户地理位置等等数据就很有必要了。之前简单使用过 Google Analytics,现在还是先用起来吧。
首先用 Google 账号登录 Google Analytics 官网。然后创建一个新的媒体资源,按照要求填写一下网站信息,最后给出了一段类似于下面的 js 跟踪代码。
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-89036***-*"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-89036***-*');
</script>
复制生成的这段代码,登录 Ghost 后台,点击 Code injection,然后粘贴到 Blog Header 里面。然后再刷新一下首页,在 Google Analytics 里面应该就可以看到实时统计数据了。
备份
备份是关于一个站点延续性的很重要的一个问题。之前都是试验性质的部署,数据的保存和备份也就没有当回事,不过既然这次要下定决心好好写一些有价值的内容,备份的事情就不得不考虑,不得不重视。
不过因为目前站点刚建好,主要经理还要放在建设上。备份暂时先放一放,后期肯定会做处理并在此更新操作方式。
数据备份
备份中最重要的就是数据备份,什么都可以丢,数据不能丢。
配置备份
除了数据,想要快速恢复站点的话诸如主题、网站布局、背景什么的相关配置也需要好好备份。
其他
解决 sudo: unable to resolve host hostname
错误
每次使用 sudo
执行命令的时候,都会提示 sudo: unable to resolve host hostname
的错误,虽然并不影响什么,但是老看到报错,心里还是有些不安的。使用管理员权限修改文件 /etc/hosts
。添加以下内容。
127.0.0.1 <hostname>
<hostname>
是你自己的主机名字。