Django Snippet - settings.py 분리(개발환경과 배포환경)

1. settings.py 분리 이유

  • settings.py 중 대표적으로 DEBUG = True 값은 배포 시 변경해야함.
  • 그 이외에도 개발환경에 필요한 설정값과 배포시 변경 또는 추가해주어야하는 설정이 존재할 수 있음
  • 배포할때마다 변경 수정하는 번거러움 또는 배포시 누락 가능성으로 파일을 분리할 필요성이 생김

2. 외부 중요정보 분리(DB암호, SECRET_KEY 등)

2.1 중요정보 분리

  • DB서버 정보와 SECRET_KEY 값을 분리하여 server_info.json 파일로 저장합니다.
  • SECRET_KEYproduction.pydevelopment.py와 다르게 갑니다.
{
    "production" : {
        "SECRET_KEY" : "SECRET_KEY 값",
        "DATABASES" : {
            "default": {
                "ENGINE": "DB 드라이버",
                "NAME": "DB이름",
                "USER": "DB유저",
                "PASSWORD": "DB유저암호",
                "HOST": "DB호스트주소",
                "PORT": "DB포트번호"
            }
        }
    }

}

2.2 중요정보를 읽어드릴 유틸함수 작성

  • conf/util.py에 아래와 같은 코드를 작성하였습니다.
import json


def get_server_info_value(key: str):

    with open('server_info.json', mode='rt', encoding='utf-8') as file:
        data = json.load(file)
        for k, v in data.items():
            if k == key:
                return v
        raise ValueError('서버정보를 확인할 수 없습니다.')

3. settings.py 분리

  • 파일을 아래와 같이 settings.py가 있던 디렉토리 내에 settings 디렉토리를 만들고, 4개의 파일을 작성합니다.
    • base.py : 공통 설정 파일
    • development.py : 개발환경 설정 파일
    • production.py : 배포환경 설정파일
    • __init__.py : 파이썬 패키지 파일

django_settings

3.1 base.py 내용

  • base.py 내용
  • 기존 BASE_DIR 값보다 한번 더 os.path.dirname() 을 사용해야합니다. settings 디렉토리안으로 이동되었기 때문입니다.
  • 공통적으로 사용할 설정값을 입력합니다.
## 공통 설정
import os

BASE_DIR = os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

INSTALLED_APPS = [
    ... 생략 ...
]

MIDDLEWARE = [
   ... 생략 ... 
]

ROOT_URLCONF = 'conf.urls'

TEMPLATES = [
    {
    ... 생략 ...
    },
]

... 생략 ...


3.2 development.py 내용

  • development.py 내용
  • 개발환경에 들어갈 설정만 담습니다.
  • 공통설정을 import 합니다. from .base import *
  • development.py에서는 SECRET_KEY 를 노출시켰습니다.
  • SECRET_KEY 노출이유는 github에서 travis를 통해 CI를 구동시킬 때, Github에 주요암호가 담긴 파일을 제외했기 때문입니다.
  • production.py에서는 SECRET_KEYdevelopment.py와 다르게 입력할 것입니다.
  • SECRET_KEY와 같은 이유로 DATABASES 값은 sqlite로 지정하였습니다.
# 개발 설정
import os

from .base import *

# dev SECRET_KEY 노출되어도 무방, 실서버와는 다름
SECRET_KEY = "buq*!eias((abkx11b6ab964cs7-at1gw%k^!oypi^1357f6@"
DEBUG = True

INSTALLED_APPS += [
    ... 생략 ...
]

ALLOWED_HOSTS = [
    "127.0.0.1",
    "localhost",
]

DATABASES = {
     'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

MIDDLEWARE += [
    ... 생략 ...
]

... 생략 ...

❈ development.py 에서는 travis를 사용하고자 sqlite를 사용하고 key를 노출시켰는데 혹시 다른 더 좋은 방법이 있으면 덧글 부탁 드립니다 ㅜ

3.3 production.py 내용

  • production.py 내용
  • 배포환경에 사용된 설정만 포함합니다.
  • 공통설정을 import 합니다. from .base import *
  • github에 노출시키지 말아야할 정보가 담긴 분리된 파일에서 정보를 가지고 올 함수를 import 합니다. from conf.util import get_server_info_value
  • SETTING_PRD_DIC = get_server_info_value("production") 외부 파일에서 정보를 가져옵니다.
# 실서버 설정
from conf.util import get_server_info_value
from .base import *

SETTING_PRD_DIC = get_server_info_value("production")
SECRET_KEY = SETTING_PRD_DIC["SECRET_KEY"]

DEBUG = False

ALLOWED_HOSTS = [
            ... 실서버 도메인 ...
            ]

DATABASES = {
    'default': SETTING_PRD_DIC['DATABASES']["default"]
}

4. OS에서 환경변수 설정

  • OS에서 환경변수 설정은 개발환경, 배포환경 양쪽 모두 적용해주어야합니다.
  • OS환경에서 bash를 사용한다면, .bash_profile, zsh를 사용한다면 .zshrc파일에 아래의 코드를 입력합니다.

  • 개발환경
export DJANGO_SETTINGS_MODULE=conf.settings.development
  • 배포환경
export DJANGO_SETTINGS_MODULE=conf.settings.production
  • 저장하고 나온 후 아래의 코드로 즉시 적용해줍니다.
$ source ~/.bash_profile

5. travis 수정

  • travis도 개발환경에서 구동될수 있도록 .travis.yml 파일을 수정합니다.
... 생략 ...
env:
  global:
    - DJANGO_SETTINGS_MODULE=conf.settings.development
... 생략 ...

6. systemd 수정

  • 저는 AWS에 systemd을 통해 gunicorn을 서비스에 등록하고 프로세스가 죽더라도 살아나도록 설정하였습니다.
  • systemd에서 guncorn 실행부분을 아래와 같이 변경합니다.
  • 추가되는 부분은 --env DJANGO_SETTINGS_MODULE=conf.settings.production 입니다.
/guncorn경로/gunicorn --env DJANGO_SETTINGS_MODULE=conf.settings.production 앱명.wsgi:application -b 0.0.0.0:실행포트

참고 사이트