Stay Hungry. Stay Foolish.

关于 Ghost

Ghost 是 Node.js 平台上为数不多的著名博客应用,第一个版本 Ghost 0.3,于 2013 年 9 月发布,由于其高性能和便捷的编辑器收到了很多人的欢迎,但是接下来的几年中一直没有大的改动,新功能发布非常缓慢,因此也受到很多诟病。

2017 年 7 月 27 日, Ghost 迎来了第 100 个版本,被命名为 Ghost 1.0,这次大更新(据称) 彻底推翻了之前的东西,重新造了一个全新的 Ghost 博客系统,安装方法也和之前的大不相同。但是这个版本也有很多问题,他的更新速度太过频繁,你甚至很难找到一个稳定版日常使用;ghost-cli 脚手架看似很方便,实际上错误百出;NodeJS 以 高效 著称,而 Ghost 有时候夸张的资源占用让人觉得 搞笑

2018 年 8 月 16 日,仅仅一年后,Ghost 2.0 作为新的大版本发布,带来了两个主要特性:动态路由表Koenig 富文本编辑器

动态路由表试图解决一个在其他平台上简单到难以置信的小功能:自定义链接格式,Wordpress、Typecho 等平台下几乎不算是功能的点,被做成了重要的新特性,还要通过写复杂的 yaml 文件来配置。

Koenig 富文本编辑器 似乎也是一个很难理解的更新,因为完全没法选择之前优雅的 Markdown 编辑器,虽然 Koenig 是个不错的编辑器,也能支持 Markdown 编辑,但总体来说失去了简介性和在手机上写作但便捷性。无独有偶,Ghost 团队的老东家 Wordpress 也开始推广新的Gutenberg 富文本编辑器,两者不但功能类似,连界面都非常相似,似乎这就是大势所趋?

注意 Koenig 目前 不支持 中文输入法。

使用 Ghost-CLI 安装 Ghost

本文只介绍简单的安装过程,更复杂的配置优化可以看这边

基础工作

首先要做的肯定是更新系统啦,Ghost 官方只在 Ubuntu 16.04 LTS 上进行测试,实际上 Debian 系列肯定都是可以的啦,本教程所用系统 Ubuntu 18.04,机器配置要求至少 1G 内存。

  • 首先使用 root 用户登录,更新系统并安装必要组件:
apt update && apt full-upgrade -y
apt install apt-transport-https lsb-release ca-certificates unzip git wget curl sudo sqlite3 -y
add-apt-repository ppa:ondrej/nginx-mainline -y
apt update && apt install nginx-extras -y
  • 添加 Swap (可选):

Ghost 要求的最小安装内存是 1G ,如果内存不足很有可能安装失败,所以我们要加一些 Swap:

fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

# 让 Swap 后台启动
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

安装 Node.js 10 LTS

curl -sL https://deb.nodesource.com/setup_10.x | bash -
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
apt update && apt install nodejs yarn -y

安装 Ghost-CLI

Ghost-CLI 需要定时更新以保持最新版本

  • yarn 安装(推荐)
yarn global add [email protected]
  • npm 安装(不推荐)
npm i -g npm
npm i -g [email protected]
  • cnpm 安装
npm i -g cnpm --registry=https://registry.npm.taobao.org
cnpm i -g [email protected]
  • 针对国内的机器可以执行换源操作:
yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global
npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global

执行安装

  • 添加运行用户,注意用户名不能为 ghost
  • 也不要使用 ghost 用户安装
adduser dcc

然后系统会提示你输入两次密码,其他的一律回车即可

  • 接着给予用户 sudo 权限:
usermod -aG sudo dcc
su - dcc
  • 创建并修改网站目录权限

假设目录在 /var/www/ghost

sudo mkdir -p /var/www/ghost && sudo chmod -R 755 /var/www/ghost && sudo chown -R dcc.dcc /var/www/ghost && cd /var/www/ghost

由于博客比较小,可以不配置 MySQL 数据库,使用 SQLite3 作为数据库,然后配置所有的环境和依赖。

  • 直接执行这个命令即可
ghost install --db=sqlite3

如果需要安装 1.x 稳定版可以加上 --v1 参数

安装会有如下提示步骤:

✔ Checking system Node.js version
✔ Checking located in user
✔ Checking current folder permissions
✔ Checking operating system compatibility
✔ Checking memory availability
✔ Checking for latest Ghost version
✔ Setting up install directory
✔ Downloading and installing Ghost v2.xx.x
✔ Finishing install process
? Enter your blog URL: https://example.com(这边输入你的博客域名)
✔ Configuring Ghost
✔ Setting up instance
Running sudo command: useradd --system --user-group ghost
Running sudo command: chown -R ghost:ghost /var/www/ghost/content
✔ Setting up "ghost" system user
? Do you wish to set up Nginx? Yes
✔ Creating nginx config file at /var/www/ghost/system/files/example.com.conf
Running sudo command: ln -sf /var/www/ghost/system/files/example.com.conf /etc/nginx/sites-available/example.com.conf
Running sudo command: ln -sf /etc/nginx/sites-availableexample.com.conf /etc/nginx/sites-enabled/example.com.conf
Running sudo command: nginx -s reload
✔ Setting up Nginx
? Do you wish to set up SSL? No
ℹ Setting up SSL [skipped]
? Do you wish to set up Systemd? Yes
✔ Creating systemd service file at /var/www/ghost/system/files/ghost_example-com.service
Running sudo command: ln -sf /var/www/ghost/system/files/ghost_example-com.service /lib/systemd/system/ghost_example-com.service
Running sudo command: systemctl daemon-reload
✔ Setting up Systemd
Running sudo command: /var/www/ghost/current/node_modules/.bin/knex-migrator-migrate --init --mgpath /var/www/ghost/current
✔ Running database migrations
? Do you want to start Ghost? Yes(建议输入 Y)
Running sudo command: systemctl is-active ghost_example-com
✔ Ensuring user is not located in as ghost user
✔ Checking if located in user is directory owner
✔ Checking current folder permissions
Running sudo command: systemctl is-active ghost_example-com
✔ Validating config
✔ Checking folder permissions
✔ Checking file permissions
✔ Checking content folder ownership
✔ Checking memory availability
Running sudo command: systemctl start ghost_example-com
✔ Starting Ghost
Running sudo command: systemctl is-enabled ghost_example-com
Running sudo command: systemctl enable ghost_example-com --quiet
✔ Starting Ghost

You can access your blog at https://example.com

Ghost-CLI -- 硬币的正反面

Ghost 博客程序实在是让人又爱又恨,而其中争议最多的必然是 Ghost-CLI 这个脚手架工具了,Ghost 团队把它吹上了天,并且意图将它打造成安装 Ghost 的唯一方法。新版本 Ghost 也越来越与 Ghost-CLI 耦合。

看似能够一个命令完成安装、配置和管理,实际上安装速度缓慢,环境、权限异常严格,也不能保证在不同环境下能够正常地运行,cli 本身更新频繁,bug 也很多。更加有趣的事情是,Ghost 的付费托管服务 Ghost Pro 并不使用 Ghost-CLI 工具,而是使用 Passenger。

不用 Ghost-CLI 安装 Ghost

这边介绍一种抛弃 Ghost-CLI 的安装方式,把 Ghost 作为 npm module 来安装。

安装 Passenger

apt-get install -y dirmngr gnupg lsb-release apt-transport-https ca-certificates unzip git wget curl sudo sqlite3
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger $(lsb_release -sc) main > /etc/apt/sources.list.d/passenger.list'
apt-get update && apt-get install -y passenger

以 npm 形式安装 Ghost

curl -sL https://deb.nodesource.com/setup_8.x | bash -
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
apt update && apt install nodejs yarn -y

mkdir -p /var/www/ghost && cd /var/www/ghost
yarn init && yarn add [email protected] --save
cp -r node_modules/ghost/content .
  • 创建启动文件 index.js
cat > /var/www/ghost/index.js << EOF
const ghost = require('ghost');
ghost().then(function (ghostServer) {
    return ghostServer.start();
})
EOF
  • 创建配置文件 config.production.json

参考配置文件如下,记得修改 "contentPath": "content" 这一项

{
    "url": "https://example.com",
    "database": {
        "client": "sqlite3",
        "connection": {
            "filename": "content/data/ghost.db"
        },
        "debug": false
    },
    "paths": {
        "contentPath": "content"
    },
    "useMinFiles": true,
    "logging": {
        "level": "info",
        "rotation": {
            "enabled": true
        },
        "transports": ["file", "stdout"]
    }
}

启动 Ghost

Ghost 1.x 时期需要使用 knex-migrator 进行数据库初始化,但是到 2.x 时期已经可以直接启动

NODE_ENV=production node index.js

这样就可以完成数据库初始化到操作,然后我们使用 passenger 来启动 Ghost

passenger start --app-type node --startup-file index.js --address 127.0.0.1 --port 2368 --environment production --daemonize

如果需要停止则执行:

passenger stop -p 2368

Ghost 和 Nginx 配置:

Ghost-CLI 本来是自带 Nginx 配置和 SSL 的,但是经过测试失败率太高,所以手动进行配置。

server {
    listen 443 ssl http2;
    server_name example.com;
    keepalive_timeout 300;
    ssl_certificate_key /etc/ssl/example.com.key;
    ssl_certificate /etc/ssl/example.com.crt;
    ssl_session_cache shared:SSL:10m;  
    ssl_session_timeout 24h;           
    ssl_buffer_size 1400;
    add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';
 
    location / {
        proxy_hide_header X-powered-by;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }
}

重启 Nginx,打开 https://example.com/ghost/ 结束安装

nginx -t
service nginx restart