【发布时间】:2019-06-05 11:05:15
【问题描述】:
我知道可用的变量替换,我可以在项目的根目录中使用 .env 并且可以这样做,但在这种情况下,我正在调整现有项目,其中现有 .env文件位置是预期的,我想避免在多个文件上使用 var 条目!
有关更多信息,请参阅documentation,所有代码都可以在 repo 的docker-support 分支上作为 WIP 获得,但我将在下面简要描述项目和问题:
项目结构
|- root
| |- .env # mongo and mongo-express vars (not on git!)
| |- docker-compose.yaml # build and ups a staging env
| |- docker-compose.prod.yaml # future wip
| |- api # the saas-api service
| |- Dockerfile # if 'docked' directly should build production
| |- .env # api relative vars (not on git!)
| |- app # the saas-app service
| |- Dockerfile # if 'docked' directly should build production
| |- .env # api relative vars (not on git!)
或者查看here 的全部内容,顺便说一下,它目前工作得很好,但是在构建用于暂存/制作的图像时,saas-app 存在一个问题,我目前可以识别。
问题
在构建时 Next.js 使用 webpack 构建页面的静态版本来完成 process.env 替换的事情,因此它需要在 docker build 阶段包含实际最终运行的变量,因此 next.js 不需要在运行时再次重建,这样我就可以在流量需要时安全地生成多个实例!
我知道,如果在运行时没有发送相同的变量,它将不得不再次重建,这违背了本练习的重点,但这正是我在这里试图阻止的,如果发送了错误的值它在我们身上,而不是项目!
而且我还需要考虑 Next.js BUILD ID 管理,但这是另一个时间/问题。
尝试
我一直在测试是否在其 Dockerfile 上包含应用程序预期的每个变量的 ARG 和 ENV 声明,例如:
ARG GA_TRACKING_ID=
ENV GA_TRACKING_ID ${GA_TRACKING_ID}
这按预期工作,但它迫使我在docker-compose.yml 文件中手动声明它们,这并不理想:
saas-app:
build:
context: app
args:
GA_TRACKING_ID: UA-xXxXXXX-X
我不能在这里使用变量替换,因为我的根 .env 不包含这个 var,它在 ./app/.env 上,我还测试了将值留空,但它没有从 env_file 或 @987654344 中提取它@ 定义,我相信这是预期的。
我有 pastbinned 的完整输出 docker-compose config 以及存储库中的现有版本:
理想情况下,我希望:
saas-app:
build:
args:
LOG_LEVEL: notice
NODE_ENV: development
PORT: '3000'
context: /home/pedro/src/opensource/saas-boilerplate/app
command: yarn start
container_name: saas-app
depends_on:
- saas-api
environment:
...
变成:
saas-app:
build:
args:
LOG_LEVEL: notice
NODE_ENV: development
PORT: '3000'
BUCKET_FOR_POSTS: xxxxxx
BUCKET_FOR_TEAM_AVATARS: xxxxxx
GA_TRACKING_ID: ''
LAMBDA_API_ENDPOINT: xxxxxxapi
NODE_ENV: development
STRIPEPUBLISHABLEKEY: pk_test_xxxxxxxxxxxxxxx
URL_API: http://api.saas.localhost:8000
URL_APP: http://app.saas.localhost:3000
context: /home/pedro/src/opensource/saas-boilerplate/app
command: yarn start
container_name: saas-app
depends_on:
- saas-api
environment:
...
问题
如果可能的话,我怎么能做到这一点,但是:
- 无需将现有的
.env文件合并到单个根目录中,也无需在多个文件上复制 var。 - 无需在 compose 文件中手动声明值,也无需在命令中推断它们,例如
docker-compose build --build-arg GA_TRACKING_ID=UA-xXxXXXX-X? - 在build stage 期间不必
COPY每个.env文件,因为它感觉不正确和/或不安全? - 在我看来,撰写团队的
args_file撰写build选项功能请求可能是有效的,您也会这么说吗? - 或者也许在 compose 文件上有一个 root 选项,您可以在其中设置多个
.env文件用于变量替换? - 或者我没有看到其他解决方案?有什么想法吗?
- 我不介意将每个
.env文件作为config 或secret 发送,这是一个比拆分文件更清洁的解决方案,有人运行这样的生产示例吗?
【问题讨论】:
-
嗯,可能是 stackoverflow.com/a/55543513/271433 的变体,其中一个根 compose 文件包含 (mongo + mongo-express) 和一个专用于每个服务的文件,希望那时我可以使用变量替换。
-
不,不要认为它会起作用(每个服务单独的撰写文件),因为如果您查看docs.docker.com/compose/extends/…,它会说“您必须确保文件中的所有路径都相对于基础撰写文件”这可能意味着它加载的 .env 文件也将与它相关! :(
-
等等,其实是“.env 放在执行 docker-compose 命令的文件夹中(当前工作目录)。”来自docs.docker.com/compose/env-file 和来自docs.docker.com/compose/reference/overview 的“--project-directory PATH 指定备用工作目录(默认值:Compose 文件的路径)”可能允许否则!将不得不进一步调查:D
-
选项 7. from edit now 可能是最明智的选择。
标签: docker webpack docker-compose open-source next.js