将博客迁移到 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 之后,终于,终于成功了。

留下评论