docker compose 漏一个参数全失效

docker compose 漏一个参数全失效

compose 文件早就摆好了,镜像也拉过,我以为就差一行 up -d:

bash 复制代码
docker compose -f compose/_base.yml -f compose/openbao.yml up -d

回车,容器起来了,健康检查也过了。打开管理后台一登 --- 密码不对。

我对着 .env 看了好几遍,密码字符串都对啊。换浏览器、清 cookie、容器重启一遍,还是不行。

服了。

进容器看环境变量:

bash 复制代码
docker exec -it openbao env | grep PASSWORD
OPENBAO_ADMIN_PASSWORD=

值是空的。

.env 里明明写了 OPENBAO_ADMIN_PASSWORD=xK9f2... 一大串,容器里怎么变空了?

一行 warning 都没有的失败

我把 compose 命令重新跑了一遍,这次盯着输出:

css 复制代码
[+] Running 1/1
 ✔ Container openbao  Started

没有任何 warning。容器照样起,只是它认为 OPENBAO_ADMIN_PASSWORD 这个变量值就是空字符串。

把 .env 临时塞了个错的密码,再跑,期望它至少要报错让我知道值在哪一步丢的。结果还是这副"成功"的样子。

我开始怀疑 compose 没读 .env。这个文件就放在我执行命令的目录下,按理说默认会读的。

直到翻 docker compose 文档看到这一段:

The .env file is loaded from the project directory. The project directory is determined by --project-directory, then by the parent directory of the first compose file specified, then by the current working directory.

我一脸懵。我用了 -f compose/_base.yml -f compose/openbao.yml,第一个 compose 文件的父目录是 compose/。所以 compose 把 project directory 推断成 compose/,而 .env 在它上一级的项目根。compose 在 compose/.env 找不到东西就当没有,展开 ${OPENBAO_ADMIN_PASSWORD} 直接给我个空串。

整个过程零 warning。

一个参数的事

修法是加 --project-directory .,显式告诉 compose 项目根在哪:

bash 复制代码
docker compose --project-directory . `
  -f compose/_base.yml `
  -f compose/openbao.yml up -d

加上这一行,.env 立刻被读到,密码也对了。

我之后所有的 compose 命令模板都套这个:

css 复制代码
docker compose --project-directory . -f ... -f ... up -d

哪怕只用一个 -f,我也加。免得下次某个组件文件挪了位置,推导路径又跑偏。

为什么这事让我搞了一晚

回头看,有几个让我跑偏的地方:

第一,compose 不报错。

${VAR} 展开为空在 compose 里是合法行为。如果 yml 里写的是 image: ${IMAGE}:${TAG},展开后会变成 image: :,这个 docker 还会接,只是拉不到镜像。但密码这种,展开成空字符串就直接以空密码塞进环境变量,容器自己也不知道这是错的。

第二,我以为 .env 是默认读的。

只在最简单的 docker compose up(单 compose 文件,没 -f)情况下,.env 才"看起来是默认读的"。一旦多 -f,project directory 推导就开始按文件位置走。文档里写得清楚,但谁会在加新组件的时候去读 docker compose 的"project directory inference rules"。

第三,压根没意识到要往这个方向查。

整个上午我在反复怀疑 .env 的格式、密码里有没有特殊字符、容器自己有没有把变量吃掉。绕了一大圈才回到 "compose 根本没读 .env"。

一行参数,记一下

css 复制代码
docker compose --project-directory . -f xxx.yml -f yyy.yml up -d

下次写 compose 命令的时候,这一行先打上,别等被坑了再回来加。

相关推荐
她的男孩16 分钟前
同一个接口,为什么销售只看到自己的订单?我拆了 681 行数据权限拦截器的源码
java·后端·架构
元界metalite18 分钟前
SpringBoot接口通用响应对象设计 - 一个 Resp 管理五种责任
后端
对象存储与RustFS21 分钟前
把 RustFS 跑在 Kubernetes 上:官方 Helm Chart 从单机到分布式
后端·rust·开源
SimonKing38 分钟前
将cURL 命令直接变成 Java 代码?用JQuick-Curl搞起来
java·后端·程序员
大牧师41 分钟前
Nest.js 微服务入门教程
开发语言·javascript·后端·微服务·node.js·nest.js·nest
凤山老林1 小时前
企业级文件服务中台:Spring Boot 集成 MinIO 实现分片存储、生命周期管理与多租户隔离
java·spring boot·后端·minio·文件服务
IT_陈寒1 小时前
Redis的订阅丢失消息?你可能忘了这个配置
前端·人工智能·后端
好好沉淀1 小时前
巧用 Set 去重与复合键:高效统计分组内不重复元素的数量
java·spring boot·后端
FfHUCisI1 小时前
Golang 函数调用的瞬间:栈帧、拷贝栈与逃逸分析
开发语言·后端·golang