使用 Docker 安装 Umami ,遇到版本升级提醒顺手就点了,结果遇到官方bug,我对docker的了解仅停留在跟着教程一步步操作的程度,结果耗费了一整天的时间解决问题,结果第二天一早官方修复了bug……又成功了消灭了一天宝贵时间。我整理了整个过程,希望对后来者有所帮助。
背景:为什么选择 Docker?
Docker 是当前非常流行的容器化技术,能够帮助用户快速部署应用程序。对于像 Umami 这样的轻量级开源网站分析工具,官方推荐通过 Docker 部署,这样可以省去复杂的环境配置,并且在理论上,升级和扩展也非常简单。当然对于小项目而言,这种技术是冗余的,如果有更简单的方案,一定不会选它。
后面是Chatgpt帮我总结的过程,用词比较幼稚,凑合看吧。
我一开始选择通过 Docker 安装 Umami 并将数据库指向 MySQL 进行存储。
问题起源:一次不经意的升级
起初,Umami 系统运行得十分稳定,但某天我注意到 Umami 官方发布了新版本,带来了多项功能优化。作为一个追求新功能的人,我决定进行升级。然而,这次升级却成为了灾难的开端:
- 升级后程序无法运行升级后,我的 MySQL 数据库连接失效,Umami 容器始终无法启动,提示各种错误。
- 尝试回退失败我试图将 Umami 回退至旧版本,但即便切换至旧版镜像,问题依然存在。原来,官方新版本某些不兼容改动已经“侵入”到我的数据环境中,导致旧版无法正常运行。
- 时间不断被浪费在反复尝试重新部署和切换镜像的过程中,我意识到:我从未备份过容器的镜像与数据库。即便有本地的源代码,根本没有参与容器运行,因为容器始终是从官方拉取最新镜像。
问题分析:容器镜像与本地源码的关系
在此次升级中,我一直以为本地下载的 Umami 源代码是容器运行的基础,但经过深入了解后发现:
- Docker 容器运行的核心是镜像本地源码只是开发过程中可用的内容,但对于 Docker 部署的项目,真正运行的是镜像里的代码。每次执行
docker-compose up
时,都会从docker-compose.yml
中定义的镜像拉取最新版本(除非指定特定版本或使用本地镜像)。 - 没有镜像备份导致无法回退我的 Umami 容器使用的是官方最新镜像,升级后,旧版本镜像可能已在官方仓库中消失。即便存在,由于升级后的数据库已被修改,旧版本镜像也无法正常运行。
解决过程:反复尝试后的临时解决方案
为了尽快恢复系统正常运行,我尝试了以下步骤:
- 切换到 PostgreSQL 数据库升级后的 Umami 对 MySQL 数据库的支持出现了 bug,官方推荐使用 PostgreSQL。因此,我调整了
docker-compose.yml
文件,将数据库切换至容器化的 PostgreSQL。 - 探索备份与恢复的可能性
- 通过
docker exec
进入容器内部,尝试直接操作数据库文件。 - 利用 Docker 的
volume
挂载功能,查找数据库的持久化路径。 - 尽管对 PostgreSQL 不熟悉,手动编辑数据未能成功,但至少了解了数据保存的位置。
- 通过
- 短期内维持现状,等待官方修复最终,我决定暂时使用 PostgreSQL 数据库运行系统,并等待官方修复 MySQL 的兼容性问题。
反思与经验:教训与经验
- 备份是关键
- 数据库备份:每次升级前,一定要导出数据库文件(如使用
pg_dump
或mysqldump
),以防数据丢失或格式不兼容。 - 镜像备份:通过
docker save
导出当前运行的镜像,这样即使官方删除了旧版本镜像,也可以通过本地镜像恢复。
- 数据库备份:每次升级前,一定要导出数据库文件(如使用
- 不要盲目升级
- 如果系统运行稳定,特别是在生产环境中,切勿随意升级。在升级前一定要阅读官方更新日志,评估升级的风险。
- 学习基本的 Docker 操作
- 理解镜像与容器的关系,掌握镜像构建(
docker build
)和容器管理(docker run
,docker-compose
)的基础操作。 - 熟悉容器化数据库的运行与备份,避免在数据损坏时无计可施。
- 理解镜像与容器的关系,掌握镜像构建(
- 容器化的优劣势
- 容器化的优点在于快速部署和隔离环境,但也带来了新的复杂性,特别是对非专业技术人员,可能需要投入更多学习成本。
未来计划:如何避免重蹈覆辙
- 搭建测试环境
- 今后在所有升级之前,先在测试环境中试运行,确认无误后再升级生产环境。
- 改用更易管理的数据库
- 如果 MySQL 在官方支持中存在问题,可以逐步熟悉 PostgreSQL 的备份与管理流程。
- 设立备份与监控机制
- 定期备份数据库与镜像。
- 利用 Docker 的日志功能,监控容器运行状态,及时发现问题。
在技术世界中,任何简单的操作背后都潜藏着复杂性。希望这篇文章能够帮助其他在 Docker 与容器化部署中遇到问题的朋友,助其少走弯路,实现事半功倍的效果。