看了一下自从上一次更新之后这又过去一个季度了。要不是这次短期旅行没有带上平时工作
的电脑估计我还不知道什么时候可以抽出时间写下这篇文章。说起来让人感慨,读书的时候我对于写代码非常不感兴趣,当年还是靠我一哥们给我讲题,帮我做作业勉强毕的业。那曾想到30岁之后因为工作的原因重新接触代码之后反而被迷住了,现在仅存的一点个人时间都放在各种有的没得project上面。
言归正传,我们下面分几个方面来说说Ghost以及如何用Docker和Traefik来快速搭建一个Ghost Blog。
什么是Ghost 我在之前的文章中也介绍过如何安装Wordpress
。根据W3Techs
的这篇CMS占比 的文章,Wordpress
超过60%的市场占有率让它毫无疑问地成为了很多人建站的第一选择。大部分的share hosting肯定都有一键安装Wordpress
的功能,而且多年的深耕也让WP拥有了及其庞大的皮肤和插件库。但是也正因为使用的人太多,让很多网站看起来都以一种同质化的感觉,而且强大的功能对于普通的博客用户根本就是累赘,反而影响了网站的加载速度以及安全性。
Ghost在这种情况下与2012年应运而生,目标是为了纯粹的博客基于Node.js
诞生的一个平台。之前看过某个奥地利博主的这篇文章 很好的说明了我对于Ghost的初始印象。
A blogging platform which is just for blogging? Having a neat markdown editor? This amazing dashboard? SEO right out of the box? Ways to extend via plugins and themes? Oh boy, John, you got me sold.
准备配置文件 自从我用上了Docker和Traefik之后,除了有特别需求的网站之外(例如需要Client Authentication的Apache)我建所有的网站都是用他们来做。在自由度上来说可能比传统的用命令行来的少,但是搭建起来实在太方便了,废话不多说,开始讲解。
首先是docker-compose.yml
这个文件。废话不多说,先放一张最后的成品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 version: '3.3' services: traefik: image: traefik:1.7-alpine command: --api --docker ports: - 80 :80 - 443 :443 labels: - "traefik.enable=true" - "traefik.backend=traefik" - "traefik.frontend.rule=Host:monitor.your.domain" - "traefik.port=8080" networks: - traefiknet volumes: - /var/run/docker.sock:/var/run/docker.sock - ./traefik.toml:/traefik.toml - ./acme.json:/acme.json container_name: traefik restart: always ghost: image: ghost:alpine restart: always ports: - 2368 volumes: - ./ghost/content:/var/lib/ghost/content - ./ghost/config.production.json:/var/lib/ghost/config.production.json environment: - NODE_ENV=production - url=https://ghost.your.domain labels: - "traefik.enabled=true" - "traefik.backend=ghost" - "traefik.frontend.rule=Host:ghost.your.domain" - "traefik.docker.network=traefiknet" - "traefik.port=2368" networks: - traefiknet container_name: ghost depends_on: - traefik networks: traefiknet:
接下来让我分开讲解一下两个container的配置重点。
Traefik Configuration
image :使用的是1.7-alpine
,我之前一直用latest
这个tag,但是在Traefik升级到2.0之后语法都不一样了,因此我之前的网站挂了一天我都没发现……(这也是用WatchTower自动升级image的坏处)
command
--docker
Enable Docker backend with default settings (default “false”)
--api
Enable api/dashboard (default “false”)
ports :打开80和443的端口
labels
需要改的只有"traefik.frontend.rule=Host:monitor.your.domain"
,把host name改成你喜欢的Dashboard的URL,其他copy
networks :自定义一个网络让Ghost和Traefik可以沟通(也可以不加)
volumes
traefik.toml
加载自定义traefik连接的config文件
acme.json
保存自动获取的Let'sEncrypt
证书的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 traefik: image: traefik:1.7-alpine command: --api --docker ports: - 80 :80 - 443 :443 labels: - "traefik.enable=true" - "traefik.backend=traefik" - "traefik.frontend.rule=Host:monitor.your.domain" - "traefik.port=8080" networks: - traefiknet volumes: - /var/run/docker.sock:/var/run/docker.sock - ./traefik.toml:/traefik.toml - ./acme.json:/acme.json container_name: traefik restart: always
traefik.toml 文件讲解
logLevel :用来检查docker运行情况的,一旦运行不起来,这些信息可以有效的帮助我debug,这里可以用INFO
或者DEBUG
defaultEntryPoints :默认打开http 和 http
[entryPoints.https.tls]
minVersion :只支持TLS1.2或以上的protocol来连接
cipherSuites :只支持这几个cipher suite来连接。这个部分我是使用Mozilla SSL Config 来帮我完成
**[acme]**:这里定义如何通过ACME来获取证书,我也只挑我认为重要的讲讲
KeyType :定义获取的证书使用的私钥类型和大小,我喜欢ECC,所以选的ECC384。更多的选择可以参考Traefik官方文档
**[[acme.domains]]**:这里定义了证书包含的域名。我只想用一张证书来保护我所有的域名,因此我在这里定义了主域名和sans。也可以完全不加这个部分,那么Traefik
会为不同的FQDN获取不同的证书保存在acme.json
里面来使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 logLevel = "INFO" defaultEntryPoints = ["http" , "https" ][entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] minVersion = "VersionTLS12" cipherSuites = [ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" , "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" , "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" , "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" , "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305" , "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305" ] [acme] email = "[email protected] " storage = "acme.json" onHostRule = true KeyType = "EC384" entryPoint = "https" [acme.httpChallenge] entryPoint = "http" [[acme.domains]] main = "monitor.your.domain" sans = ["ghost.your.domain" ]
生成acme.json文件 1 2 touch acme.json sudo chmod 600 acme.json
Ghost Configuration 网上大部分的Ghost教程都用的MySQL的数据库。我认为普通人使用Ghost自带的SQLite已经完全足够,我们也不需要再配置以及连接MySQL和Ghost(虽说不难吧……还是能省则省)
image :这里我们选择用最新的Ghost Alpine Image (Alpine的好处是体积小,所以任何可以用alpine的image我都用alpine)
volumes
./ghost/content
是把Ghost的文件映射到服务器本地方便修改
./ghost/config.production.json
是把Ghostd的config文件映射出来方便修改,这一步挺重要的,不然你就需要使用docker exec
进入到container去修改这个文件了
其他的照抄,需要注意的就是把下面的URL改成你blog的地址
"traefik.frontend.rule=Host:ghost.your.domain"
- url=https://ghost.your.domain
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ghost: image: ghost:alpine restart: always ports: - 2368 volumes: - ./ghost/content:/var/lib/ghost/content - ./ghost/config.production.json:/var/lib/ghost/config.production.json environment: - NODE_ENV=production - url=https://ghost.your.domain labels: - "traefik.enabled=true" - "traefik.backend=ghost" - "traefik.frontend.rule=Host:ghost.your.domain" - "traefik.docker.network=traefiknet" - "traefik.port=2368" networks: - traefiknet container_name: ghost depends_on: - traefik
配置config.production.json 这个文件其实是Ghost自动生成的,唯一需要修改的地方就是网站的URL了。你可以也注意到了这里可以配置Mail。ghost支持自动发送邮件给用户。想用的朋友可以根据自己邮箱的服务商来配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { "url" : "http://ghost.your.domain" , "server" : { "port" : 2368 , "host" : "0.0.0.0" }, "database" : { "client" : "sqlite3" , "connection" : { "filename" : "/var/lib/ghost/content/data/ghost.db" } }, "mail" : { "transport" : "Direct" }, "logging" : { "transports" : [ "file" , "stdout" ] }, "process" : "systemd" , "paths" : { "contentPath" : "/var/lib/ghost/content" } }
下面以我用的腾讯企业邮为例,大家可以参考应该怎么配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... , "mail" : { "from" : "[email protected] " , "transport" : "SMTP" , "options" : { "host" : "smtp.exmail.qq.com" , "secureConnection" : true , "requiresAuth" : true , "port" : 465 , "auth" : { "user" : "[email protected] " , "pass" : "YourPassword" } } }, ...
开始安装
这里我假设各位已经安装好了docker和docker-compose
ssh
到vps,默认进入home folder
touch docker-compose.yml && touch traefik.toml
创建docker-compose
和traefik
的配置文件,之后可以用vim
或者nano
打开文件把上文的内容粘贴进去
touch acme.json && chmod 600 acme.json
创建acme.json
文件并修改access权限
mkdir ghost && cd ghost && touch config.production.json
创建ghost目录,生成config.production.json
文件。把上文这个config的文件修改好域名之后copy进去即可
cd ..
回到home folder
docker-compose up
运行docker-compose,系统会自动把image抓下来安装并且ssl证书也会一并安装好
理论来说如果各位按照我上面的做法来做肯定可以成功。