安装 Ghost

背景

一直想有一个个人博客空间,之前使用过自建的 WordPress,但是后来没有坚持下来。后来学会了 Node.js,想用 Node.js 开发的个人博客系统,之前查到过 Ghost,因为使用的是 Mysql 数据库,所以没有想使用。由于最近要重做管理平台,数据库计划由 MongoDB 迁移到 Mysql,所以有了使用 Ghost 的充分理由。

目标

  • 正常安装 Ghost;
  • 正常使用 Ghost;
  • 学习 Ghost 的代码;
  • Mysql 的连接和使用部分;
  • 权限管理部分;
  • 业务部分;
  • 配置文件;
  • 启动文件;

安装过程

安装 Ghost

第一次使用 Ghost-CLI 安装,提示一下内容:

⚠ Linux version is not Ubuntu 16,⚠ Missing package: systemd,⚠ Missing package: nginx

看来只有在 Ubuntu 16 上才可以使用 Ghost-CLI,我的 Centos 7 自然是不行了。因此采用最传统的安装方式。

  1. 下载最新的 Ghost 版本

    curl -L https://ghost.org/zip/ghost-latest.zip -o ghost.zip

  2. 解压到指定文件夹

    unzip ghost.zip -d ./ghost/

  3. 安装运行所需要的依赖包

    npm install --production

  4. 测试运行

    npm start --production

  5. 建立 PM2 配置文件,使用 PM2 运行 Ghost

    pm2 ecosystem
    pm2 start ecosystem.config.js

  6. 配置 Nginx

  7. 将数据库从 SQLite3 更换为 MariaDB,修改配置文件 config.js

database: {
  client: 'mysql',
  connection: {
    host     : '127.0.0.1',
    user     : 'your_database_user',
    password : 'your_database_password',
    database : 'ghost_db',
    charset  : 'utf8'
  }
}

配置 HTTPS

  1. 安装 certbot;
  2. 修改原有 Nginx 配置文件;
  3. 下载证书;
  4. 再次编辑 Nginx 配置文件,启用 HTTP2 和 HTTPS;
  5. 定期自动更新证书

安装 certbot

sudo yum install epel-release
sudo yum install certbot

修改原有 Nginx 配置文件

Let's encrypt 为了鉴定域名的所有权,会在域名下的 /.well-known/acme-challenge 路径下放置一个文件,并做相应的鉴权,因此需要保证相关路径能够正确的解析,最简单的办法就是直接修改 Nginx 配置文件。

location ^~ /.well-known/acme-challenge/ {
  root /usr/share/nginx/html;
}

location = /.well-known/acme-challenge/ {
  return 404;
}

下载证书

certbot certonly --webroot -w /usr/share/nginx/html/ -d domain1.com -d domain2.com

然后就会进入安装界面,提示输入邮箱地址等信息,然后就安装完毕了。证书文件被保存在 /etc/letsencrypt/live/domain.com/fullchain.pem 下。

再次编辑 Nginx 配置文件,启用 HTTP2 和 HTTPS

upstream my_nodejs_upstream {
    server 127.0.0.1:2368;
    keepalive 64;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name domain.com;

# Redirect all HTTP requests to HTTPS with a 301 Moved
Permanently response.
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name domain.com;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    resolver 8.8.8.8 8.8.4.4;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_max_temp_file_size 0;
        proxy_pass http://my_nodejs_upstream/;
        proxy_redirect off;
        proxy_read_timeout 240s;
    }

    location ^~ /.well-known/acme-challenge/ {
        root    /usr/share/nginx/html;
    }

    location = /.well-known/acme-challenge/ {
        return 404;
    }
}

其中,ssl_certificate 开头的和 ssl_certificate_key 开头的这句分别对应刚刚下载好的证书。
另外,ssl_dhparam 开头的这句指向的证书需要通过以下代码来生成。

sudo mkdir /etc/nginx/ssl
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

定期自动更新证书

因为 Let's encrypt 证书的有效期限是 90 天,因此在 90 天必须要更新证书以避免证书失效。根据 Certbot 官网所述,只有在临近到期时才会真正更换证书,因此最好的每天执行更新命令,确保证书及时更新。

测试更新命令

使用以下命令测试更新证书,但并不会真的更新。

sudo certbot renew --dry-run

设置更新证书定时任务

首先创建定制任务

sudo crontabe -e

然后在文件中加入以下语句,表示在每天的 3 点 43 分尝试更新证书,如果证书更新成功,则重启 Nginx 服务以便读取新证书

43 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

测试定时更新语句

为确保定时更新语句有效,最好单独测试一下,直接输入以下语句看执行结果

certbot renew --quiet --post-hook "systemctl reload nginx"

应该会提示还不需要更新,不过不要紧,只要测试语句有效就可以了。至此,HTTP2 和 HTTPS 的配置全部完毕。

测试配置成果

测试服务器 SSL 的安全性

Qualys SSL Labs 提供了全面的 SSL 安全性测试,填写你的网站域名,给自己的 HTTPS 配置打个分。

如果安装本教程来配置,正常情况下应该会得到 A+ 的得分。

测试 HTTP2

Chrome 下有个插件叫做 HTTP/2 and SPDY indicator。可以利用它来查看访问的站点是否支持 HTTP2。

HTTP2 的问题

话说 HTTP2 之前有 2 种实现的协商协议,分别是 NPN 和 ALPN,后来 Chrome 就只支持 ALPN 了。但当前大部分服务器的 OpenSSL 都是1.01e 版本,只支持 NPN。因此按照本教程部署完毕后,使用 Chrome 刚刚配置好的站点的时候发现还是不能使用 HTTP2,还需要在服务器上做一些调整才可以。

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容