Контейнер докеров Django не улавливает переменную окружения ALLOWED_HOSTS в конвейере GitLab CI

Aug 19 2020

Я пытаюсь создать конвейер GitLab-CI, но Django, похоже, не улавливает переменную ALLOWED_HOST, переданную как переменную среды.

Сам проект - это проект Django, работающий в контейнере. Для работы Django необходимы значения ALLOWED_HOSTS и SECRET_KEY в настройках. В моей среде разработки, а также на моем производственном сервере переменные передаются в Django через env-файл.

Пример настроек Django:

SECRET_KEY = os.environ.get('SECRET_KEY')

ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")

Пример env-файла:

SECRET_KEY=mydummysecretkey

DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]

Это отлично работает на моем разработчике и моих производственных машинах.

Но когда я пытаюсь запустить его в своем .gitlab-ci.yml, Django не находит переменную DJANGO_ALLOWED_HOSTS. У меня всегда возникала такая ошибка:

$ docker run --rm $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA py.test ./my_project

ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")
AttributeError: 'NoneType' object has no attribute 'split'
ERROR: Job failed: exit code 1

Это довольно странно, потому что Django хорошо улавливает переменную SECRET_KEY. Как вы можете видеть в приведенном ниже фрагменте кода, я даже применил эхо к переменной, которая хорошо отображается.

К вашему сведению: Django работает в контейнере Docker, а CI-конвейер создает образ (и отправляет его в регистр Gitlab) в первом задании, чтобы протестировать его во втором задании (и развернуть его в третьем задании).

Вот мой .gitlab-ci.yml:

image: docker:stable

services:
  - docker:19.03.0-dind

variables:
  SECRET_KEY: 'mydummysecretkey_gitlab-ci'
  DJANGO_ALLOWED_HOSTS: 'localhost 127.0.0.1 [::1]'

stages:
  - build
  - test

Build and push stage:
  stage: build
  script:
    - docker login --username $CI_REGISTRY_USER --password "$CI_BUILD_TOKEN" $CI_REGISTRY
    - docker pull $CI_REGISTRY_IMAGE:latest || true - docker build --cache-from $CI_REGISTRY_IMAGE:latest -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA ./my_project
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

Test stage:
  stage: test
  script:
    - echo $DJANGO_ALLOWED_HOSTS - docker login --username $CI_REGISTRY_USER --password "$CI_BUILD_TOKEN" $CI_REGISTRY
    - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - docker run --rm $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA py.test ./my_project  # Fails here !
    - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest - docker push $CI_REGISTRY_IMAGE:latest

Вот результат:

$ echo $DJANGO_ALLOWED_HOSTS
localhost 127.0.0.1 [::1]
$ docker login --username $CI_REGISTRY_USER --password "$CI_BUILD_TOKEN" $CI_REGISTRY
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
$ docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA ... $ docker run --rm $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA py.test ./my_project
Traceback (most recent call last):
  
...

  File "/usr/src/app/my_project/settings.py", line 32, in <module>
    ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")
AttributeError: 'NoneType' object has no attribute 'split'
ERROR: Job failed: exit code 1

Ответы

2 Bravo2bad Aug 20 2020 at 06:35

Я получил свой ответ благодаря @Zeitounator

Я просто процитирую его / ее комментарий, чтобы было проще:

os.environ.getизвлекает переменные среды из работающей системы, которая является вашим контейнером докеров, а не из базовой системы gitlab-ci. Вары Gitlab CI (как ваши обычные вары оболочки) не помещаются в ваш контейнер автоматически. SECRET_KEYне выдает предупреждения, потому что это просто null. DJANGO_ALLOWED_HOSTSделает, потому что вы пытаетесь его разделить. Вы должны передать эти переменные env своему контейнеру либо с параметром -e docker, либо через файл env, который вы создаете на месте.

Так что это определенно работает:

...

Test stage:
  stage: test
  script:

...

    - docker run --rm -e SECRET_KEY=mydummysecretkey_gitlab-ci -e DJANGO_ALLOWED_HOSTS='localhost 127.0.0.1 [::1]' $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA pytest

...

У меня получилось что-то вроде этого:

docker run --rm -e SECRET_KEY='$SECRET_KEY' -e DJANGO_ALLOWED_HOSTS='$DJANGO_ALLOWED_HOSTS' $CI_COMMIT_SHA pytest