0. 服务器环境部署
node.js
先在Ubuntu x64上安装好Node.js,这里参见Digital Ocean官方给的一个在服务器上搭建ghost的教程,虽然不适用于新版的ghost,但是值得参考。
#做好准备工作
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
nginx
server {
listen 80;
server_name example.me;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
}
1. 使用ghost-cli安装ghost dev
安装ghost dev
ghost-cli(Command Line Interface)是官方在1.0版本后引入的一个便捷搭建ghost环境的工具,使用它安装ghost更加方便运行、停止和升级ghost,参考官方doc。
ghost分为production和development两种。这里采用dev的模式进行安装,其好处是其用本地的sqlite数据库,而不是mysql。dev模式下会生成配置文件config.development.json
,数据文件ghost-dev.db
;如果采用prod的方法安装,还需要配置mysql,比较麻烦。
环境是Ubuntu 16.04 x64,首先安装ghost-cli,然后使用ghost-cli安装ghost。
sudo npm install -g ghost-cli@latest --registry=http://registry.npm.taobao.org
sudo mkdir -p /var/www/ghost #递归建立文件夹
sudo chown -R [user]:[user] /var/www/ghost #添加权限
#如sudo chown ubuntu:root /var/www/ghost
cd /var/www/ghost
ghost install local #安装最新版ghost development
ghost install 1.25.5 --local #指定1.25.5版本进行development安装
ghost stop #注意到ghost已经自行启动,先关掉
mv config.development.json config.production.json #参考
以下几点需要注意:
- 代理: ghost-cli可能下载速度很慢,可以挂淘宝代理加速
- 权限问题:如果不添加权限,之后可能得
sudo ghost start/stop
- 切换production:由于是dev模式,默认情况下,只存在
config.development.json
。但如果development.json
和production.json
同时存在,ghost start时会首选production,检查ghost status
时也会显示为status为production;ghost run的作用是可以实时在bash中看输出。但是,在没有production.json
的情况下,运行ghost run
会报错,需要拷贝一份development.json
文件;综上,只需保留一份production.json
恢复content和theme
- 登录后台,注册帐户(流浪西,Jiaxi's Website),注意邮箱无需使用jiaxi域名的邮箱
- 进入Labs界面,选择
Delete all content
,然后import content
。如果备份的json文件过大 (如>2MB),可先压缩为zip文件,再次进行导入 - 恢复content目录内的image和theme目录
如果使用直接覆盖content
目录的方法迁移,ghost本身也可以正常工作,但是ghost-algolia会无法更新索引,因为其无法登录ghost内部的帐户,提示NoPermissionError
,这点在ghost run
时候可以检测出。
ghost-algolia进行bulk indexing (v1版本)
首先清空algolia官网内的index,然后进入v1版本的ghost目录
ghost stop
cd content/apps
git clone https://github.com/jsxzljx/ghost-algolia.git #恢复定制版的ghost-algolia
cd ghost-algolia
npm install #安装对应的包
cd /path/to/ghost
patch -p1 < ./content/apps/ghost-algolia/ghost_algolia_init.patch
ghost run
ghost不产出自适应大小图片
如果没有自适应大小的图片产出,原因是因为ghost node_modules没有安装sharp这个可选包,参见这里。
- sharp是optional node_modules,npm/ghost默认不会安装;
- 如果首先在个人目录下安装好sharp,再进行ghost update,那么会发现versions/{ver_num}/node_modules目录下有sharp包;
- 如果先ghost update,然后手动在新的versions/{ver_num}/node_modules里安装sharp,会破坏ghost程序导致无法启动。
所以采用如下方法来解决
npm install -g sharp@0.23.4 #确定下versions/{ver_num}/package.json中依赖的sharp版本,此版本是0.23.4
# 因为需要下载github的内容,所以有可能需要挂载代理
# 如果安装sharp时提示fatal error: vips/vips8: No such file or directory,那么则需要先安装minpass
# npm install -g minipass
# 参见 https://github.com/lovell/sharp/issues/1882
ghost update
# 然后手动check下ghost/versions/{ver_num}/node_modules是否有sharp包
有关npm install相关,参见这里:
npm install packageName #本地安装,安装到项目目录下,不在package.json中写入依赖
npm install packageName -g #全局安装,安装在Node安装目录下的node_modules下,如~/.npm-global
npm install packageName --save #安装到项目目录下,并在package.json文件的dependencies中写入依赖,简写为-S
npm install packageName --save-dev #安装到项目目录下,并在package.json文件的devDependencies中写入依赖,简写为-D
2. 本地评论系统isso
由于国外的Disqus经常无法访问,国内的畅言有广告,所以可以自己搭一个评论系统,isso是一个用python开发的,以sqlite做存储的开源评论系统,主要参考Github的教程。
使用源代码安装isso
由于isso的release非常慢,使用pip
的方法只能安装非常旧的版本,所以使用源码安装。
sudo pip install python python-dev virtualenv
sudo npm install -g bower requirejs uglify-js jade
wget https://github.com/posativ/isso/archive/0.11.1.zip
unzip 0.11.1.zip
#git clone https://github.com/posativ/isso.git
#这里使用的是release-0.11.1版本,其在我的魔改版js下能够work
cd isso
virtualenv . #在isso目录下安装py2
source ./bin/activate #进入虚拟环境
python setup.py develop #注意不得使用python setup.py install
make init #初始化js文件
make js #生成embed.min.js
deactivate #退出虚拟环境
python setup.py develop
的安装方法是在isso
目录里build文件,然后链接到python库里,而不是直接生成可执行文件放在库里,适合开发使用,参见这里,所以不能安装完后删掉isso
目录。注意不得使用python setup.py install
,否则之后会访问不到embed.min.js
。
server端配置
isso的配置文件有很多,具体参见GitHub的例子。
[general]
dbpath = /var/www/isso/comments.db
host = http://example.me/isso/
notify = smtp
reply-notifications = true
[server]
listen = http://127.0.0.1:1234/
[moderation]
enabled = false
[guard]
enabled = true
ratelimit = 5
reply-to-self = true
require-author = true
require-email = true
[smtp]
username = username@qq.com
password = password
host = smtp.qq.com
port = 465
security = ssl
to = targetname@example.com
from = "Isso Comment Notification"<username@qq.com>
timeout = 30
具体解释如下:
host
填一个可以ping得通的网站主页,否则会在isso run时warning. 以本地Django测试为例,host地址则为Django的127.0.0.1:8000
notify
和[smtp]
使用qq邮箱作为bot进行提醒(网易邮箱会报垃圾游戏,无法发送),如果不需要,删除notify
和[smtp]
的信息即可reply-notifications
给留言进行留言时可以收到Isso Comment Notification的邮件提醒listen
isso监听的端口,不同于host
moderation = false
留言不需要审核就可以展示出来[guard]
反垃圾邮件机制,reply-to-self = true
可以使得debug时候能自我回复,require-author
和require-email
设置为true时,需要在client端同样配置为true- 与官网教程不同,不要使用跨域名,如
comment.example.me
(和example.me
是两个域名),否则会发生最后无法提交评论的情况
此时可以运行isso,然后查看embed.min.js
是否存在。
/var/www/isso/bin/isso -c /var/www/isso/isso.conf run
curl http://127.0.0.1:1234/js/embed.min.js
nginx转发
与官网教程不同,为了避免跨域名,这里使用http://example.me/isso
子目录,所以nginx的配置如下。注意,与官网教程不同,第一行的listen 80
一定要有,否则会出现nginx无法转发成功的情况。此外,不妨把ghost nginx配置和isso nginx配置放在一个文件里。
server {
listen 80;
listen [::]:80;
server_name example.me;
location /isso {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Script-Name /isso;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8090;
}
}
上述配置完成,可以通过http://example.me/isso/js/embed.min.js
来测试,注意如果有CDN,先刷新预取一下。
client端配置
在网页中添加如下内容(最简版本),注意这里的data-isso
要和之前的host,nginx里的转发都一致. 全部版本参考GitHub。
<section id="isso-thread"></section>
<script data-isso="http://example.me/isso"
data-isso-css="false"
data-isso-lang="en"
data-isso-reply-to-self="true"
data-isso-require-author="true"
data-isso-require-email="true"
data-isso-max-comments-top="10"
data-isso-max-comments-nested="5"
data-isso-reveal-on-click="5"
data-isso-avatar="true"
data-isso-reply-notifications="true"
data-isso-avatar-bg="#F2F3F5"
data-isso-avatar-fg="#9abf88 #5698c4 #e279a3 #9163b6 ..."
data-isso-vote="false"
src="http://example.me/isso/js/embed.min.js"></script>
这里的data-isso-reply-to-self
,-to-author
,to-email
要和server端对应起来。
使用nohub挂载isso
nohup your_command > my_nohup.log 2>&1 &
#将日志输出在my_nohup.log文件中,并将stderr重定向至stdout
使用systemd启动isso
systemd即为system daemon,是linux下的一种init软件.首先编辑/lib/systemd/system/isso.service
文件
[Unit]
Description=lightweight Disqus alternative
[Service]
User=jiaxi
ExecStart=/home/USER/isso-0.11.1/bin/isso -c /home/USER/isso-0.11.1/isso.conf run
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload #每次修改isso.service后都需要重载
sudo systemctl restart isso.service
sudo systemctl status isso.service
使用supervisor启动isso (已废弃)
supervisor是用py2写的一个进程管理程序[1],首先安装supervisor。
之所以不用py3写,据说因为py3下其会产生崩溃的问题 ↩︎
deactivate #如果之前进入了虚拟环境,先退出
sudo pip install supervisor #用pip2安装supervisor
vim /var/www/isso/supervisor.conf #在isso目录下建立配置文件
mkdir -p /var/log/supervisor #生成日志目录
supervisord.conf
文件如下
[unix_http_server]
file=/var/log/supervisor/supervisor.sock ; the path to the socket file
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10 ; # of main logfile backups; 0 means none,default 10
loglevel=info ; log level; default info; others: debug,warn,trace
pidfile=/var/log/supervisor/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false ; start in foreground if true; default false
minfds=1024 ; min. avail startup file descriptors; default 1024
minprocs=200 ; min. avail process descriptors;default 200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/log/supervisor/supervisor.sock
[program:isso]
command = /var/www/isso/bin/isso -c /var/www/isso/isso.conf run
directory = /var/www/isso/
user = ubuntu
autostart = true
autorestart = true
stdout_logfile = /var/log/supervisor/isso.log
stderr_logfile = /var/log/supervisor/isso.err
environment = LANG="en_US.UTF-8"
然后注意,先运行一次supervisord
,不要直接就运行supervisorctl
,否则会报socket.error错误。
cd isso #supervisord会首先在当前目录寻找supervisord.conf
supervisord
supervisorctl stop isso #停止isso
supervisorctl start isso #启动isso
如果有其他错误,先删除/var/log/supervisor
里的所有文件,然后运行一次supervisord
. 更多命令参考官方文档。
搜索组件ghost-algolia
在ghost v2版本中,可在Integrations中配置后台触发逻辑,实现在进行更新/删除文章等操作后,自动将消息给第三方server,因此可以使用Node.js的netlify-cli搭建一个接收server,来实时建立索引。
npm install netlify-cli -g #安装netlify-cli
git clone https://github.com/jsxzljx/ghost-algolia-online.git
cd ghost-algolia-online
npm install #安装package.json中指定的dependencies
vim src/functions/update-post.js #修改algolia设置
#注意algolia有两个api key,这里填有写权限的那个
npm run serve > algolia.log 2>&1 & #后台执行
这里npm run serve
实际就是执行package.json中的scripts中的serve命令,即
netlify-lambda serve --config ./webpack.functions.js src/functions
其中
--config ./webpack.functions.js
好像和环境变量有关,可以删掉的- 每次执行
netlify-lambda serve
命令,其会把src/functions
进行编译,生成一个大的js文件,放到netlify.toml中指定的functions目录并执行,原理参考官方doc
algolia触发逻辑
保存/发布/不发布/删除会触发的逻辑:
- 新post只编辑不发布:
Post updated
- 新post首次发布:
Post published
和Post updated
- 编辑保存已发布的post:
Published post updated
和Post updated
- 发布的post改为不发布状态:
Post unpublished
和Post updated
- 不发布的post改为发布状态:
Post published
和Post updated
- 删除发布状态的post:
Post deleted
和Post unpublished
- 删除不发布状态的post:
Post deleted
因此,最后我们需要的触发逻辑只有Published post updated
,Post published
和Post unpublished
。
algolia js client调试记录
可以自己起一个调试环境,使用algoliasearch-client-javascript进行读写调试。
在调试的过程中,发现index的deleteBy({filters: "..."})
方法不work,后来谷歌搜到这篇Q&A,才发现要到algolia网页后台的Indices - Configuration - Filtering and Faceting > Facets中,把filters
要用的属性添加进去,这个属性有两个用处:1) to turn an attribute into a facet;2) to make any string attribute filterable。
腾讯云记录
由于腾讯云CDN免费版套餐不区别http和https,为了使用https,决定迁移对象存储,CDN到腾讯云
https证书
在FreeSSL.org网站上可以免费申请https证书,建议选择一年期的. 只需要云解析添加其要求的txt记录就可以验证域名的所有权,非常方便. 注意每个整数的key
和pem
都是和域名一一对应的。对于a.jiaxi.me
和jiaxi.me
,需要申请两个不同的证书。
数据万象和对象存储
首先在数据万象中新建bucket,其bucket会自动关联到对象存储cos中,注意勾选CDN加速,其会自动建立数据万象的CDN加速域名. 以后就使用这个域名访问包括图片的静态资源. 之所以不使用自定义域名或者cos的加速域名,是因为
- 自定义域名在CDN控制台设置了HTTP Header的
Access-Control-Allow-Origin
值为*
时,在跨域访问的时候依然总是报错,怀疑腾讯云有bug - cos的域名/加速域名是为了下载而使用的,如打开图片会自动下载而不是直接显示; 此外没有
?imageInfo
的功能
然后到对象存储的设置界面,添加Access-Control-Allow-Origin
的值为*
,便于跨域访问。
CDN控制台
上传证书到腾讯云后,可以为每个域名开启https. 具体方法为,在CDN设置界面,开启强制跳转HTTPS,跳转方式可以选301跳转(永久跳转)。
调试手机网页
由于手机上浏览器的内核和chrome的不一样,同样的网页显示出来不同; 所以一个办法就是连接手机,用chrome的审查元素进行调试。
手机上安装UC浏览器开发者版本,打开开发者选项
-USB调试
,连接电脑; 打开chrome://inspect/#devices
就能看到手机UC浏览器中当前显示的页面,点击Inspect Pages
进行调试,此时手机上会高亮显示当前选中的dom块。
Win10下调试iPhone iOS:见这里,注意电脑需要安装safari。
Tips
- 小banner比例为
2:1
或2.2:1
,大banner是靠上30%对齐的,一般用4:3
- MathJax配置教程,更建议参考官方文档
- Chrome用woff2字体(带有Unicode Range),IE/夸克使用woff字体,搜狗会使用ttf字体
Last updated on Feb 08, 2020.