Docker从文件

时间:2019-06-05 11:05:15

标签: docker webpack docker-compose open-source next.js

我知道可用的变量替换,可以在项目的根目录使用.env,但可以这样做,但是在这种情况下,我要适应现有的项目,而现有的{ {1}}文件位置是预期的,我想避免必须在多个文件上包含var项!

有关更多信息,请参见documentation,所有代码都可以在仓库的.env分支上以WIP的形式获得,但是我将在下面简要描述该项目和问题:

项目结构

docker-support

或者看整个事情here,就目前而言,它很好用,但是|- 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!) 存在一个问题,当我为到目前为止的舞台/制作图像时,我可以确定。< / p>

问题

在构建时,Next.js使用webpack来构建页面的静态版本,以实现saas-app替换,因此它需要在docker构建阶段包括最终实际运行的var,因此next.js不会需要在运行时再次重建,以便在流量需要时可以安全地生成多个实例!

我知道,如果在运行时未发送相同的变量,则必须重新构建,这违背了本练习的要点,但这正是我要在此处避免的,如果发送了错误的值这是我们的事,而不是项目的事!

我还需要考虑Next.js BUILD ID管理,但这是另一个时间/问题。

尝试

我一直在测试是否为应用程序在其Dockerfile上期望的每个变量包括ARG和ENV声明,例如:

process.env

这可以按预期工作,但是它迫使我在docker-compose.yml文件中手动声明它们,这并不理想:

ARG GA_TRACKING_ID=
ENV GA_TRACKING_ID ${GA_TRACKING_ID}

我不能在这里使用变量替换,因为我的根 saas-app: build: context: app args: GA_TRACKING_ID: UA-xXxXXXX-X 不包含此变量,它在.env上,并且我还测试了将该值保留为空,但未从{{ 1}}或./app/.env的定义,我认为这是预期的结果。

pastbinned的完整输出为env_file,其中包含存储库中的现有版本:

理想情况下,我想要:

enviroment

成为:

docker-compose config

问题

如果可能的话,我将如何实现这一目标,但是:

  1. 无需将现有 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: ... 文件合并到单个根目录中,也不必在多个文件上复制var。
  2. 无需手动在compose文件中声明值,也不必在命令中推断它们,例如 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: ...
  3. build stage期间不必.env docker-compose build --build-arg GA_TRACKING_ID=UA-xXxXXXX-X每个文件,因为感觉不正确和/或不安全?
  4. 在撰写COPY选项功能请求中,对于撰写团队来说,.env似乎是有效的,您也这样说吗?
  5. 或者在撰写文件上有一个根选项,您可以在其中为变量替换设置多个args_file文件?
  6. 还是我看不到的另一种解决方案?有什么想法吗?
  7. 我不介意以configsecret的形式发送每个build文件,这是比分割组成文件更干净的解决方案,有人在运行这样的示例进行生产吗? / li>

2 个答案:

答案 0 :(得分:1)

您可以考虑使一个主.env并使API和APP服务继承相同的根.env,而不是尝试传递和合并多个.env中的值?

答案 1 :(得分:0)

我设法实现了一个折衷方案,该折衷方案不影响任何现有的开发工作流程,也不允许 app 在没有env变量的情况下进行构建(这一要求对于生产而言更为关键构建)。

我基本上已经决定重用docker的内部功能来读取.env文件,并将其用于组成文件中的变量替换,这是一个示例:

# compose
COMPOSE_TAG_NAME=stage

# common to api and app (build and run)
LOG_LEVEL=notice
NODE_ENV=development
URL_APP=http://app.saas.localhost:3000
URL_API=http://api.saas.localhost:8000
API_PORT=8000
APP_PORT=3000

# api (run)
MONGO_URL=mongodb://saas:secret@saas-mongo:27017/saas
SESSION_NAME=saas.localhost.sid
SESSION_SECRET=3NvS3Cr3t!
COOKIE_DOMAIN=.saas.localhost
GOOGLE_CLIENTID=
GOOGLE_CLIENTSECRET=
AMAZON_ACCESSKEYID=
AMAZON_SECRETACCESSKEY=
EMAIL_SUPPORT_FROM_ADDRESS=
MAILCHIMP_API_KEY=
MAILCHIMP_REGION=
MAILCHIMP_SAAS_ALL_LIST_ID=
STRIPE_TEST_SECRETKEY=
STRIPE_LIVE_SECRETKEY=
STRIPE_TEST_PUBLISHABLEKEY=
STRIPE_LIVE_PUBLISHABLEKEY=
STRIPE_TEST_PLANID=
STRIPE_LIVE_PLANID=
STRIPE_LIVE_ENDPOINTSECRET=

# app (build and run)
STRIPEPUBLISHABLEKEY=
BUCKET_FOR_POSTS=
BUCKET_FOR_TEAM_AVATARS=
LAMBDA_API_ENDPOINT=
GA_TRACKING_ID=

查看更新后的docker-compose.yml,我也使用了Extension fields,以确保在构建和运行时仅发送正确和有效的var。

它从问题上打破了规则1.,但我觉得这是一个足够好的折衷方案,因为它不再依赖于其他.env文件,在大多数情况下,它们始终是开发的关键! >

不幸的是,如果将来vars发生变化,我们将需要维护compose文件,并且必须将相同的.env文件用于生产版本,但是因为那样可能会在某些CI / CD,不用担心。

我正在发布此信息,但尚未完全解决问题,如果其他人可以提出更好的主意,我将不胜感激。