Kontainer buruh pelabuhan Django tidak menangkap variabel lingkungan ALLOWED_HOSTS dalam pipa GitLab CI

Aug 19 2020

Saya mencoba untuk membangun pipa GitLab-CI tetapi Django tampaknya tidak menangkap variabel ALLOWED_HOST yang diteruskan sebagai variabel lingkungan.

Proyek itu sendiri adalah proyek Django yang berjalan dalam wadah. Django membutuhkan ALLOWED_HOSTS dan nilai SECRET_KEY dalam pengaturannya agar bisa bekerja. Pada lingkungan pengembangan saya serta di server produksi saya, variabel diteruskan ke Django melalui file env.

Contoh pengaturan Django:

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

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

Contoh file-env:

SECRET_KEY=mydummysecretkey

DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]

Ini berfungsi dengan baik pada dev dan mesin produksi saya.

Tetapi ketika saya mencoba menjalankannya di .gitlab-ci.yml saya, Django tidak menemukan variabel DJANGO_ALLOWED_HOSTS. Saya selalu mendapat kesalahan ini:

$ 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

Ini cukup aneh karena Django menangkap variabel SECRET_KEY dengan baik. Seperti yang Anda lihat pada potongan kode di bawah, saya bahkan melakukan gema pada variabel yang ditampilkan dengan baik.

FYI: Django sedang berjalan dalam wadah Docker dan pipeline CI membangun citra (dan mendorongnya ke pendaftar Gitlab) pada pekerjaan pertama untuk mengujinya pada pekerjaan kedua (dan menerapkannya pada pekerjaan ketiga).

Ini .gitlab-ci.yml saya:

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

Inilah hasilnya:

$ 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

Jawaban

2 Bravo2bad Aug 20 2020 at 06:35

Saya mendapat jawaban saya berkat @Zeitounator

Saya hanya akan mengutip komentarnya untuk membuatnya sederhana:

os.environ.getmengambil variabel lingkungan dari sistem yang sedang berjalan yang merupakan container buruh pelabuhan Anda, bukan dari sistem gitlab-ci yang mendasarinya. Gitlab CI vars (seperti shell vars biasa) tidak didorong secara otomatis ke penampung Anda. SECRET_KEYtidak mengeluarkan peringatan karena itu hanya nol. DJANGO_ALLOWED_HOSTSlakukan karena Anda mencoba membaginya. Anda harus meneruskan vars env tersebut ke container Anda, baik dengan opsi -e docker atau melalui file env yang Anda buat saat itu juga.

Jadi ini pasti berhasil:

...

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

...

Saya berakhir dengan sesuatu seperti ini:

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