1Panel-dev / 1Panel-dev/1Panel
[Feature] Stop Dependent Application Containers When Restoring Database Backups to Avoid Migration Race Conditions
@wanghe-fit2cloud is already working on this.
Since Sep 14, 2026.
- Dominant language
- Go
- Stars
- 37k
- Forks
- 3.4k
- Avg merge
- 9h 16m
- Merged PRs (30d)
- 105
Description
环境
- 1Panel:
v2.2.5(stable) - 应用:sub2api(
weishaw/sub2api:0.2.3) - 数据库:PostgreSQL 18.6(1Panel 内建 postgresql 应用)
- 应用容器策略:
restart: always
问题描述
对应用执行「回退」时,1Panel 会连带还原升级前备份里的数据库 dump(sub2api.sql.gz)。但整个还原过程中,restart: always 的应用容器始终在运行、每秒重启,而该应用在启动时会自动执行数据库迁移。两者竞态,导致应用陷入无限重启循环,服务完全不可用。
复现步骤
- 安装一个「启动时自动执行数据库迁移」的应用(如 sub2api),关联 1Panel 内建数据库
- 升级该应用到一个新版本,再在面板执行「回退」
- 回退时 1Panel 还原数据库备份,但不停止应用容器
- 观察容器状态:持续
Restarting (1)
实际现象(竞态证据)
还原流程与应用启动迁移相互抢同一张 schema_migrations 表:
# PostgreSQL 日志(还原侧)
CREATE TABLE public.schema_migrations ( ... ) → ERROR: relation "schema_migrations" already exists
COPY public.schema_migrations ... FROM stdin; → ERROR: duplicate key ... (001_init.sql) already exists
ALTER TABLE ONLY public.schema_migrations ADD CONSTRAINT ... PRIMARY KEY → ERROR: multiple primary keys
关键竞态循环:
- 还原流程
DROP掉schema_migrations - 应用容器恰好在这一秒重启,
migrations_runner立刻CREATE TABLE IF NOT EXISTS schema_migrations建回一张空表 - 空表 → 应用从
001开始按文件名重放全部迁移 - 还原流程再想
COPY数据进去时,主键已被应用写入的记录占用 → 报错 - 最终
schema_migrations内容不完整,应用迁移记录与真实 schema 脱节
根因
1Panel 的应用回退把「换镜像」和「还原数据库」绑定执行,却没有先把依赖该数据库的应用容器停掉。而 1Panel 其实持有「应用 ↔ 数据库」的关联信息(应用的 docker-compose.yml / 环境变量里 DATABASE_HOST、PANEL_DB_* 等字段就是证据),只是在还原前没有用它来做停容器/加锁的保护。
期望行为
在「应用回退」或「还原数据库备份」流程中:
- 若目标数据库被某个
restart: always的应用依赖,应先 stop 该应用容器,还原完成后再 start; - 或者,至少在确认弹窗中明确警告「还原将影响正在运行的应用 X,建议先停止该应用」。
影响面
任何「1Panel 部署 + 启动时自动迁移 + restart: always」的应用(sub2api 只是一例)都会踩中;一旦触发即无限重启,且用户很难从现象直接定位到「回退流程不停容器」这个根因。
补充说明
上游 sub2api 的迁移非幂等是本次「无限重启」的直接卡点,我已单独提 issue:https://github.com/Wei-Shaw/sub2api/issues/7030 。但即便上游修复了非幂等,1Panel 这边「还原数据库前不停依赖应用」的竞态依然存在,属于独立的流程改进点,故单独提此 feature request。
期望:还原流程把「停止依赖应用」纳入标准步骤(或至少给出警告),从面板层面规避这类竞态。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.