Docker составляет аргументы времени сборки из файла - PullRequest
1 голос
/ 05 июня 2019

Я знаю о доступных заменах переменных, где я мог бы использовать .env в корне проекта, и это было бы сделано, но в этом случае я адаптирую существующий проект, где существующий .envрасположение файлов ожидается, и я хотел бы избежать необходимости иметь записи var для нескольких файлов!

См. документацию для получения дополнительной информации, и весь код доступен как WIP на docker-supportфилиал репо, но я кратко опишу проект и проблему ниже:

Структура проекта

|- 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!)

Или посмотреть все это здесь , он прекрасно работаеткстати на данный момент, но есть одна проблема с saas-app при создании образа для постановки / производства, которую я до сих пор мог идентифицировать.

выпуск

во время сборки Next.js buildsстатическая версия страниц, использующая веб-пакет для выполнения подстановки process.env, поэтому требуется, чтобы фактические возможные запущенные переменные были включены на этапе сборки докера, поэтому next.js не нужно повторностроить снова во время выполнения, а также, чтобы я мог безопасно создавать несколько экземпляров, когда требуется трафик!

Я знаю, что если во время выполнения не будут отправлены те же самые переменные, ему придется заново строить, игнорируя смысл этого упражнения, но это именно то, что я пытаюсь здесь предотвратить, если это неправильнозначения отправляются нам, а не проекту!

И мне также нужно рассмотреть управление BUILD ID в Next.js, но это в другой раз / вопрос.

Попытки

Я тестировал с включением деклараций ARG и ENV для каждой из переменных, ожидаемых приложением в Dockerfile , например:

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 не включаетэта переменная находится на ./app/.env, и я также проверил, оставив значение пустым, но оно не берется из определений env_file или enviroment, что, как я полагаю, соответствует ожиданиям.

I 'VE 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:
      ...

Вопросы

Как бы я мог добиться этого, если это возможно, но:

  1. Без объединения существующих файлов .env в один корень или необходимости дублировать переменные на несколькихфайлы.
  2. Без ручного объявления значений в файле compose или необходимости выводить их по команде, например docker-compose build --build-arg GA_TRACKING_ID=UA-xXxXXXX-X?
  3. Без необходимости COPY каждого .env файла во время этап сборки , потому что он не выглядит правильным и / или безопасным?
  4. Возможно, запрос args_file на опцию compose build опций для команды compose мне кажетсяДопустим, вы бы тоже так сказали?
  5. Или, возможно, у вас есть корневая опция в файле compose, где вы можете установить более одного .env файла для замены переменных?
  6. Или, возможно, другое решениея не вижу?Любые идеи?
  7. Я не против отправить каждый .env файл в виде config или secret , это более чистое решение, чем разделение составных файлов, кто-нибудьзапустить такой пример для производства?

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Вместо того, чтобы пытаться обойти и объединить значения в нескольких .env, рассмотрите возможность создания одного основного .env и предоставления службам API и APP наследования одного и того же корня .env?

0 голосов
/ 06 июня 2019

Мне удалось достичь компромисса, который не затрагивает ни один из существующих рабочих процессов разработки, и при этом он не позволяет app собирать без переменных env (требование, которое будет более важным для производственных сборок). ).

Я в основном решил повторно использовать внутреннюю способность docker для чтения файла .env и использовать его при подстановке переменных в файле compose, вот пример:

# 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 Я также использовал Поля расширения , чтобы гарантировать, что только правильные и действительные переменные передаются при сборке и запуске.

Это нарушает правило 1. из вопроса, но я чувствую, что это достаточно хороший компромисс, потому что он больше не опирается на другие .env файлы, которые в любом случае потенциально являются ключами разработки!

К сожалению, нам понадобится сохранить файл compose, если в будущем изменятся переменные, и этот же файл .env придется использовать для производственной сборки, но, поскольку это, вероятно, будет выполнено внешне на некоторых CI / CD, это не сильно беспокоит.

Я отправляю это, но не полностью закрываю вопрос, если кто-то еще мог бы предложить лучшую идею, я был бы очень признателен.

...