使用Docker搭建Ghost博客
对于想搭建自己博客的人来说,可选择的平台有很多,比如功能强大的WordPress、可运行在GitHub Pages上的静态博客平台Hexo和jekyll,以及本文介绍的博客平台Ghost。各平台各有优劣,本文不作赘述,重点介绍如何自己搭建一个可用的Ghost博客。
总体来说可通过两个docker run命令,分别运行Ghost博客和Nginx服务器即可,但运行前需要进行相关的配置。
1. 前期准备
搭建该平台需要准备如下的内容:
- 一个公网可访问的服务器,如可使用阿里云服务器。服务器建议安装64位的Linux系统,并安装docker。
- 一个域名,也可不使用域名,直接通过IP地址访问。本文以本博客使用的域名blog.datarepo.cn为例。
2. 配置并运行Ghost博客
使用Docker安装Ghost可以省掉配置环境的繁琐过程。但需要将配置信息、主题及博客内容存储在本地,以防止Docker运行停止造成的数据丢失。
下面是Ghost中存放这些信息的路径:
- 配置文件:/var/lib/ghost/config.production.json和/var/lib/ghost/config.development.json
- 主题:/var/lib/ghost/content/themes/
- 博客内容:/var/lib/ghost/content/
配置修改
Ghost的官方容器镜像中有默认的配置文件,需要对其进行修改,主要是“url”和“mail”两个字段。配置修改方式为两种,一种是在容器中修改,然后重新打包为新的镜像;另一种为在本地创建文件,然后挂载到容器中,以替换容器中的文件。本文选用第二种方法。
本地创建配置文件:config.production.json和config.development.json
# touch config.production.json
在config.production.json文件中添加如下内容,其中邮箱以163邮箱为例。也可直接下载config.production.json,并对相应的字段进行修改:
{
"url": "yoururl",
"server": {
"port": 2368,
"host": "0.0.0.0"
},
"database": {
"client": "sqlite3",
"connection": {
"filename": "/var/lib/ghost/content/data/ghost.db"
}
},
"mail": {
"transport": "SMTP",
"from": "youremail",
"options": {
"host": "smtp.163.com",
"secureConnection": true,
"port": 465,
"auth": {
"user": "youremail",
"pass": "yourpassword"
}
}
},
"logging": {
"transports": [
"file",
"stdout"
]
},
"process": "systemd",
"paths": {
"contentPath": "/var/lib/ghost/content"
}
}
然后复制config.production.json文件:
# cp config.production.json config.development.json
在Ghost容器中,config.development.json为指向config.production.json的链接文件,理论上只需要修改config.production.json文件,但如果本地挂载该文件后,config.development.json文件的链接会发生错误,造成无法启动。
使用Gitalk作为评论组件
由于国内的多说已经关闭,国外Disqus访问不稳定,本文选用Gitalk作为评论组件。Gitalk是基于Github issue和Preact实现的开源评论组件。实现效果见本博客最下方,或Gitalk的Demo。
为了添加评论组件,首先下载Ghost博客的默认主题Casper:
# mkdir content/themes/
# cd content/themes/
# git clone https://github.com/TryGhost/Casper.git
添加评论组件需要创建Github Application,并修改casper/post.hbs文件,配置方法详见Gitalk项目主页教程。
修改后的post.hbs可参考文件post.hbs中的Gitalk comment component一段,并根据官方教程修改其中的字段。
使用Gitalk需要有github账号,并且在一篇文章发表之后,需要点开文章并初始化评论,其他人才可以使用。
解决Gitalk出现validation error错误问题
需要注意的是,在Gitalk的配置中,id 字段需要格外注意,官方推荐的写法为location.pathname ,确保每一个文章都有不同的id 值。该字段用于在github中创建当前文章对应的issue,作为label添加到issue中,如果该字段设置为固定值,则只能创建一个issue,即所有文章共享相同的评论,显然这样是不可接受的。
同时,还需要注意的是,github在2018年2月份对issue中label的字符长度进行限制,如果id 字段过长(超过50个字符),则会创建issue失败,打开文章后会显示validation error,详见官方issue 。
为了解决该问题,可以在创建文章时修改URL,使其总长度小于50字符。或者采用官方issue中DOUBIGROUP给出的方法,将id字段设置为location.pathname的md5值,具体方法为,在casper/post.hbs添加:
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
并将id字段设置为:md5(location.pathname)。
中文摘要截取问题
当前Ghost博客对中文的支持较差,Casper主题在主页中使用post-card作为单个文章的展示,图片后的文字默认截取33个单词,但是不支持对中文字数的截取,通常会在图片后放大段的文字,展现效果不够美观。
本文参考Ghost 调教日志 - 解决中文摘要的截取问题对Ghost和Casper主题代码进行了修改。包括excerpt.js文件和post-card.hbs文件,修改后的文件见excerpt.js和post-card.hbs
。
其中excerpt.js文件为Ghost博客中的代码文件,通过本地文件挂载的形式对原文件进行覆盖,post-card.hbs为Casper博客中的文件,可直接替换掉本地文件casper/partials/post-card.hbs。
图片超出文档范围问题
默认情况下由于Ghost CSS样式文件问题,博客中引入的图片会超出文章的总宽度,本文参考Ghost 调教日志 - 解决图片超过文章宽度方法,在Ghost后台中插入代码解决。
在后台Settings/Code injection的Blog Header中加上如下内容:
<style type="text/css">
.post-full-content img {
max-width: none !important;
width: 100% !important;
}
</style>
文章第一段显示字体过大的问题
Casper主题中文章的第一段字体和正文相比较大,这样浏览起来不够美观,尤其是在手机端浏览时。参考上面的做法,使用代码注入的方式,覆盖原来的CSS文件中的代码片段。
在后台Settings/Code injection的Blog Header中的</style>前插入如下内容:
.post-template .kg-card-markdown > p:first-child {
font-size: 1em !important;
line-height: 1.5em;
运行Ghost镜像
切换到config.production.json文件所在的目录,执行docker run命令运行Ghost镜像,并挂载本地文件:
# docker run -d --name blog -p 2368:2368 \
-v `pwd`/content/:/var/lib/ghost/content/ \
-v `pwd`/content/themes/:/var/lib/ghost/content/themes/ \
-v `pwd`/config.production.json:/var/lib/ghost/config.production.json \
-v `pwd`/config.development.json:/var/lib/ghost/config.development.json \
-v `pwd`/excerpt.js:/var/lib/ghost/current/core/server/helpers/excerpt.js \
ghost:alpine
上述命令指定容器名为blog ,监听端口为默认的2368 ,并分别挂载了博客内容、主题、配置文件和更改的代码文件。
运行上述命令之后,即可通过http://yoururl:2368端口访问博客了。
如果使用阿里云服务器,还需要设置安全组策略,打开2368端口的访问。
3. 配置并运行Nginx服务器
常见的网站一般通过端口80来进行访问,实际上在上述命令中,可直接将端口映射改为-p 80:2368 。但是为了使服务器能够提供尽量多的Web服务,本文没有改变端口映射,而是使用Nginx进行反向代理,将访问二级域名blog.datarepo.cn 80端口的流量转发到Ghost服务端口。
本地创建Nginx配置文件default.conf :
# mkdir conf.d
# cd conf.d
# touch default.conf
添加如下内容:
server {
listen 80;
server_name yoururl;
location / {
proxy_pass http://yoururl:2368;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 100m;
}
}
切换到包含conf.d的文件夹下,运行Nginx服务:
# docker run -d —name webserver -p 80:80 \
-v `pwd`/conf.d/:/etc/nginx/conf.d/ \
nginx:alpine
运行后,即可通过http://yoururl访问博客了。
4. 博客使用
博客的管理页面为http://yoururl/ghost。
登录后可创建用户、通过前文配置的邮箱邀请用户、撰写并发布文章、对博客进行定制等。
需要注意的是,当前Ghost博客的编辑器在iPhone和iPad中无法输入中文,只能在其他地方输入中文后,粘贴到编辑器中,在电脑端不受影响。该问题是Ghost使用的开源markdown编辑器CodeMirror中的bug,详见issue。遗憾的是,这个问题在2015年就发现了,到现在依然没有解决。
Enjoy the fun of writing.