主机商涨价或跑路怎么办?基于 Docker 与 Restic 的 VPS 5 分钟无缝搬家实战

容器化 + 增量加密备份,让 VPS 搬家从折腾大半天变成 5 分钟切 DNS。手把手讲 docker-compose 统一管理与 Restic 备份到 S3/MinIO。

一、谁还没被商家坑过

买过便宜国外 VPS 的都懂:今天续费翻倍,明天发邮件说「我们退出这个机房了」,后天论坛里传商家卷款跑路。真到那一刻,最要命的不是钱,而是你机器上跑着的东西——博客、监控、RSS、密码库、几万个文件。传统搬家怎么搞?SSH 上去一个个看配置文件、导数据库、改 Nginx、scp 传文件,运气不好折腾大半天还漏了东西,网站停摆一两天。

其实只要提前用「云原生」的思路布好局,搬家可以快到让你怀疑人生:新机器装好 Docker,拉一下镜像,还原一份加密备份,改一条 DNS 解析,5 分钟服务满血复活。核心就两件事:应用全部容器化、数据全部可备份。下面手把手来。

我见过最惨的案例,是有人把博客和数据库直接装在系统里,三年没备份,结果商家跑路,三年文章全没了。后来他学乖了,所有东西装进 Docker,配好 Restic 每天自动加密备份到 Cloudflare R2,上个月从一家涨价商家搬到另一家,前后不到十分钟——喝口水的功夫,域名解析一改,博客就搬新家了。这篇就是把他的做法拆开讲给你听。

二、传统搬家的三大痛点

  • 环境对不上:老机器是 Ubuntu 20.04 + PHP 7.4,新机器是 Debian 12 + PHP 8.2,依赖版本一变,程序直接报错,排查半天。
  • 数据库最麻烦:MySQL/PostgreSQL 不能简单 scp 数据目录,得先 dump 成 SQL 再导入,字符集、权限稍不对就乱码。
  • 配置散落一地:Nginx 在 /etc/nginx,证书在 /etc/letsencrypt,脚本在 ~/,环境变量记在脑袋里——迁移时永远少一两样,上线就 502。

这三件事的本质,是「状态」和「环境」混在一起了。容器化就是把它们拆开。

三、云原生搬家思维:all in docker-compose

正确姿势是:所有应用都用 docker-compose 管,每个项目一个目录,里面三件套——docker-compose.yml.env、数据目录(volume 映射)。这样「应用怎么跑」是一份代码,「数据是什么」是一堆文件,「密码在哪」是 .env。搬家时代码和配置跟着 Git 走,数据跟着备份走。

一个标准项目长这样:

/opt/stacks/
├── proxy/
│   ├── docker-compose.yml
│   ├── .env
│   ├── data/
│   └── letsencrypt/
├── rss/
│   ├── docker-compose.yml
│   ├── .env
│   └── data/
└── notes/
    ├── docker-compose.yml
    └── data/

1)用 volume 把数据落盘。 容器本身是一次性的,真正值钱的是挂载出来的目录。compose 里这么写:

services:
  freshrss:
    image: freshrss/freshrss:latest
    restart: unless-stopped
    mem_limit: 128m
    volumes:
      - ./data:/var/www/FreshRSS/data
    env_file:
      - .env

2)用 .env 管密钥,别写死。 数据库密码、API Key 全放 .env,compose 用 env_file${VAR} 引用。搬家时 .env 一复制就位,零改动。

# .env
DB_USER= freshrss
DB_PASS= 一串强密码
TZ= Asia/Shanghai

这样设计好后,你的「服务定义」就彻底和环境解耦了——这才是能 5 分钟搬家的根基。

四、备份才是搬家的底气:Restic 增量加密

光容器化还不够,数据得有份「异地加密备份」。推荐 Restic:开源、增量、去重、加密,一条命令备份到各种后端(S3、MinIO、Backblaze B2、Cloudflare R2、Wasabi 都行)。增量意思是第二次备份只传变化的部分,又快又省流量。

先装(Debian/Ubuntu):

sudo apt install -y restic

配置环境变量,把仓库地址和密码交给它。注意 RESTIC_PASSWORD仓库加密密码,丢了谁都解不开备份,务必记牢:

export AWS_ACCESS_KEY_ID=你的S3_KEY
export AWS_SECRET_ACCESS_KEY=你的S3_SECRET
export RESTIC_REPOSITORY=s3:https://s3.example.com:9000/restic
export RESTIC_PASSWORD=一段超强仓库密码

嫌每次敲麻烦,把这些写进 ~/.restic-env,用时 source ~/.restic-env 即可。接着初始化仓库(只做一次):

restic init

备份整个 stacks 目录(增量,秒级):

restic backup /opt/stacks

想确认备份了啥,看快照列表:

restic snapshots

恢复也一行搞定,把最新快照还原到指定目录:

restic restore latest --target /opt/restore

平时用 cron 让它每天自动跑(先 source 环境变量):

0 4 * * * source ~/.restic-env; restic backup -q /opt/stacks

备份攒久了会占空间,记得定期清理旧快照。Restic 的 forget 配合 --prune 能按策略删除并回收空间:

restic forget --keep-daily 7 --keep-weekly 4 \
  --keep-monthly 6 --prune

意思是保留最近 7 天每天一份、4 周每周一份、6 个月每月一份,其余删除并真正回收数据块。把这条也丢进 cron 每周跑一次,备份仓库就不会无限膨胀。

重要提醒:备份别放在同一台 VPS 上,那等于没备(机器没了备份也没了)。要么用 Cloudflare R2 / Backblaze B2 这种对象存储(R2 出站免费、B2 存便宜),要么在另一台机器自建 MinIO。MinIO 一行 docker 就能起:

services:
  minio:
    image: minio/minio:latest
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=changeme123
    volumes:
      - ./minio-data:/data

然后 RESTIC_REPOSITORY=s3:http://内网IP:9000/restic 指过去就行。数据库这类有状态服务,备份前最好停一下容器保证一致性,或者先 mysqldump 出 SQL 再备份。

五、搬家实战:5 分钟无缝切换

假设你已经按上面布好局,现在要从旧商家搬到新买的 RackNerd / Vultr。步骤如下:

第 1 步:旧机器先做一次最新备份。

source ~/.restic-env
restic backup /opt/stacks

第 2 步:新机器装 Docker。

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

第 3 步:把 compose 和 .env 传过去。 这些文件小,scp 秒到:

scp -r /opt/stacks user@新IP:/opt/
scp ~/.restic-env user@新IP:~/

第 4 步:新机器还原数据。 先建好目录,再 restic 还原到对应位置:

ssh user@新IP
source ~/.restic-env
restic restore latest --target /opt/stacks

第 5 步:一键拉起全部服务。

cd /opt/stacks/proxy && docker compose up -d
cd /opt/stacks/rss && docker compose up -d
cd /opt/stacks/notes && docker compose up -d

如果镜像还在拉,可以先 docker compose pull 预拉取。反代的证书(letsencrypt 目录)也跟着 .env 和 data 一起备份还原了,所以 HTTPS 直接生效,不用重新申请。

第 6 步:改 DNS,切流量。 提前把域名 TTL 调小(比如 300 秒),搬家前改 A 记录指向新 IP。等生效,旧机器就可以关机了。全程用户侧最多感知一次几十秒的解析切换,服务基本无感。

搬家前后用 docker pscurl -I https://你的域名 验一下,确认返回 200 就大功告成。

六、把停机时间压到最低的 3 个技巧

  • 双机并行:新机器先 docker compose up -d 跑起来,确认数据还原正确、页面能开,再切 DNS。切错了随时把 DNS 指回旧 IP。
  • 数据库一致性:对有写入的数据库,搬家前在旧机 docker compose stop db 停写,做最后一次备份,再还原,避免还原出「半成品」数据。
  • 证书别重签:Let's Encrypt 证书目录一起备份还原,新机直接复用,省去重新校验域名的等待,也避免频繁申请被限流。

七、不想敲命令?Duplicati 图形版备选

如果你不爱命令行,Duplicati 是个带网页界面的备份工具,同样支持增量加密备份到 S3/MinIO/FTP/OneDrive,点点鼠标设好计划任务就行,底层思路和 Restic 一样。但它吃内存稍多(空闲 ~50MB),低配机可以和主服务分开跑。真正省钱省心还是 Restic + cron。

八、搬家清单(照着打钩)

  • ✅ 所有应用都在 docker-compose 里,数据用 volume 落盘;
  • ✅ .env 管密码,没硬编码在 compose;
  • ✅ Restic 已 init,每天 cron 增量加密备份到异地;
  • ✅ 搬家前做一次最新备份,旧机停写数据库;
  • ✅ 新机装 Docker,scp 传 compose/.env,restic 还原数据;
  • ✅ docker compose up -d 拉起,验证 200,改 DNS(TTL 先调小)。

九、趁搬家,换个更稳的商家

搬家也是个重新选商家的好机会。挑新机器看三点:KVM 架构(才能自由开 Swap/zRAM)、年付口碑(别刚搬过去又涨价)、支持快照(万一再搬能直接快照迁移)。几个适合做「下一站」的:

  • RackNerd年付白菜价,黑五经常 1 核 1G 不到 $10/年,洛杉矶、圣何塞机房多,老牌低价代表。
  • ColoCrossing:机房遍布美欧,延迟低且稳,适合放反代和前端,做对外入口很合适。
  • CloudCone:按量计费 + 支持快照,弹性好,先开最小的机验证整套流程,顺了再长期用。
  • Vultr:按时计费、全球 30+ 机房,验证完即删不浪费钱,适合当「临时演练机」。
  • Bandwagon(搬瓦工CN2 GIA 线路对国内访问友好,贵一点但稳,想国内顺畅访问选它。

小建议:正式搬家前,先用新商家开一台最小实例,把本文流程完整跑一遍当演练,确认备份还原没问题,再正式切流量,心里最踏实。

十、常见翻车点与排查

  • 还原后 502:反代连不上后端。九成是后端没加进同一个 proxy-net 网络,或者容器名写错,docker network ls + docker logs 一看便知。
  • 证书失效 / 一直转圈:letsencrypt 目录没跟着还原,或权限不对。用 Traefik 时务必 chmod 600 acme.json
  • 数据库起不来:restic 还原后目录属主变成 root,而容器里进程用的是非 root uid。用 chown -R 1000:1000 数据目录(或对应 uid)修一下。
  • 数据对不上:restic restore 的 --target 路径必须和 compose 里 volume 映射的路径一致,否则服务读的是空目录。
  • 时间错乱、日志时间对不上:容器没设时区。在 .env 统一 TZ=Asia/Shanghai,compose 里 environment: - TZ=${TZ} 引用即可。

把这套流程固化下来,以后不管商家怎么作妖,你都能淡定地「备份 → 开新机 → 还原 → 切 DNS」,5 分钟喝茶等生效。便宜 VPS 的乐趣,不就在于随时说走就走吗?

延伸阅读

更多相关攻略推荐:【发行版选型 10】如何选择合适的 Linux 发行版VPS 装什么系统好?Ubuntu、Debian、CentOS 大白【安全基线 01】加固 SSH 与 Fail2ban【购买指南 01】新手如何选购第一台 VPS:配置/线路/支付/退款刚买的 VPS 怎么连上去?SSH 新手教程(Windows / M