Django, Docker-compose 에서 .env 적용 안되는 문제

Django, Docker-compose 에서 .env 적용 안되는 문제

Published
June 14, 2023
Last updated
Last updated October 25, 2024
장고 프로젝트를 도커로 배포하며 환경변수가 적용되지 않는 문제를 겪었습니다.
이 상황당시의 배포방식은 docker compose와 docker을 이용하고, 이때 env_file인 web.env를 docker-compose.yml에 명시해주어 파일의 환경변수를 가져와주고, 이를 파이썬에서 os.environ.get()으로 읽어오는 방식이였습니다.
# docker-compose.yml version: "3" services: django: build: . ports: - 80:80 env_file: - web.env volumes: - ./static:/staticfiles command: gunicorn config.wsgi --bind 0.0.0.0:80
# Dockerfile FROM python:3.10 ENV PYTHONUNBUFFERED=0 WORKDIR /web COPY ./requirements.txt /web RUN pip3 install --upgrade pip RUN pip3 install -r requirements.txt COPY . /web RUN python manage.py collectstatic --noinput CMD gunicorn config.wsgi:application --bind 0.0.0.0:80
# settings.py import os SECRET_KEY = os.environ.get("SECRET_KEY", "1234") DEBUG = os.environ.get("DJANGO_DEBUG", "False") == "True" ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "*").split(" ")
# web.env DJANGO_DEBUG=False SECRET_KEY=12345 DJANGO_ALLOWED_HOSTS=localhost
위와 같은 상황에서 계속 오류가 발생하고 있었는데, 당시 다음과 같은 문제를 의심해 보았습니다.
  1. web.env environment file이 제대로 불러와지지 않은 경우, 포맷이 잘못된 경우
  1. docker 내부에 환경변수가 제대로 들어가지 않은 경우
  1. python에서 os.environ.get()으로 환경변수를 잘 읽어내지 못하는 경우
당시에 이 3가지를 가정하고 디버깅을 진행했습니다.
.env파일과 도커파일들의 문서를 보며 정확한 서식을 찾아보고, 컨테이너를 빌드해보며, docker-compose와 web.env의 파일의 규칙 문제는 아니라고 확신하고, 계속 문제를 찾아보았습니다.
그러다 우연히 문제를 발견하게 되었습니다.
Step 8/9 : RUN python manage.py collectstatic --noinput ---> Running in 4afbff0af905 Traceback (most recent call last): File "/web/manage.py", line 22, in <module> main() File "/web/manage.py", line 18, in main execute_from_command_line(sys.argv) File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line utility.execute() File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 420, in execute django.setup() File "/usr/local/lib/python3.10/site-packages/django/__init__.py", line 24, in setup apps.populate(settings.INSTALLED_APPS) File "/usr/local/lib/python3.10/site-packages/django/apps/registry.py", line 116, in populate app_config.import_models() File "/usr/local/lib/python3.10/site-packages/django/apps/config.py", line 269, in import_models self.models_module = import_module(models_module_name) File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1050, in _gcd_import File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 883, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/usr/local/lib/python3.10/site-packages/rest_framework_simplejwt/models.py", line 6, in <module> from .settings import api_settings File "/usr/local/lib/python3.10/site-packages/rest_framework_simplejwt/settings.py", line 19, in <module> "SIGNING_KEY": settings.SECRET_KEY, File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 101, in __getattr__ raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.") django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty. ERROR: Service 'django' failed to build: The command '/bin/sh -c python manage.py collectstatic --noinput' returned a non-zero code: 1
당시 오류 메시지를 보면 다음과 같았는데, 보면 8/9단계인 RUN으로 정적파일을 다루는 부분에서 오류가 난 것을 볼 수 있습니다. 이는 docker-compose.yml에서 넘겨준 환경변수는 최종단계에서는 제대로 전달이 되지만, 빌드단계인 8단계에서는 Docker로 들어가지 않아 collectstatic를 실행할 때는 SECRET_KEY가 지정되지 않아 오류가 나는 것이었습니다.
제대로 오류를 읽어보았다면, 빌드과정에서, 그것도 8단계에서 SECRET_KEY가 없는것의 문제인 것을 금방 알 수 있었을 텐데, 오류 코드를 제대로 읽어보지 않아 많은 시간을 낭비하게 된 경험이었습니다.
이후 해당문제는 django-environ 라이브러리를 사용해 파일에서 바로 환경변수를 읽어오는 방식을 이용하여 해결했습니다.