คอนเทนเนอร์นักเทียบท่าของ 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]

สิ่งนี้ใช้ได้ดีกับ dev และเครื่องผลิตของฉัน

แต่เมื่อฉันพยายามเรียกใช้ใน. 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 ได้ดี ดังที่คุณเห็นในข้อมูลโค้ดด้านล่างฉันยังทำเสียงสะท้อนของตัวแปรที่แสดงผลได้ดี

FYI: Django กำลังทำงานในคอนเทนเนอร์ Docker และ CI-pipeline จะสร้างอิมเมจ (และส่งไปยัง Gitlab registery) ในงานแรกเพื่อทดสอบในงานที่สอง (และปรับใช้ในงานที่สาม)

นี่คือ. 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 vars (ตามปกติของเชลล์ vars) จะไม่ถูกส่งไปยังคอนเทนเนอร์ของคุณโดยอัตโนมัติ SECRET_KEYไม่ออกคำเตือนเพราะเป็นโมฆะ DJANGO_ALLOWED_HOSTSทำเพราะคุณพยายามแยกมัน คุณต้องส่ง env vars เหล่านั้นไปยังคอนเทนเนอร์ของคุณไม่ว่าจะด้วยอ็อพชัน -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