-
Umami Docker 故障排查实录:从 PostgreSQL pg_control: Permission denied 到平滑迁移到 Named Volume
这次 Umami 故障,表面上看是应用无法启动,实际上根因在 PostgreSQL 数据目录权限异常。日志中最关键的报错是 pg_control: Permission denied,说明数据库虽然识别到了旧数据目录,但已经无法正常读取核心控制文件。 这篇文章记录了我从故障出现、恢复旧数据、排查误区,到最终迁移到更稳妥的 Docker named volume 方案的完整过程。结论很直接:如果 PostgreSQL 数据目录长期使用宿主机 bind mount,在异常关机、目录权限变化、面板操作等场景下,确实更容易出现类似问题。 一、故障现象 最开始看到的 PostgreSQL 日志如下: postgres: could not find the database systemExpected to find it in the directory "/var/lib/postgresql/data",but could not open file "/var/lib/postgresql/data/global/pg_control": Permission deniedPostgreSQL Database directory appears to contain a database; Skipping initialization 同时,Umami 容器中还有这样的报错: Invalid `prisma.$queryRaw()` invocation:Raw query failed. Message: `Can't reach database server at db` 从这两类日志结合来看,可以得出一个比较清晰的判断: Umami 并不是第一故障点 PostgreSQL 先启动失败 Umami 随后因为连接不上数据库而报错 也就是说,这本质上是一次数据库层问题,而不是 Umami 应用本身的问题。 二、问题根因分析 我原本的 PostgreSQL 挂载方式是这样的: volumes: - ./postgres-data:/var/lib/postgresql/data 这属于典型的 Docker bind mount,也就是把宿主机目录直接映射进容器。 这种方式的优点是直观,目录可见、便于备份和手工操作;但缺点也很明显: PostgreSQL 对目录权限和属主要求严格 宿主机目录一旦被修改权限、改属主,或者受到面板、脚本、异常关机影响 容器就可能无法读取 pg_control 一旦 pg_control 不可读,数据库会直接拒绝启动 这次的核心问题,本质上就是: PostgreSQL 数据目录仍然存在,但容器进程已经没有权限正常读取关键数据库文件。 三、第一步修复:先把旧库救活 遇到这类问题时,最重要的不是立刻删卷重建,而是先确认旧数据是否还在。 从后续日志里可以看到类似信息: database system was interrupted database system was not properly shut down; automatic recovery in progress database system is ready to accept connections 这说明: 数据库之前经历过异常中断 但数据本身未必已经损坏 只要目录权限恢复正常,PostgreSQL 有机会自动恢复 所以我第一步做的不是迁移,而是先修复旧数据目录权限,把原有数据库拉起来。 修复思路大致是: 停掉容器 对旧数据目录重新执行 chown 和 chmod 重新启动数据库 观察 PostgreSQL 是否自动完成恢复 这一步成功后,旧数据恢复正常,Umami 页面数据也重新出现。这说明问题主要在目录权限,而不是数据库内容损坏。 四、为什么不应该止步于“先能跑起来” 虽然旧库恢复成功了,但这并不代表风险已经解除。 如果继续沿用 bind mount,把数据库文件直接放在宿主机目录里,那么类似问题后面仍然可能再次出现,尤其是在这些场景下: VPS 异常断电 面板或脚本误改目录权限 手动操作数据目录 宿主机挂载状态变化 文件系统异常 所以我后面的目标就变成了: 在确认旧数据完整的前提下,把 PostgreSQL 从 bind mount 平滑迁移到 Docker named volume。 五、迁移过程中踩到的两个坑 1. 认证失败:password authentication failed 迁移初期我遇到了数据库认证报错,原因后来确认是: 修改了 POSTGRES_PASSWORD 但数据库卷并不是全新初始化的 PostgreSQL 不会自动把已有用户密码改成新的环境变量值 需要特别注意的是: POSTGRES_PASSWORD 只在数据库首次初始化时生效。 如果卷里已经有旧数据,后面再改这个环境变量,并不会自动修改数据库里已有用户的密码。 因此迁移时最稳妥的做法是: 不改数据库用户名 不改数据库密码 只改存储方式 这样可以显著降低迁移过程中的变量数量。 2. 路径错位:容器启动了,但数据“消失”了 另一个坑来自 PGDATA。 一开始我尝试引入这样的配置: PGDATA: /var/lib/postgresql/data/pgdata 但旧数据库实际上是按默认路径初始化的,数据文件原本就在: /var/lib/postgresql/data 结果就出现了一个典型问题: 旧数据还在原目录 PostgreSQL 却在 pgdata/ 子目录里重新初始化了一套新库 容器可以正常启动 但应用里看到的是一个全新的空数据库 这个问题非常隐蔽,因为从表面看服务是正常的,但实际已经连到了新库。…- 25
- 0
-
Umami 源码部署记录[非docker]
开源地址:GitHub - umami-software/umami(一个简单、快速且注重隐私的谷歌分析替代品) 在开始搭建之前,你需要做好以下准备工作: 一台服务器 宝塔面板 已安装 Node.js(版本需在 14 以上) 已安装 yarn 已安装 mysql8 接下来是详细的部署流程: 下载 Umami 源码:git clone https://github.com/umami-software/umami.git ; 安装依赖:在umami目录下运行 yarn install 命令来安装项目所需的依赖; 创建数据库及表:在你的数据库管理系统中创建一个名为“umami”的数据库,接着使用位于 Umami 源码文件夹中“umami/sql/schema.mysql.sql”路径下的建表语句来创建所需的表结构; 配置环境变量:在 Umami 文件夹内新建一个名为“.env”的文件,并在该文件中添加以下配置内容(请将其中的“账号”“密码”“数据库服务器访问地址”替换为实际的数据库连接信息):DATABASE_URL=mysql://账号:密码@数据库服务器访问地址:3306/数据库名称; 构建项目:执行 yarn build 命令来构建项目,等待构建过程完成; 更新数据库:执行 yarn update-db 更新数据库,确保数据结构与项目版本相匹配,同样等待该过程结束; 在宝塔NODE项目里新建项目来启动,Umami(默认启动端口为 3000,如果反代域名的不需要开放端口,如果IP+端口访问的请去防火墙里开放3000端口)。 项目启动后的操作 默认账号密码:admin / umami 添加网站:登录 Umami 管理后台,添加你的网站信息。 获取跟踪代码:添加网站后,获取对应的跟踪代码,并将其放置到网站的<head>标签下。 至此,Umami 的部署工作就全部完成了! 如果之前是通过 Docker 部署的 Umami,并且现在想要迁移为使用源码进行部署,可以按照以下步骤进行操作: 备份原 Docker 部署的 MySQL 数据: 登录到你的 Docker 容器中,找到 Umami 数据库所在的容器。 使用 MySQL 的备份命令(如 mysqldump)将数据库导出为一个 SQL 文件。 在宝塔面板中新建数据库:登录到宝塔面板,进入数据库管理界面。创建一个新的数据库,导入刚刚备份的数据。 重复前面的部署步骤: 完成数据迁移后,按照前面提到的源码部署步骤(第 1、2、3、4、6、7步)继续进行操作。 在第 7 步配置环境变量时,确保 .env 文件中的 DATABASE_URL 配置正确指向了你刚刚在宝塔面板中创建并导入数据的数据库。 通过以上步骤,你就可以将原本通过 Docker 部署的 Umami 迁移到使用源码部署的方式,并且保留原有的数据。 2025年11月更新 MySQL被官方抛弃了……我已经将接近100GB的MySQL数据转换了……MySQL确实不太香……- 41
- 0
-
umami mysql版本更新到2.18 check-db报错解决
升级到 2.18.0 后,Umami 由于 09_update_hostname_region 迁移失败而无法启动。 在 DB 容器内的 SQL shell 中使用以下 SQL 命令: UPDATE _prisma_migrations SET finished_at = NOW(), logs = NULL, applied_steps_count = 1 WHERE migration_name = '09_update_hostname_region'; Prisma 迁移过程中可能因数据库权限、表结构冲突或版本兼容性问题导致状态卡住。- 29
- 0


![Umami 源码部署记录[非docker]](https://img.apicdo.top/i/1/2025/09/11/cd6106d1a45f8c4175f50c3bf4da8211-1.webp)
