记一次博客数据迁移 | doker compose

背景

从上大学开始,一直用的是阿里云的学生云服务器,毕业之后懒得迁移,一直沿用了阿里云。但阿里云价格越来越贵,最近一两年,一台2核2G配置的服务器,续费也要1500左右一年。

并且2G 内存和40G 的存储,已经无法满足我现在的需求了,多跑几个服务就内存和存储紧张。

今年11月份,在群里看到一个腾讯云的双十一活动,2核4G 80SSD 的云服务器,3年一共才198元,比阿里云半年的都便宜,直接买了一台,当时还在犹豫要不要多屯几个。

最近工作很忙,一直没来得及迁移,今天刚好是元旦假期,2022年的1月1日,自己一个人跑公司来迁移服务器了。新的一年,开心快乐~

架构

也搭建和迁移过多次服务器了,每次都比较蒙圈,也会遇到很多坑。但也越来越平静了,不至于束手无策。

最早在搭建自己博客的时候,就考虑到了数据迁移问题。

整体的技术架构,都使用docker 容器来部署,配合docker compose ,将容器数据统一挂载到单独的文件夹下。这样在迁移的时候,只需要保证容器的版本一致,直接将数据卷拷贝到新的服务器,理论上就搞定。哈哈哈,不过迁移真的很折磨人,各种奇奇怪怪的问题,这也是为什么得写文章记录一下。节省下次迁移的时间。

博客组成

WordPress

博客的前端,采用的是wordpress 软件。之所以选择WordPress,一方面是自己过来爱自己手写博客代码和捣鼓样式的年龄,另一方面,目前WordPress做的真实非常好,几十年的生态,还有好用的区块编辑器,以及完善的文档教程。可以最快速的搭建一个自己喜欢的个人博客网站。

MySQL

由于选用了WordPress,MySQL就成了必备的配套设施,必须带上。既然有了,平时也可以在里面捣鼓点其他东西。

nginx

反向代理服务器。之所以Nginx 必不可少,是因为平时自己还会有很多的node 项目,以及子域名的使用,这么来看,Nginx 也是不可或缺的。

docker-compose 文件

这是几年前的源文件。

version: '3'
services:
  nginx:
    image: nginx:1.15.8
    restart: always
    # 端口映射
    ports:
      - "80:80"
      - "443:443"
    # 依赖关系
    depends_on:
      - "wordpress"
    # 数据卷
    volumes:
      # 映射主机./conf.d目录到容器/etc/nginx/conf.d目录
      - "./conf.d:/etc/nginx/conf.d"
      - "/volumes/ever/www:/usr/share/nginx/html"
      - "./ssl:/var/ssl"
    networks:
      - app_net
    # 容器名称
    container_name: "compose-nginx"

  mysql:
    image: mysql:5.7
    restart: always
    ports:
      - "3336:3306"
    # 环境变量
    environment:
      MYSQL_PASSWORD: **
      MYSQL_ROOT_PASSWORD: **
    volumes:
      - ./mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf
      - /volumes/ever/mysql:/var/lib/mysql
    networks:
      app_net:
        # 固定子网ip,网段必须在子网络10.10.*.*
        ipv4_address: 10.10.10.1
    container_name: "compose-mysql"

  wordpress:
    depends_on:
      - mysql
    image: wordpress:5.3.2
    ports:
      - "8211:80"
    restart: always
    environment:
      WORDPRESS_DB_NAME: **
      WORDPRESS_DB_HOST: **
      WORDPRESS_DB_USER: **
      WORDPRESS_DB_PASSWORD: **
    volumes:
      - /volumes/ever/wordpress:/var/www/html
    networks:
      app_net:
        # 固定子网ip,网段必须在子网络10.10.*.*
        ipv4_address: 10.10.10.5
networks:
  app_net:
    driver: bridge
    ipam:
      config:
        # 子网络
        - subnet: 10.10.0.0/16

这里有几个注意点,对于丝滑迁移十分重要:

  1. docker image 的版本号,一定要指定精确的版本号x.x.x ,不要只用x ,更不要用latest。只要有一点点不一样,迁移的时候都可能会耗费大量的时间来查问题,如果是用了latest ,甚至都无法兼容。
  2. 凡是容器会产生数据的,一律把数据都挂载到容器外面,并且最好都放到一个文件夹当中,这样迁移的时候方便一锅端。

数据迁移

大家可以看到,我之前已经把所有的数据都挂载到了/volumes 下面,理论上我只要把/volumes 拷贝到新的服务器的相同位置,然后git 拉一下代码,执行:

docker compose up

就一键搞定了,完美!

哈哈哈,然鹅事实上我还是花了半天时间才搞定的。

首先是拷贝/volumes,我们可以使用远程拷贝命令:

scp -r /volumes user@ip:/volumes

这个文件夹下面有几百兆数据,拷贝起来还是很慢的,另外因为一些原因,我拷贝了好几次,抓狂。

为什么我拷贝了好几次?因为拷贝完mysql 执行报错了:

[ERROR] InnoDB: Plugin initialization aborted with error Cannot open a file

我记得之前迁移就见过这货,老对手了。我第一反应是可能拷贝的时候没拷贝完,数据缺失,于是删掉重新拷贝,还是同样的错误。在查了一些资料之后,用有人说到,mysql 数据备份的时候要停止服务。我觉得可能是这个的原因,于是停止了老服务器上的docker ,再次拷贝,运行成功!

mysql 好了之后,我打开wordpress , 发现能访问到服务,但页面加载不出来,浏览器F12 看了一下,发现所有的css 和js 都没加载成功,原因是WordPress 写的是绝对路径,用的是我的域名,而服务刚刚被我停掉了。

重启服务后,验证没问题,感觉到阿里云把DNS 解析到新的ip 上。

说到解析,生效会有个延迟,大概10分钟。这十分钟里,我ping redream.cn 返回的是新的ip,但浏览器访问却是网络错误,正在我还在各种检查的时候,忽然就生效了哈哈哈。

但wordpress 这个写死绝对路径的写法,感觉会给我埋坑,假如之后把博客放到子域名下,可能会引发一下小问题。不过问题不大,查了下wordpress修改域名也挺简单的,可以在设置里面改,如果服务起不来,可以在数据库直接修改。

优化

迁移算是基本完成了,但还有挺多优化可以做的。这里简单列一下:

  1. mongo 数据库加入到docker compose 集群当中,不单独起服务。
  2. docker build 避免在本地进行。本地build 后每次迁移,如果没有推送到仓库,会丢失一些镜像。之前多数是用钩子触发docker hub的构建,目前docker hub 只有付费用户才能构建。准备迁移下,使用github actions 构建后推送到docker hub, 本地拉取镜像只运行。
  3. 所有数据卷放在同一个目录。

最后

今天是2022年的第一天,平凡而普通的一天,一如既往,呆在公司捣鼓一些事情。希望新的一年,开心、幸福、健康,有所突破!

安利下腾讯云的服务器,真的很香,1核2G 38/年,2核4G 74/年。不到一顿饭钱,多学点东西,多一些可能性!

Leave a Comment

邮箱地址不会被公开。 必填项已用*标注