Sub2API 从脚本安装迁移到 Docker Compose 部署流程本文档记录一次实际走通的 Sub2API 迁移流程旧服务器使用官方脚本安装配置和程序位于/opt/sub2api新服务器使用官方docker-compose.local.yml部署并从 PostgreSQL 备份恢复业务数据。适用场景旧服务器官方安装脚本部署主配置文件在/opt/sub2api/config.yaml。新服务器使用 Docker Compose 部署。备份方式Sub2API 后台“数据备份”已将 PostgreSQL 备份上传到 S3/R2文件形如sub2api_20260528_152845.sql.gz。Redis只作为缓存和锁使用通常不迁移旧 Redis 数据。一、旧服务器打包在旧服务器执行cd/opt/sub2api# 备份主配置文件cpconfig.yaml /root/sub2api-config.yaml# 备份应用本地数据目录tarczf /root/sub2api-data.tar.gz data确认旧配置中的数据库、Redis、JWT 等信息grep-nA20^database:/opt/sub2api/config.yamlgrep-nA20^redis:/opt/sub2api/config.yamlgrep-nEsecret|password|client_secret|encryption_key/opt/sub2api/config.yaml需要带到新服务器的文件/root/sub2api-config.yaml /root/sub2api-data.tar.gz R2/S3 下载下来的 sub2api_YYYYMMDD_HHMMSS.sql.gz如果不使用 R2/S3 备份也可以在旧服务器手动导出 PostgreSQLPGPASSWORD旧库密码pg_dump\-hlocalhost\-p5432\-Usub2api\-dsub2api\--no-owner\--no-acl\-f/root/sub2api.sqlgzip-f/root/sub2api.sql二、把文件放到新服务器/opt将以下文件上传到新服务器/opt/opt/sub2api-config.yaml /opt/sub2api-data.tar.gz /opt/sub2api_YYYYMMDD_HHMMSS.sql.gz示例scp/root/sub2api-config.yaml root新服务器IP:/opt/sub2api-config.yamlscp/root/sub2api-data.tar.gz root新服务器IP:/opt/sub2api-data.tar.gzscpsub2api_YYYYMMDD_HHMMSS.sql.gz root新服务器IP:/opt/三、新服务器准备 Docker Compose在新服务器执行cd/optgitclone https://github.com/Wei-Shaw/sub2api.gitcd/opt/sub2api/deploycp.env.example .envmkdir-pdata postgres_data redis_data解压旧服务器的本地数据目录tarxzf /opt/sub2api-data.tar.gz-C/opt/sub2api/deploy放入旧配置cp/opt/sub2api-config.yaml /opt/sub2api/deploy/config.yaml四、修改config.yaml编辑新服务器上的配置vi/opt/sub2api/deploy/config.yaml把旧服务器本地地址改成 Docker Compose 内部服务名database:host:postgresport:5432user:sub2apipassword:旧数据库密码dbname:sub2apisslmode:disableredis:host:redisport:6379password:Redis密码db:9enable_tls:false如果旧配置里没有固定的totp.encryption_key建议现在补上避免每次重启生成随机密钥openssl rand-hex32把输出填入config.yaml与jwt:同级totp:encryption_key:64位hex密钥注意如果旧实例之前没有固定totp.encryption_key数据库里已经加密保存的部分 secret 无法在新实例自动解密需要迁移完成后重新录入。例如系统设置里的 S3/R2Secret Access KeyChannel Monitor 里的 API Key已开启 2FA 的用户需要重新绑定或由管理员关闭后再启用五、修改docker-compose.local.yml编辑vi/opt/sub2api/deploy/docker-compose.local.yml确认sub2api服务的volumes包含这两行volumes:-./data:/app/data-./config.yaml:/app/data/config.yaml六、修改.env编辑vi/opt/sub2api/deploy/.env至少保持这些值与config.yaml一致POSTGRES_USERsub2api POSTGRES_PASSWORD旧数据库密码 POSTGRES_DBsub2api REDIS_PASSWORDRedis密码 REDIS_DB9 JWT_SECRET旧配置里的 jwt.secret TOTP_ENCRYPTION_KEYconfig.yaml 里的 totp.encryption_key如果 Redis 密码包含、^、!等特殊字符建议在.env中使用单引号包裹。七、启动 PostgreSQL 和 Redis先只启动数据库和 Rediscd/opt/sub2api/deploydockercompose-fdocker-compose.local.yml up-dpostgres redisdockercompose-fdocker-compose.local.ymlps确认sub2api-postgres和sub2api-redis都是Healthy。八、导入 PostgreSQL 备份用 R2/S3 下载下来的备份文件恢复数据库gunzip-c/opt/sub2api_YYYYMMDD_HHMMSS.sql.gz\|dockercompose-f/opt/sub2api/deploy/docker-compose.local.ymlexec-Tpostgres\psql-Usub2api-dsub2api如果.env中的数据库用户名或库名不是sub2api同步替换命令里的-U和-d。九、启动 Sub2API数据库恢复完成后启动主服务dockercompose-f/opt/sub2api/deploy/docker-compose.local.yml up-dsub2apidockercompose-f/opt/sub2api/deploy/docker-compose.local.yml logs-fsub2api正常情况下可以看到[Backup] 定时备份已启用: 0 2 * * *如果出现下面日志TOTP encryption key auto-generated说明固定的totp.encryption_key没有生效需要检查/opt/sub2api/deploy/config.yaml是否挂载到/app/data/config.yamlconfig.yaml中是否有totp.encryption_key.env中是否填了TOTP_ENCRYPTION_KEY十、迁移后检查迁移完成后检查dockercompose-f/opt/sub2api/deploy/docker-compose.local.ymlpsdockercompose-f/opt/sub2api/deploy/docker-compose.local.yml logs--tail200sub2api后台检查管理员是否能登录用户、渠道、账号、订阅是否都在系统设置是否恢复数据备份配置是否恢复R2/S3 备份是否能测试连接Channel Monitor 是否有解密失败日志如果使用 2FA确认用户能否正常登录如果 R2/S3 连接测试失败通常是旧数据库里的Secret Access Key因旧加密密钥缺失而无法解密。进入后台“系统设置 - 数据备份”重新填写Secret Access Key保存并测试连接即可。这里分享一下个人搭建的中转站https://hahacode.com十一、常见问题1.pg_dump version报错看版本应使用pg_dump--versionpg_dump version会被当成数据库名可能触发连接错误。2. 迁移后日志提示channel_monitor: decrypt api key failed说明旧库中保存的 Channel Monitor API Key 无法用当前密钥解密。进入后台重新填写对应监控项的 API Key。3. 迁移后日志提示payment encryption/signing key is not explicitly configured配置固定的totp.encryption_key后重启服务。4. Redis 数据要不要迁移通常不需要。Sub2API 主业务数据在 PostgreSQLRedis 主要用于缓存、锁和临时状态。新服务器用新 Redis 即可。5. R2 桶里有文件但后台看不到Sub2API 备份列表不是扫描 R2/S3 桶而是读取 PostgreSQL 里的settings.key backup_records。只要导入的是完整 PostgreSQL 备份备份记录就会恢复。这里分享一下个人搭建的中转站https://hahacode.com