Внедрить переменную env в стадию сборки изображения - PullRequest
1 голос
/ 11 января 2020

Работа над конвейером CI / CD для Django API. Мне нужно ввести переменную окружения на этапе сборки, чтобы успешно создать образ.

  • python manage.py collectstatic запускается в Dockerfile при создании образа
  • collectstatic для запуска
  • SECRET_KEY пуст на этом этапе, потому что он считывается с os.environ['SECRET_KEY]
  • Поскольку он пуст, сборка завершается неудачно
  • Таким образом, мне нужно настроить окружение так, чтобы эта переменная была *1019*

У меня проблемы со сборкой, поэтому хотел посмотреть, сможет ли кто-нибудь мне помочь.

Вот что у меня есть:

Azure Трубопровод

enter image description here

azure -pipelines.yml

trigger:
  branches:
    include:
    - master

resources:
- repo: self

variables:
  # Container registry service connection established during pipeline creation
  secretKey: $(SECRET_KEY)

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build and push stage
  jobs:  
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - bash:
      env:
        SECRET_KEY: $(secretKey)
    - task: Docker@2
      displayName: Build and push api image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)-api
        dockerfile: $(dockerfilePath)/api/Dockerfile
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
    - upload: manifests
      artifact: manifests

Dockerfile

FROM python:3.7-slim
ENV PYTHONUNBUFFERED 1
WORKDIR /app
EXPOSE 5000
COPY requirements*.txt ./
RUN pip install -r requirements.txt
COPY . .
RUN python manage.py collectstatic
CMD ["gunicorn", "-b", ":5000", "--log-level", "info", "config.wsgi:application"]

Журнал сбоя сборки (вероятно, не помогает, потому что я знаю, почему это не удалось ... SECRET_KEY не в env vars)

Step 8/18 : RUN python manage.py collectstatic
 ---> Running in 1f42a5c062aa
Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 325, in execute
    settings.INSTALLED_APPS
  File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 79, in __getattr__
    self._setup(name)
  File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 66, in _setup
    self._wrapped = Settings(settings_module)
  File "/usr/local/lib/python3.7/site-packages/django/conf/__init__.py", line 157, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/app/config/settings.py", line 26, in <module>
    SECRET_KEY = os.environ['SECRET_KEY']
  File "/usr/local/lib/python3.7/os.py", line 679, in __getitem__
    raise KeyError(key) from None
KeyError: 'SECRET_KEY'
The command '/bin/sh -c python manage.py collectstatic' returned a non-zero code: 1
##[error]The command '/bin/sh -c python manage.py collectstatic' returned a non-zero code: 1
##[error]The process '/usr/bin/docker' failed with exit code 1

Я просто не уверен, как добиться sh получения переменной среды там. Мой подход может быть совершенно неверным с самого начала.

Так как же мне go о:

  1. Безопасное объявление переменных среды в конвейере?
  2. Передача переменные среды на этапе сборки?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 17 января 2020

Ваш python manage.py collectstatic работает в контейнере docker, и его os.environ['SECRET_KEY] попытается получить переменную среды контейнера, в котором он работает. Но переменная окружения SECRET_KEY, которую вы установили в своем конвейере, предназначена для агента сборки.

Вы можете попробовать следующие шаги, чтобы передать переменную env конвейера в контейнер docker.

1, я добавляю ARG и ENV в ваш файл dockerfile ARG SECRET; ENV SECRET_KEY $SECRET

ENV SECRET_KEY относится к значению ARG SECRET

FROM python:3.7-slim

ARG SECRET
ENV SECRET_KEY $SECRET

ENV PYTHONUNBUFFERED 1
WORKDIR /app
EXPOSE 5000
COPY requirements*.txt ./
RUN pip install -r requirements.txt
COPY . .
RUN python manage.py collectstatic
CMD ["gunicorn", "-b", ":5000", "--log-level", "info", "config.wsgi:application"]

2, я разделяю docker buildandpu sh задачу для стыковки сборки и стыковки pu sh, как buildandpu sh команда не может принимать аргументы.

В docker build задача. Я передал переменную secretKey в поле arguments --build-arg SECRET=$(secretKey). Так что когда docker запустит сборку, ARG SECRET будет заменен на secretKey. И он будет передан в ENV SECRET_KEY, как определено в приведенном выше файле dockerfile. Так что для SECRET_KEY будет установлена ​​переменная Environment контейнера docker.

Тогда вы python код сможете получить значение переменной среды, используя os.environ['SECRET_KEY]

stages:
- stage: Build
  displayName: Build and push stage
  jobs:  
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build
      inputs:
        command: build
        repository: $(imageRepository)-api
        dockerfile: $(dockerfilePath)/api/Dockerfile
        containerRegistry: $(dockerRegistryServiceConnection)

        arguments: --build-arg SECRET=$(secretKey)

        tags: |
          $(tag)

    - task: Docker@2
      displayName: Push
      inputs:
        command: push
        repository: $(imageRepository)-api
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)


- upload: manifests
  artifact: manifests
0 голосов
/ 11 января 2020

Вы можете ввести переменные env, используя --build-arg и соответствующую команду ARG в Dockerfile, но это небезопасно . Ключ будет встроен в изображение!

Ваши параметры, если вы хотите быть в безопасности:

  1. Загрузите все, что вам нужно, используя секретный ключ за пределами из Docker build, и просто скопируйте его.
  2. Используйте (экспериментальный, но менее ошибочный, чем в прошлом) бэкэнд BuildKit для Docker, который поддерживает безопасную передачу секретов.
  3. Запустите сетевой сервер в другом контейнере, запустите Docker build с --network container:<thatcontainerid>, и теперь вы можете отправлять запросы в этот другой контейнер для получения секретов. Или аналогичным образом запустите веб-сервер на хосте, выполните --network host.

Более продолжительная запись, в которой также упоминаются некоторые другие альтернативы, такие как копирование с помощью многоступенчатой ​​сборки: https://pythonspeed.com/articles/docker-build-secrets/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...