DjangoのDockerコンテナーは、GitLabCIパイプラインの環境ALLOWED_HOSTS変数をキャッチしません
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
回答
@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