将WordPress从Plesk迁移到Docker

由于维基主机(idc.wiki)老板失联多时,tg群友也反馈其服务器无人维护,固将博客从维基主机的plesk迁移到Hetzner的VPS上,在此记录过程。

1. Docker compose

使用docker官方的wordpress和mysql镜像,我的VPS已经实机安装Nginx和acme.sh,因此这两个就不再使用Docker。

docker-compose.yml文件如下:

services:
  blog:
    image: wordpress:latest
    container_name: blog
    restart: always
    ports:
      - 127.0.0.1:30080:80
    volumes:
      - /wordpress/wp_config:/var/www/html
    depends_on:
     - mysql
  mysql:
   image: mysql:latest
   container_name: mysql
   restart: always
   ports:
     - 127.0.0.1:3306:3306
   environment:
     MYSQL_DATABASE: 数据库名称
     MYSQL_ROOT_PASSWORD: 数据库密码
   volumes:
     - /wordpress/mysql_config1:/var/lib/mysql
     - /wordpress/mysql_config2:/docker-entrypoint-initdb.d
     - /wordpress/mysql_backup:/mysql_backup

2. 导入文件

数据库文件:将plesk中导出的数据库文件放入 /wordpress/mysql_backup 文件夹中,之后运行以下命令:

#如果需要改数据库内容,可以直接改dump文件
docker exec mysql bash -c "mysql -uroot -p数据库密码 数据库名称 < /mysql_backup/数据库文件"

WordPress文件:将plesk备份文件上传到VPS之后,解压:

tar -I zstd -xvf 备份文件.tzst

关闭1中开启的wp镜像,之后将/wordpress/wp_config中的文件,除了htaccess全部删除,将解压出的wp文件除了htaccess放入其中,并修改权限:

chown www-data:www-data wp_config/* -R
#或
chown 33:33 wp_config/* -R

之后修改 wp_config.php,更改数据库相关信息,数据库地址为 mysql,用户为root,数据库名称和数据库密码和docker compose中设置的一致。

如果最后在登录wp后台时,遇到循环重定向问题,需要在wp_config.php中增加:

$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_LOGIN', true);
define('FORCE_SSL_ADMIN', true);

同时,用crontab代替WP-Cron,在wp_config.php中增加:

define('DISABLE_WP_CRON', true);

在crontab中增加:

*/10 * * * *  /usr/bin/docker exec blog bash -c "php -f /var/www/html/wp-cron.php" > /wordpress/wp-cron.log 2>&1

最后,启动wp镜像。

3. 配置SSL与Nginx反代

获取Cloudflare的API token,参考:

https://github.com/acmesh-official/acme.sh/wiki/dnsapi#1-cloudflare-option

之后获取证书:

export CF_Token="CF的API token"
export CF_Account_ID="CF的账户ID"

/root/.acme.sh/acme.sh --register-account -m 邮箱
/root/.acme.sh/acme.sh --issue --dns dns_cf -d 域名 -d *.域名
/root/.acme.sh/acme.sh --installcert -d 域名 --key-file /证书文件夹/域名.key --fullchain-file /证书文件夹/域名.pem --reloadcmd  "service nginx force-reload"

最后建立Nginx的配置文件:

server {
    listen 80;
    server_name 域名 www.域名;
    return 301 https://$server_name$request_uri;
}

server {
    server_name 域名;

    listen 443 ssl;
    
    ssl_certificate         /证书文件夹/域名.pem;
    ssl_certificate_key     /证书文件夹/域名.key;
    
    return 301 https://www.域名$request_uri;
}

server {
    server_name www.域名;

    listen 443 ssl;
    
    ssl_certificate         /证书文件夹/域名.pem;
    ssl_certificate_key     /证书文件夹/域名.key;
    

    location ~* /xmlrpc.php {
      deny all;
    }
 
   location / {
          client_max_body_size  64m;
          proxy_http_version 1.1;
          proxy_pass http://127.0.0.1:30080;
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $remote_addr;
          proxy_cache_bypass $http_upgrade;
          proxy_set_header Accept-Encoding gzip;
   }

}

最后测试配置正确后,重启Nginx:

nginx -t
service nginx restart

4. 每日备份

需要配置rclone和crontab,用以每日备份博客到Dropbox.

#   0 5    *   *   *  /bin/bash /wordpress/back_wp.sh  > /wordpress/back_wp.log 2>&1
BASE_DIR=/wordpress
/usr/bin/docker exec mysql bash -c "mysqldump -uroot -p数据库密码 数据库名称 > /mysql_backup/wp_db_$(date +%Y%m%d).sql"
tar -czvf $BASE_DIR/wp_backup/wp_date_$(date +%Y%m%d).tar.gz $BASE_DIR/wp_config
tar -czvf $BASE_DIR/wp_backup/wp_backup.tar.gz               $BASE_DIR/mysql_backup/wp_db_$(date +%Y%m%d).sql $BASE_DIR/wp_backup/wp_date_$(date +%Y%m%d).tar.gz
rm                                                           $BASE_DIR/mysql_backup/wp_db_$(date +%Y%m%d).sql $BASE_DIR/wp_backup/wp_date_$(date +%Y%m%d).tar.gz
/usr/bin/rclone copy $BASE_DIR/wp_backup dropbox:wp_backup

大功告成~