💡
此文也可作为新服务器安装指南

三年之期还没到,腾讯就开始给我上嘴脸了,每天的续费通知就像催命符似的发个没完,起初是准备换平台的,因为大厂的老用户都没办法买特价机器。

后来无意间发现腾讯云一个身份证可以认证最多5个账号,新认证的账号是可以作为新用户买特价机器的,且这些账号可以销户重来,理论上可以实现无限循环,就是可能每次都需要搬家。

所以我直接开了新身份重新入手了一太2c2g4m50g的轻量云机器,今天恰好有时间,索性就把家搬了。

其实搬家这个事已经盘算了好些日子了,新机器是23年10月27号便下手购置的,明日复明日拖到今天才算开始落地,有时候对自己这拖沓性格恨铁不成钢无可奈何。

不过,也是因为这VPS搬家的麻烦程度和现实世界搬家也并无太大区别了,这三年倒腾添置的零零碎碎一大堆,好在之前就担心过这个问题,所以后来几乎都是用docker起的服务,数据文件和衣柜里的衣服一样基本上都大致堆在了一起,这些核心的东西倒是不会出太大的错(好像还是太乐观了)。不过最担心的就是那种几年前弄的小东西,当时临时弄了一下,然后放在某个很理所当然的小角落,今天搬家就给遗忘了,不过已经做好搬过去后大小问题不断的心理准备了。

好了,闲话不多说,正式开始。

最简单的办法

其实最好的搬家办法是用腾讯云的系统镜像服务直接整个服务器做个镜像共享给新服务器作为安装镜像使用然后将域名对应的A记录做一下修改即可无损搬家

不过这个上面有个腾讯挖的坑:新VPS的系统盘要大于等于之前服务器的系统盘我当时还不知道是咋回事,明明系统镜像制作、共享都成功了,为啥新机器那边不显示,后来还是问客服才知道的​,总结如下:

  • Q:怎么重装系统后不能选择其他账号共享的镜像?
  • A:稍等,帮您看看....。不好意思久等了,因为您的的镜像是60G的,新机器的系统盘容纳不下,所以无法使用。
  • Q:那我可以单独买10G云硬盘再使用吗?
  • A:您好,不可以,轻量云无法单独升级系统盘。
  • 然后我就去查了一下升级费用...,我淦,三年要多出差不多600块钱

还是你马爸爸会玩。

整理思路

简单的方法行不通就只能手动搬家了,为了避免问题,这次搬家也琢磨了半个月,最后确定的方案是依据在使用的服务的主次来分优先级,大致思路如下:

  1. 对新服务器的安全优化
  2. 迁移所有基础服务:MySQL、Nginx等等。
  3. 重新部署acme.sh证书服务。
  4. 迁移主域名下 1900.live 的主要服务「博客」,如果迁移失败基本上算是和互联网断联了。
  5. 迁移子域名下 *.1900.live 的其他服务,如 Umami统计服务lx-sync洛雪歌单同步服务memos笔记服务 等等,这些服务即便没有正常迁移也不会对访问有很大的影响。

安全优化

💡
如果客户机想通过SSH密钥登录VPS需要将公钥写入 authorized_keys 文件:cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys ,并且客户端需要持有私钥文件已做验证。

目前我只对SSH登录方面做了相关的优化。

  • 修改SSH端口位高位端口
    1. 以root用户身份登录到VPS服务器。
    2. 打开SSH配置文件(一般为/etc/ssh/sshd_config
    3. 找到并修改配置文件中的 Port 行,将端口号更改为您想要的高端口号(建议选择大于1024的端口号)
  • 添加新的非ROOT用户,并添加到sudo组
    1. 以root用户身份登录到VPS服务器
    2. 使用以下命令创建一个新用户 adduser newuser
    3. 将新用户添加到sudo组 usermod -aG sudo newuser
  • 禁用密码登录、Root登陆
    1. 打开SSH配置文件(一般为/etc/ssh/sshd_config
    4. 找到 PermitRootLogin 修改为 no 禁用Root登录
    3. 找到 PasswordAuthentication 修改 no 禁用密码登录
    5. 保存并关闭文件,然后重新启动SSH服务 systemctl restart sshd

开始搬家

一、 MySQL

之前的MySQL是本地安装的,这次想用Docker起,然后老机器那边把数据dump出来,新服务器这边导入即可,docker-compose文件如下:

version: '3'
services:
  mysql:
    container_name: mysql
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - 3306:3306
    volumes:
      - /data/mysql-data/data:/var/lib/mysql
      - /data/mysql-data/config:/etc/mysql/conf.d
    network_mode: "host"
💡
这里遇到过一个坑,在拉mysql的时候挂载目录用了 ~/data/mysql-data 这种格式,后来发现数据没有出现在设定的目录中,折腾了好久才发现原来是用的 sudo 执行的docker命令,被认为是root用户,文件跑到/root/目录下去了,后来还去v站提了问 用 docker 创建 mysql,数据文件在那里呢?
最后总结,在docker中写路径,一定要用绝对路径,不然会出现很多莫名奇妙的问题。

拉好容器后将老机器dump下来的Ghost博客数据文件 backup.sql 复制进入容器,然后进入容器登录mysql执行导入操作。

# 将数据文件复制到容器内部根目录
sudo docker cp backup.sql mysql:/backup.sql
# 进入容器内
sudo docker exec -it mysql bash
# 用root登录mysql,并将数据文件导入
mysql -u root -p < /backup.sql

因为dump下来的数据没有用户信息,所以需要自己根据Ghost那边的数据库账号信息创建:

#第一行:创建用户
#第二行:设置访问权限和登录host,%符号是任意都可以登录,可以根据需要换成127.0.0.1
#第三行:刷新权限
CREATE USER 'ghost-user'@'%' IDENTIFIED BY 'yourpassword'; 
GRANT ALL PRIVILEGES ON ghost_db.* TO 'ghost-user'@'%'; 
FLUSH PRIVILEGES;

二、Ghost博客

之前Ghost博客就是用的Docker起的,所以起容器没啥大问题。

先将老服务器上的Ghost容器内的数据文件全部下载下来,并传到新服务器上,并复制以前的docker-compose配置文件过来,然后up即可,配置文件如下:

version: '3.1'

services:
  ghost:
    container_name: ghost
    image: ghost:latest
    restart: always
    ports:
      - "2306:2306"
    environment:
      server__host: "127.0.0.1"
      server__port: 2306
      
      portal__url: "https://npm.webcache.cn/@tryghost/portal@~{version}/umd/portal.min.js"
      sodoSearch__url: "https://npm.webcache.cn/@tryghost/sodo-search@~{version}/umd/sodo-search.min.js"
      sodoSearch__styles: "https://npm.webcache.cn/@tryghost/sodo-search@~{version}/umd/main.css"
      comments__url: "https://npm.webcache.cn/@tryghost/comments-ui@~{version}/umd/comments-ui.min.js"
      comments__styles: "https://npm.webcache.cn/@tryghost/comments-ui@~{version}/umd/main.css"
      
      logging__level: "error"

      # 配置事务邮件
      mail__transport: SMTP
      mail__options__service: Mailgun
      mail__options__auth__user: "noreply@1900.live"
      mail__options__auth__pass: "testb0e79eb0b21b5e5757160c9-af778b4b-f76ed900"

      
      # see https://ghost.org/docs/config/#configuration-options
      # 配置数据库
      database__client: mysql
      database__connection__host: "127.0.0.1"
      database__connection__port: 3306
      database__connection__user: "ghost-uset"
      database__connection__password: "yourpassword"
      database__connection__database: "ghost_db"

      # 配置又拍云图床插件
      storage__active: "ghost-upyun-store"
      storage__ghost-upyun-store__bucket: "blog"
      storage__ghost-upyun-store__operator: "ghost"
      storage__ghost-upyun-store__password: "XHVtAfAzp"
      storage__ghost-upyun-store__domain: "https://test.1900.live"
      storage__ghost-upyun-store__prefix: "assets/"
      storage__ghost-upyun-store__folder: "YYYY/MM/D"
      storage__ghost-upyun-store__suffix: ""

      # this url value is just an example, and is likely wrong for your environment!
      url: https://1900.live
      # contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
      #NODE_ENV: development
    volumes:
      - /home/user/ghost-data:/var/lib/ghost/content
    network_mode: "host"
💡
我迁移的时候Ghost可以连上MySQL,但是一直显示 Access denied for user 'ghost-user'@'127.0.0.1' (using password: YES) ,提示这个说明已经能访问数据库了,有可能是密码错误!我当时以为是网络有问题,走了错误的方向,研究了一早上 Docker 的自定义网桥设置,最后才发现原来是自己密码设置错误...,真的低级!

三、Nginx服务

在这个地方卡了我很久。

和MySQL一样,我Nginx之前也是安装在本地,所以在新家这边我也打算直接用Docker来运行,但是在实际操作过程中遇到了很多问题,同样无法解决,也在V2ex上发了求助帖:我又来了,还是 docker 的问题: docker 起的 nginx,老是提配置文件打不开。 多数大佬都建议这种基础服务不要用docker,避免出现一些路径、端口等莫名其妙的问题。

所以最后还是使用了本地安装,不过在实际安装后发现好像并没有那么复杂:

  1. 更新系统: sudo apt update
  2. 安装nginx: sudo apt install nginx
  3. 启动nginx: sudo systemctl start nginx
  4. 开机启动: sudo systemctl enable nginx

完成后将老服务器上的 snippets 文件夹内的文件,sites-available 文件夹下的站点配置文件复制到新服务器即可。

另外,此时可能无法直接使用 nginx -s reload 等命令管理nginx服务,可进行以下操作:

  1. 通过 whereis nginx 找到nginx的安装位置,我这边是在 /usr/sbin/nginx
  2. 编辑: vim.bashrc
  3. 在文末加上: ​export PATH=$PATH:/usr/sbin
  4. 是环境变量生效 source ~/.bashrc

四、acme.sh证书服务

详细教程可以看我之前的教程:全站 HTTPS 【完】:acme.sh 泛域名证书生成和配置 ,现在都还是很好使。

然后将域名的DNS记录修改为新服务器IP即可。

结束

至此博客已顺利的完成了迁移,其他子域名服务多是Docker版本的,只需要将对应的数据文件拷贝过去,通过docker-compose文件重新拉起即可,还是十分方便的。

虽然看起来文章很短,但是实际整个博客迁移过程花了我两天。

如果不是因为我平时在日常使用的过程中已经有意识的对系统产生的数据做了大致归拢汇总,不至于在真的要要搬家的时候茫然无措、丢三落四,否则整个迁移过程恐怕会更加难缠。