개발하는 자몽

[Django] 개발 환경 분리 본문

Python/Django

[Django] 개발 환경 분리

jaamong 2023. 12. 30. 10:13

서버에서 개발을 하다가, 여러 명이 서버에 접근할 때 git이나 여러 설정이 꼬여서 개발 환경을 분리하기로 결정했다. 

 

SpringBoot는 `application.yml`이나 `application.properties`를 이용하여 개발 환경을 분리한다면, Django는 `settings.py`를 이용하여 개발 환경을 분리해야 한다. 

 

구조

분리 전 설정이 담긴 프로젝트 구조는 아래와 같다.

📦backend
 ┣ 📜settings.py
 ┣ 📜asgi.py
 ┣ 📜exceptions.py
 ┣ 📜urls.py
 ┣ 📜wsgi.py
 ┗ 📜__init__.py

프로젝트 설정이 `settings.py` 하나로만 구성되어 있다. 이렇게 되면 로컬 환경이나 배포 환경의 설정이 동일하게 되므로 DB 접속이나 기타 설정 등을 할 때 번거롭다. 

따라서 이러한 설정을 분리하기 위해 settings.py를 `base.py`, dev.py`, `prod.py`로 분리했다.

 

아래는 분리 후 프로젝트 구조이다. settings라는 디렉토리를 추가하여 안에 환경 설정을 담고 있는 코드를 모아두었다. 

📦backend
 ┣ 📂settings
 ┃ ┣ 📜base.py
 ┃ ┣ 📜dev.py
 ┃ ┣ 📜prod.py
 ┃ ┗ 📜__init__.py
 ┣ 📜asgi.py
 ┣ 📜exceptions.py
 ┣ 📜urls.py
 ┣ 📜wsgi.py
 ┗ 📜__init__.py
  • base.py : 언어/지역 및 시간 설정, 공통적으로 사용할 `INSTALLED_APPS`과 같은 로컬 환경과 배포 환경이 공통적으로 갖고 있는 설정들을 작성한다.
  • dev.py : dev는 development를 줄여놓은 것으로 개인 환경에서 사용할 설정들을 작성하면 된다. 개인 개발 환경에서는 `DEBUG`를 `True`로 설정해 둔다. DB 설정, `ALLOWED_HOST` 등 개인 환경에 맞추어 설정하면 된다. 
  • prod.py : prod는 production을 줄인 것으로 배포 환경에서 사용할 설정들을 작성한다. 배포 환경이므로 `DEBUG`를 `False`로 설정해 두고, 이에 따라 `ALLOWED_HOST`도 잘 설정해야 한다(그렇지 않으면 에러가...). DB 설정도 배포를 위한 것으로 작성한다.

 

 

Settings

base.py

base.py를 작성하면서 주의할 것은 `BASE_DIR` 설정이다.

from pathlib import Path
import os, environ

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent

env = environ.Env(DEBUG=(bool, False))
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')

# Application definition
INSTALLED_APPS = [  
    ...
]

MIDDLEWARE = [
    ...
]

ROOT_URLCONF = 'backend.urls'

TEMPLATES = [
    ...
]

WSGI_APPLICATION = 'backend.wsgi.application'

AUTH_PASSWORD_VALIDATORS = [
    ...
]


# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ko'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Seoul'

USE_I18N = True

USE_TZ = False


STATIC_URL = 'static/'

MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

...

기존에는 `parent`를 두 번 붙였었는데, 위치가 변했으므로(settings.py으로 이동) `parent`를 총 세 번 붙이게 되었다. 주의하자! 

 

dev.py

dev.py에 base.py를 임포트 하고, `DEBUG`를 `True`로 설정해 두었다. DB 설정도 로컬 환경에 맞게끔 설정해 두었다😉

from .base import *


DEBUG = True

ALLOWED_HOSTS = [
    'localhost',
    '127.0.0.1',   
]

CORS_ORIGIN_WHITELIST = [
    'http://127.0.0.1:8000',
]

CSRF_TRUSTED_ORIGINS = [
    'http://127.0.0.1:8000',
]

CORS_ALLOW_CREDENTIALS = True

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': env('DB_NAME'),  
        'USER': env('DB_USER'),  
        'PASSWORD': env('DB_PASSWORD'),  
        'HOST': env('DB_HOST'), 
        'PORT': '',
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    },
}

참고로 `SECRET_KEY`나 DB 설정과 같은 민감한 정보는 `django-environ`을 통해서 따로 분리할 수 있다. (이 내용은 다른 포스트로 올릴 예정)

 

prod.py

prod.py에 base.py를 임포트 하고, `DEBUG`를 `False`로 설정해 두었다

from .base import *

# 배포환경에서는 DEBUG를 False로 설정해두자!
DEBUG = False

INSTALLED_APPS += [
    # 배포 환경에서 추가적으로 필요한 것들
]

ALLOWED_HOSTS = [
	...
]

CORS_ORIGIN_WHITELIST = [
	...
]

CSRF_TRUSTED_ORIGINS = [
    ...
]

CORS_ALLOW_CREDENTIALS = True

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': env('DB_NAME'),  
        'USER': env('DB_USER'),  
        'PASSWORD': env('DB_PASSWORD'),  
        'HOST': env('DB_HOST'), 
        'PORT': '',
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    },
}

 

 

실행 방법

개발 환경을 분리했다면 실행할 때도 그에 맞춰서 실행해줘야 한다. 설정 변경 후 실행 방법에는 두 가지가 있다. 

 

방법 1. manage.py 수정

로컬 또는 배포 환경인 경우 `os.environ.setdefault` 설정을 `settings.dev` 또는 `settings.prod`로 변경해야 한다. 또한 이와 같이 실행 설정을 해주어야 하는 파일이 있다면 동일하게 수정해야 한다.

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings.dev')
    
    ...


if __name__ == '__main__':
    main()

 

방법 2. 실행 시 옵션 추가

다른 방법으로는 아래와 같이 실행할 때 옵션을 추가하는 것이다. 방법 1로 진행했다면 위와 같이 옵션을 주지 않고 실행할 수 있다. 

$ python manage.py --settings=backend.settings.dev  // 로컬
$ python manage.py --settings=backend.settings.prod  // 배포

 

 

 

 

Comments