update 2020.04.25

背景

之前在Vultr LA部署了ghost,mysql连接的是百度云服务上的RDS,两个原因迁移主机:

  • RDS到期不想续费了,希望在本机直接建一个mysql服务
  • LA有点远,重新部署在TOKYO的主机上,无论翻墙还是博客访问都能快一点

两个解决思路:

  • 起两个docker服务,手动组网
  • 使用docker-compose组合两个container服务

出于调试需求,本文手工起了两个docker服务。

相关版本配置

  • OS:CentOS 8
  • Docker:19.03.8
  • mysqld:5.7
  • ghost:3.13.4
  • caddy:v2.0.0-rc.3

Docker 安装

  • Step1:设置docker的安装源并安装
$ yum-config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
$ yum install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
$ yum -y install docker-ce
  • Step2:启动docker并设置开机启动
$ systemctl enable --now docker 
$ systemctl disable firewalld
  • Step3:检查启动状态
$ systemctl is-active docker
$ systemctl is-enable docker

Docker mysqld

  • Step1:设置数据库文件本地映射目录
$ mkdir -p /usr/local/docker/mysql/etc
$ mkdir -p /usr/local/docker/mysql/var/log
$ mkdir -p /usr/local/docker/mysql/var/lib
  • Step2:配置mysqld的systemctl service文件
$ cat /usr/lib/systemd/system/docker.mysqld.service
[Unit]
Description=Mysqld Service in Docker Container
Documentation=https://hub.docker.com/_/mysql/
After=network.target docker.service
Requires=docker.service

[Service]
Type=simple
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker stop mysqld
ExecStartPre=-/usr/bin/docker rm mysqld
ExecStart=/usr/bin/docker run \
        --name mysqld \
        -p 3306:3306 \
        -e MYSQL_USER=ghost \
        -e MYSQL_PASSWORD=<db_ghost_passwd> \
        -e MYSQL_DATABASE=gblog \
        -e MYSQL_ROOT_PASSWORD=<db_root_passwd> \
        -v /usr/local/docker/mysql/etc:/etc/mysql \
        -v /usr/local/docker/mysql/var/log:/var/log/mysql \
        -v /usr/local/docker/mysql/var/lib:/var/lib/mysql \
        mysql:5.7

ExecStop=/usr/bin/docker kill mysqld

[Install]
WantedBy=multi-user.target
  • Step3:启动mysqld并设置开机启动
$ docker pull mysql:5.7
$ systemctl daemon-reload
$ systemctl enable --now docker.mysqld

注意事项

  1. 该配置文件直接设置了一个新的mysql用户名ghost和密码<db_ghost_passwd>,不需要启动之后再进入container手动添加用户
  2. 该配置文件直接创建了一个新的数据库gblog,也不需要启动之后再进入container手动添加数据库
  3. mysql root密码必须设置,实际上可能没有用,这里用的是MYSQL_ROOT_PASSWORD参数
  4. 根据官方文档说明,MYSQL_HOST 参数不要轻易设置,在docker容器中容易出错
  5. mysql挂载的文件系统需要保持干净,如果出现 --secure-file-priv 相关问题,可以尝试换一个新的容器文件挂载点
    docker mysql 参数变量说明

Docker ghost

  • Step1:设置ghost内容映射目录
$ mkdir -p /opt/ghost/content
  • Step2:设置ghost的systemctl service文件
$ cat /usr/lib/systemd/system/docker.ghost.service
[Unit]
Description=Ghost Application in Docker Container
Documentation=https://hub.docker.com/r/library/ghost/
After=network.target docker.service docker.mysqld.service
Requires=docker.service
Requires=docker.mysqld.service

[Service]
Type=simple
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker stop ghost
ExecStartPre=-/usr/bin/docker rm ghost
ExecStart=/usr/bin/docker run \
        --name ghost  \
        -p 2368:2368  \
        -e NODE_ENV=production \
        -e url=http://huhao.ai \
        -e database__client=mysql \
        -e database__connection__host=172.17.0.1 \
        -e database__connection__user=ghost \
        -e database__connection__password=<db_ghost_passwd> \
        -e database__connection__database=gblog \
        -v /opt/ghost/content:/var/lib/ghost/content  \
        ghost:alpine

ExecStop=/usr/bin/docker kill ghost

[Install]
WantedBy=multi-user.target
  • Step3:启动ghost并设置开机启动
$ docker pull ghost:alpine
$ systemctl daemon-reload
$ systemctl enable --now docker.ghost

注意事项

  1. ghost的url参数不能是https,只能是http,否则会出现http 301死循环。
  2. database__connection__host参数要根据docker的网络设置来。此处,由于没有定义docker network,也没有设置swarm service之类,因此设置成了docker容器默认的网关。如果使用127.0.0.1可能出现无法连接。
  3. docker默认的网络docker0的网关就是172.17.0.1,可以通过以下两种方式查看:
$ docker network inspect bridge
$ ifconfig
  1. 注意ghost配置文件的After和Requires

Caddy Https反向代理

之前是通过Nginx做反向代理,支持https通过certbot,配置过程还是比较麻烦。使用Caddy服务器之后,过程就极其简单。

  • Step1:安装caddy
$ yum-config-manager --add-repo https://copr.fedorainfracloud.org/coprs/g/caddy/caddy/repo/epel-8/group_caddy-caddy-epel-8.repo
$ yum install caddy

Step2:将域名 huhao.ai、www.huhao.ai 的DNS解析指向TOKYO的服务器。

Step3:设置caddy配置文件

$ cat /etc/caddy/Caddyfile
huhao.ai {
        reverse_proxy 127.0.0.1:2368
}

www.huhao.ai {
        redir https://huhao.ai{uri}
}
  • Step4:启动caddy服务
$ systemctl daemon-reload
$ systemctl enable --now caddy

注意事项

  1. caddy默认使用ACME协议自动管理https证书,跟letsencrypt自动集成,不需要做任何设置。
  2. caddy启动的时候,会检查配置文件中的域名,如果没有https证书,会自动申请并管理证书。
  3. 本文使用的是caddy v2,跟v1在配置文件上有一些不同,做了很多简化、默认配置,不再需要设置transparent或者X-Real-IP、X-Forwarded-Proto之类的。caddy v2配置文件升级说明

Ghost迁移

之前网站数据在LA的服务器,迁移到TOKYO的服务器,主要有两部分:

  • 文章Posts:通过Ghost Admin后台的Export/Import功能导出/导入
  • 网站设置、图片信息(包括主题):/var/lib/ghost/content 文件夹整体打包迁移

Ghost迁移指南

相关调试方法

过程中遇到的问题,调试需要查看日志相关,几个相关的命令如下:

  1. 查看docker容器的日志文件
$ docker logs -f ghost
  1. 查看systemctl服务的日志信息
$ journalctl -u caddy -f
  1. 进入mysqld容器进行相关手动操作
$ docker exec -it mysqld mysql -uroot -p<db_root_passwd>
mysql> create user ghost@'%' identified by '<db_ghost_passwd>';
mysql> grant all on gblog.* to 'ghost'@'%' identified by "<db_ghost_passwd>";
mysql> grant all on gblog.* to 'ghost'@'localhost' identified by "<db_ghost_passwd>";
mysql> grant all on gblog.* to 'ghost'@'172.17.0.1' identified by "<db_ghost_passwd>";
mysql> flush privileges;


mysql> use mysql;
mysql> select host, user, authentication_string, password_last_changed from user;

理论上,如果使用了MYSQL_USER、MYSQL_PASSWORD、MYSQL_ROOT_PASSWORD、MYSQL_DATABASE,就会自动创建数据库、用户并授权。此处仅为了说明手动操作原理。

相关参考