Контейнер докеров Django не улавливает переменную окружения ALLOWED_HOSTS в конвейере GitLab CI
Я пытаюсь создать конвейер 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
Ответы
Я получил свой ответ благодаря @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