跳到主要内容
轻盈的鱼

← 返回归档

1Panel 跨机迁移 PostgreSQL:不要用面板导入

日期:分类:linuxguide标签:PostgreSQL1PanelDockerpgvectorPayload CMS

1Panel 自带的「导入数据库」对跨机、单库迁移并不稳:面板走的是 SQL 文本导入,容易撞编码、角色、ACL,也吃不消 -Fc 自定义格式。更可靠的做法是:在源机 docker execpg_dump,把 dump 文件拷到目标机,再 pg_restore 进空库。stdout / stdin 直接落到当前目录,不用 docker cp

本文以 Crispy(Payload CMS + PostgreSQL)单库为例,流程适用于任何 1Panel 托管的 PostgreSQL 容器。

先记住三条坑

  • 不要加 -t。 docker exec -it 会把 TTY 混进管道,破坏 -Fc 自定义格式的二进制 dump。只用 -i
  • 1Panel 容器里通常没有 postgres 角色。 -U 必须用该库自己的用户(1Panel 数据库列表里的用户名),不要想当然写成 -U postgres
  • 目标机先建空库和用户,再 restore。应用连接串用目标机的用户名和库名,不要沿用源机凭据。

查容器名:

1docker ps --format '{{.Names}}' | grep -i postgres

常见名字类似 1Panel-postgresql-xxxx

源机导出

在要保存 dump 文件的目录执行:

1docker exec -i 1Panel-postgresql-xxx \
2 pg_dump -U 源库用户 -O --no-acl --encoding=UTF8 -Fc 源库名 \
3 > crispy.dump

参数含义:

  • -O / --no-owner:不绑定源机 owner,目标机用户才能顺利接管对象。
  • --no-acl:丢掉源机 ACL,避免 restore 时因角色不存在而失败。
  • -Fc:自定义压缩格式,体积小、可并行 restore,也方便后面用 -T 跳表。
  • --encoding=UTF8:避免中文内容在跨机时编码漂移。

如果报 role "postgres" does not exist,说明你仍在用 -U postgres。改用该库用户。管理员名也可以从容器环境变量确认:

1docker inspect 1Panel-postgresql-xxx \
2 --format '{{range .Config.Env}}{{println .}}{{end}}' | grep POSTGRES_USER

向量表、前台缓存、权限缓存都可以重建,导出时可以跳过以缩小 dump:

1docker exec -i 1Panel-postgresql-xxx \
2 pg_dump -U 源库用户 -O --no-acl --encoding=UTF8 -Fc \
3 -T content_embeddings -T frontend_cache_entries -T authz_cache \
4 源库名 \
5 > crispy.dump

crispy.dump 拷到目标机(scp 或 1Panel 文件上传均可)。

目标机导入

先在 1Panel 建好空库和用户,再在 dump 所在目录执行:

1docker exec -i 1Panel-postgresql-xxx \
2 pg_restore -U 目标库用户 --no-owner --no-acl --if-exists -d 目标库名 \
3 < crispy.dump

空库上出现 DROP ... does not existrole "user_xxx" does not exist 可以忽略——--if-exists 和跨机角色差异都会产生这类噪声。以行数为准,不要以 restore 的 stderr 是否干净为准。

1docker exec -i 1Panel-postgresql-xxx \
2 psql -U 目标库用户 -d 目标库名 \
3 -c 'SELECT count(*) FROM posts; SELECT count(*) FROM pages; SELECT count(*) FROM media; SELECT count(*) FROM users;'

把核心业务表的行数和源机对一下。对得上,库就算迁完了。

应用侧还要改两处

数据库只是一半。Crispy / Payload 的连接串必须换成目标机用户和库名DATABASE_URI 或等价环境变量)。生产环境保持 DATABASE_PUSH=false,用 pnpm cli db:migrate 管 schema,不要在新机上对已 restore 的库做 schema push。

媒体文件不在 PostgreSQL 里。本机上传目录需要另拷;若已改走 S3 / 对象存储,确认新机的 bucket 与凭证即可。

pgvector:默认镜像往往没有

1Panel 常用的 PostgreSQL 镜像经常没装 vector 扩展。分两种情况:

不需要语义搜索: .envPGVECTOR_ENABLED=false,应用启动时跳过向量相关逻辑。

需要语义搜索: dump 时用 -T content_embeddings 跳过旧向量;新机装好 pgvector、确认扩展可用后,再重建:

1pnpm cli ai:backfill

不要指望把源机的 content_embeddings 原样 restore 进一台没有 vector 的目标库——扩展不存在时,整次 restore 会卡在这张表上。

小结

面板导入留给同机、小 SQL 文件。跨机单库迁移走这条链路:

  1. 源机 docker exec -i + pg_dump -Fc-U 用库用户,不要 -t
  2. *.dump 到目标机
  3. 目标机建空库,pg_restore --no-owner --no-acl
  4. posts / pages / media / users 行数验收
  5. 改连接串、拷媒体或切 S3;按需处理 pgvector

做完后再启动应用。库是空的、角色对不上、向量扩展缺失,这三件事占了 1Panel 跨机翻车的绝大多数。

版权信息

日期2026/08/27
协议CC BY-NC-SA 4.0 转载请注明出处
评论

暂无评论,来抢沙发吧。