将博客迁移到 Docker 上

这两年也就春节这几天有工夫折腾一下自己的博客。

16 年左右吧,Docker 大火,想把博客迁移到 Docker 上,然而失败了。这几年随着 Docker 越用越多,工具越来越好,又尝试了好几次,不幸的是,都失败了。

然而今年,终于成功了。


来说说做了啥。

首先,我依然有强烈的洁癖:不想用第三方镜像,只想用 “官方” 镜像。于是有了下面这个列表:

  • wordpress:fpm-alpine
  • nginx:alpine
  • mariadb:latest

要说上面三个镜像凑齐了就能开始干活了。

先照虎画猫,写个 docker-compose.yml 文件:

version: "3.6"
services:
  wordpress:
    image: wordpress:fpm-alpine
    container_name: my_blog
    volumes:
      - ./wordpress:/var/www/html
    environment:
      - WORDPRESS_DB_NAME=wordpress
      - WORDPRESS_TABLE_PREFIX=wp_
      - WORDPRESS_DB_HOST=database
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
    depends_on:
      - database
    restart: always

  database:
    image: mariadb
    container_name: database
    volumes:
      - ./database:/var/lib/mysql
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress
      - MYSQL_DATABASE=wordpress
    restart: always

  nginx:
    image: nginx:alpine
    container_name: nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - ./cert:/etc/letsencrypt
      - ./logs:/var/log/nginx
      - ./wordpress:/var/www/my_blog
    depends_on:
      - wordpress
    restart: always

然后 docker-compose up ,浏览器打开,发现被拒绝。 docker ps 发现 nginx 一直在重启。比较奇怪的是,其他 volume,如果宿主机上没有的话,docker 会将镜像里面的东西复制到宿主机上来,但是 nginx 的配置死活过不来。然后看 readme,将 docker 里面的配置文件复制出来:

docker run --name tmp-nginx-container -d nginx
docker cp tmp-nginx-container:/etc/nginx/nginx.conf /host/path/nginx.conf
docker cp tmp-nginx-container:/etc/nginx/conf.d/default.conf /host/path/default.conf
docker rm -f tmp-nginx-container

OK,这下子能看到 nginx 欢迎页了。但这远远不够:Wordpress 还没工作呢。

改 nginx 配置如下:

server {
    listen 80 http2 ssl;
    #listen [::]:80 http2 ssl ipv6only=on;

    server_name _;

    root /var/www/my_blog; # Only for static files
    index index.html index.php;

    location / {
        try_files $uri $uri/ /index.php?$args; # 注意最后不能加上 `=404` 否则不能伪静态
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_index index.php;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;# 注意这里前面我手写了绝对路径
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_pass blog:9000;
        include fastcgi_params;
    }

}

OK 这下子 wp 可以工作了。这里有个点需要注意一下:看 docker-compose 里面的 volumes 设置。 wp 的路径在 /var/www/html,如果这个东西被挂载在了 nginx 里面的 /var/www/html,那么假如我想再起一个 wp,路径也在 /var/www/html,两个就冲突了。所以这里需要搭配开。另外,如果这里和 php-fpm 里面的路径不同的话,SCRIPT_FILENAME 需要再自己写一下,和 php-fpm 里面的路径对应。好像设置 root 的方式无效。

以上所有步骤都在自己的 mac 上跑的,验证通过后自然就是上线测试了。将现在网站的配置、插件、 sql 导出来,新服务器上安 docker,起 docker,导入 sql,一切看起来都那么顺利。

然而……

首先发现,我之前启用了 hsts,会强制从 http 跳转到 https,现在还没有配置 https,于是各种挂。并且似乎 wildcard hsts 是和 dns 绑定的,一直试图跳转到原来的 ip 。

重启浏览器,开隐身,强行进数据库里面将首页的 https 改为 http,然后各种降级,终于能在 http 模式下跑起来了。

然后是配置 https 。再挂上一个 acme.sh 的 Docker:

  acme.sh:
    image: neilpang/acme.sh
    container_name: acme.sh
    command: daemon
    volumes:
      - ./data/cert:/acme.sh
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - Ali_Key=XXXXX
      - Ali_Secret=XXXXX

然后执行一句 docker-compose exec acme.sh --issue --dns dns_ali -d haoyu.love -d "*.haoyu.love",证书就申请好了。最后将证书配置到 nginx 里面就好。

最最后是备份脚本。有了 Docker,有了备份,就能迅速搬家。本来备份这件事儿也想写个 Docker 来搞,但是觉得工作量太大了……就污染一下母鸡:安个 conda,写个 crontab,完事儿。


说这这么简单……其实……都是泪……

比如,nginx,尝试了一整天才知道后面 SCRIPT_FILENAME 应该这样设置;比如,配置证书,申请到好几个文件,不知道哪个该怎么写;比如,想配置 Redis 缓存,无奈 php-fpm 镜像默认没装 redis 扩展;比如,w3tc 配置 Redis 缓存,找遍了 docs 才找到方法;比如,备份脚本,调用 bash 的时候,命令是对的,但结果死活与预期不相符……

这下好了~估计下次折腾博客,是 2021 年了。

后续

因为全国肺炎疫情在家闲着,就顺便多折腾了点。

首先,解决了左边菜单一直飘的问题。感觉应该是跟背景 backdrop-filter 冲突了,只要加上这句,就开始乱飘。后来通过一个伪类解决了这个 Bug 。

然后是,给代码加上了个样式。之前 code 跟正文实在分不开,现在能看清了。

还有是修复了一大堆的样式。第一次感受到 WordPress 的主题编辑器还是有点用的。😂

最后嘛……各种小 Bug 修复,还没修完。想不通为啥 Docker 之后这么多 Bug……站点健康总达不到 100% 。

参考资料


本来昨天晚上写的时候,标题是「将博客迁移到 Docker 上——又一次失败了」,然后今天找了一天资料,无数次 docker-compose up -d 和 docker-compose down 之后,终于,终于成功了。