DjangoのDockerコンテナーは、GitLabCIパイプラインの環境ALLOWED_HOSTS変数をキャッチしません

Aug 19 2020

GitLab-CIパイプラインを構築しようとしていますが、Djangoが環境変数として渡されたALLOWED_HOST変数をキャッチしていないようです。

それ自体のプロジェクトは、コンテナーで実行されるDjangoプロジェクトです。Djangoが機能するには、設定にALLOWED_HOSTSとSECRET_KEYの値が必要です。私の開発環境と本番サーバーでは、変数はenvファイルを介してDjangoに渡されます。

Django設定サンプル:

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

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

環境ファイルのサンプル:

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レジスターにプッシュ)して、2番目のジョブでテスト(および3番目のジョブにデプロイ)します。

これが私の.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システムからではなく、Dockerコンテナである実行中のシステムから環境変数を取得します。Gitlab CI変数(通常のシェル変数と同様)は、自動的にコンテナーにプッシュされません。SECRET_KEY単にnullであるため、警告は発行されません。DJANGO_ALLOWED_HOSTSあなたがそれを分割しようとするのでそうします。-e dockerオプションを使用するか、その場で作成したenvファイルを介して、これらの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