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 命令的时候,这一行先打上,别等被坑了再回来加。

相关推荐
ZengLiangYi18 小时前
从零实现 Embedding 服务:文本转向量
人工智能·后端
星栈18 小时前
订单状态机别写散:我在 Rust CRM 里把 6 个状态收进领域模型
后端·rust·全栈
韩小兔修媛史18 小时前
SpringBoot面试八股文(持续更新)
spring boot·后端·面试
码上出头18 小时前
地理围栏从0到1:我是怎么把轮询接口从每分钟2000次干到0次的
后端
神奇小汤圆18 小时前
搞懂数据库索引:它到底帮了什么忙,又埋了什么坑?
后端
浮游本尊18 小时前
Java学习第38天 - 企业级 REST API 设计、OpenAPI 契约与接口可靠性
后端
苍何18 小时前
分享最近高频用 Agent 提效的 4 大场景
后端
Java编程爱好者18 小时前
Java后端硬核实战:用Spring AI Alibaba+Redis给LLM装上“超强记忆中枢”
后端
XovH18 小时前
Django 从 0 到 1 打造完整电商平台:下单前的准备,订单模型设计
后端