
























记录一次因 Docker Compose 的 ${PWD} 变量在不同运行目录下解析值不同,导致 Waline 评论系统 Volume 挂载路径错误、数据库丢失的排查过程。
最近发现博客评论系统(Waline v3)的后台管理页面可以正常打开,但登录时一直提示“用户名或密码错误”。试了试密码重置功能,页面显示“请稍后再试”,也搞不定。前台评论区域也不显示已有评论,整个系统看起来像是丢了所有数据一样。
这种情况在自部署项目中不算少见,我去 GitHub 和技术社区搜了一圈,发现类似问题还真不少——大都是因为 SQLite 数据库文件被意外清空或者指向了空文件,应用启动时自动创建了空表结构,导致原有用户数据全部“消失”,所以才会出现登录失败、重置失败这些看起来莫名其妙的问题。
排查下来发现,根本原因是 Docker Compose 中 ${PWD} 变量在不同运行目录下解析出的值不同,导致 Volume 挂载路径异常。
我的 docker-compose 配置是这样的:
| |
注意这个 ${PWD}/data。${PWD} 是一个预定义的环境变量,它的值取决于你执行 docker compose 命令时所在的目录,而不是 compose 文件所在的目录。
/docker/data/waline/)→ ${PWD} 解析为 /docker/data/waline → 挂载 /docker/data/waline/data:/app/data → 数据库正常/data)→ ${PWD} 解析为 /data → 挂载 /data:/app/data → 但 /data 目录下只有一个 0 字节的空 waline.sqlite,容器读到的就是个空数据库这就能解释为什么数据“丢了”——不是文件没了,而是挂载到了错误的位置。
根据 Docker 官方文档,Compose 在解析变量时遵循以下规则:
当没有显式设置
--env-file时,Compose 会按以下顺序确定项目目录:
--project-directory如果设置了的话- 否则,第一个通过
-f/--file指定的 Compose 文件所在的目录- 否则,当前 shell 的工作目录(
PWD)
同时,环境变量优先级如下(从高到低):
docker compose run -e 命令行传入environment 或 env_file 属性中从 shell 或 .env 文件插值的变量environment 属性直接设置的值env_file 属性引用的值ENV 指令设置的值来源: Docker Docs - Environment Variables Precedence
也就是说,${PWD} 的值完全取决于你在哪个目录敲下 docker compose up。如果 compose 文件里用了 ${PWD},但每次执行的目录不固定,挂载路径就会飘忽不定,这就埋下了隐患。
我去 Waline 官方文档(waline.js.org)查了一下,确认了:
<serverURL>/ui/register | |
日志里发现了关键线索:
| |
这些 404 错误说明数据库中的管理相关表不存在或为空,API 路由找不到对应的数据。
| |
正确的数据库里有 4 个用户(1 个管理员 + 3 个访客),而 /data/waline.sqlite 虽然存在但是空的。
| |
404 进一步确认了数据库虽然加载了,但没有用户数据。
| |
看到 volumes 里用的是 ${PWD}/data:/app/data。${PWD} 在执行 docker compose up 时会被替换为当前 shell 的工作目录。如果之前在某次操作时不在 compose 文件所在目录执行命令,${PWD} 就解析到了其他路径,Volume 也就挂载到了错误的地方。
找到原因就好办了。先在正确目录下执行一次,确保 ${PWD} 解析到正确路径:
| |
验证一下:
| |
数据全在,问题解决。后台地址还是 https://<博客域名>/ui/,用管理员邮箱密码登录就行。
${PWD}:${PWD} 依赖执行命令时的当前目录,不够稳定。更推荐用相对路径(Compose 会自动以 compose 文件所在目录为基准),或者用 .env 文件固定变量值。docker logs 是最直接的线索来源,比瞎猜效率高多了。此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。