프로젝트를 진행할 때 가장 중요한 것은 깃에서 추적할 코드와 추적하지 않을 중요 정보 및 설정을 분리해놓는 것이다. 특히 깃헙 퍼블릭 레포지토리를 사용하고 있다면 소스코드를 푸시하기 전에 반드시 추적되선 안되는 프로젝트 시크릿 키, 허용하는 호스트 주소들, 데이터베이스 정보 등은 따로 관리해주어야 한다.

숨기고 싶은 값들은 루트 경로에 .config_secret 폴더를 따로 생성하여 내부에서 환경별로 관리해준다. 또한 개발(로컬)환경과 운영환경에서 사용하는 설정값이 다를 수 있으므로 하나의 프로젝트 내에서 배포와 개발환경을 서로 나누어 사용하려고 한다. 배포환경 설정을 저장할 파일은 deploy, 개발환경 설정을 저장할 파일은 debug로 각각 분리하였다.


설정 분리하기

.config_secret 폴더로 숨길 값들 관리하기

프로젝트 폴더 내에 .config_secret을 만들어준다.(django_app 폴더와 같은 위치)

해당 폴더는 숨김파일로 기능한다. 폴더 내에 JSON 파일을 만들어주고 앱의 secret_key, debug, database, allowed_host, 그리고 static 파일경로 등의 앱 설정사항을 넣어준다. 배포환경, 개발환경에서 공통으로 사용할 비밀값들을 저장하는데에 JSON 파일 형식을 사용한다.


.json 파일 작성하기

JSON 파일은 딕셔너리로 구성되어 있으며 문자열에 작은 따옴표('')를 허용하지 않는다. 또한 딕셔너리 마지막 값 뒤에 콤마(,)를 쓰면 에러나므로 주의한다.

공통으로 사용할 개인/중요정보는 settings_common.json에 저장한다.

### .config_secret/settings_common.json

{
  "django": {
    "secret_key": "[앱 시크릿키값]"
  }
}


개발 환경에서만 사용할 개인/중요정보는 settings_debug.json에 저장한다.

### .config_secret/settings_debug.json

{
  "django": {
    "allowed_hosts": [
      "*"
    ]
  }
}


배포 환경에서만 사용할 개인/중요정보는 settings_debug.json에 저장한다.

### .config_secret/settings_deploy.json

{
  "django": {
    "allowed_hosts": [
      "*"
    ]
  }
}


settings 파일 분할하기

(1) base.py

기존의 settings 파일은 동일 프로젝트 폴더 내에 파이썬 패키지 settings로 만들고 base.py로 저장한다. 기존 settings.py에 있는 내용을 모두 옮겨주고 기존파일은 삭제한다.

경로가 바뀌었으므로 os.path을 사용하여 세팅 안의 경로 지정값들을 바꿔준다. (os.path는 파일과 경로를 지정해줄 때 유용한 함수들을 여러 개 제공하고 있다.)

import json

# 파이썬 패키지 안에 넣어주었으므로 기존 BASE_DIR 경로에서 dirname()으로 한번 더 감싸준다.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# BASE_DIR로 루트 경로를 변수에 할당한다.
ROOT_DIR = os.path.dirname(BASE_DIR)

# .config_secret폴더 및 하위 파일 경로
CONFIG_SECRET_DIR = os.path.join(ROOT_DIR, '.config_secret')
CONFIG_SECRET_COMMON_FILE = os.path.join(CONFIG_SECRET_DIR, 'settings_common.json')
CONFIG_SECRET_DEBUG_FILE = os.path.join(CONFIG_SECRET_DIR, 'settings_debug.json')
CONFIG_SECRET_DEPLOY_FILE = os.path.join(CONFIG_SECRET_DIR, 'settings_deploy.json')

# .config_secret 변수에 CONFIG_SECRET_COMMON_FILE경로의 파일을 읽은 값을 할당
f = open(CONFIG_SECRET_COMMON_FILE)
config_secret_string = f.read()
# json 형식을 파이썬 딕셔너리 형식으로 변환해준다.
config_secret = json.loads(config_secret_string)
# 열었던 파일을 닫는다.
f.close()

# 위의 과정을 아래와 같이 작성할 수도 있다.
config_secret_common = json.loads(open(CONFIG_SECRET_COMMON_FILE).read())
# 변수가 사용되지 않으면 파일은 자동으로 닫힌다

# 시크릿키를 바로 쓰는 것이 아니라 숨김파일에 따로 설정해 불러올 수 있다.
SECRET_KEY = config_secret_common['django']['secret_key']


콘솔에서 사용하기

기존 세팅파일을 새로 정의해주었으므로 서버를 실행할 때 어떤 환경의 설정을 사용할 것인지 명시해주어야 한다.

# 기본, 개발, 배포용 서버를 각각 따로 실행할 수 있다.
$ .manage.py runserver --settings=config.settings.base  # 기본용
$ .manage.py runserver --settings=config.settings.debug  # 개발용
$ .manage.py runserver --settings=config.settings.deploy  # 배포용

일일히 작성하기 싫다면 터미널 별로 환경변수의 기본값을 설정하여 사용할 수도 있다.

# 예) 아래와 같이 선언하면 해당 터미널에서는 타 명령을 실행할 때 개발환경의 설정을 따른다.
$ export DJANGO_SETTINGS_MODULE=config.settings.debug


(2) debug.py와 deploy.py

settings폴더 내에 debug.py, deploy.py 파일을 각각 생성한 후 다음의 값을 설정해준다.

  • DEBUG = True설정
  • settings_debug.json의 값을 불러와 파이썬 딕셔너리로 돌려준 값
  • ALLOWED_HOSTS 값을 설정
### settings/debug.py

from .base import *


config_secret_debug = json.loads(open(CONFIG_SECRET_DEBUG_FILE).read())

DEBUG = True
ALLOWED_HOSTS = config_secret_debug['django']['allowed_hosts']

위의 설정으로 콘솔에서 runserver를 실행해보면…

# DEBUG 설정을 debug.py로 옮겨주면 기존 base 파일은 실행되지 않는다.
$ ./manage.py runserver --settings=config.settings.base    
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.

# 따라서 debug로 실행해준다.
$ ./manage.py runserver --settings=config.settings.debug

만들어준 .config_secret 디렉토리는 .gitignore에 명시해주어 Github에서 추적하지 않도록 해준다. 배포는 AWS키를 사용할 예정이므로 처음 실습한다면 bitbucket을 사용하는 것을 추천한다. Github는 비공개 레포지토리가 유료이지만 bitbucket은 무료로 비공개 레포지토리를 생성/사용할 수 있다.

또한 배포할 프로젝트 폴더는 settings 파일을 제공하지 않기 때문에 README.md를 따로 작성하여 requirements에 대한 안내문을 작성해주는 것이 좋다.


프로젝트 구조 이해하기

설정을 분리한 파일구조를 보면 다음과 같다.

$ tree .
.
# 깃에서 track하면 안되는 중요 정보들을 저장하는 json 파일 묶음.
├── .config_secret
	# 프로젝트 secret_key
    ├── settings_common.json   
    # 개발환경의 allowed_hosts 설정
    ├── settings_debug.json     
    # 배포환경의 allowed_hosts 및 데이터베이스 설정
    └── settings_deploy.json   
├── .requirements
    # 개발환경에서 필요한 패키지 모음
    ├── debug.txt
    # 배포환경에서 필요한 패키지 모음
    └── deploy.txt
# 프로젝트 루트폴더 (프로젝트를 구성하는 앱과 기본 설정 묶음.) 
├── django_app
  # 프로젝트 기본 설정폴더 (startproject 시 기본으로 생성해줌)
    ├── config
    │   ├── __init__.py
    # 기존 settings.py를 환경 별로 다르게 적용되도록 분리. 
    │   ├── settings
    │   │   ├── __init__.py
    │   │   ├── base.py  # 공통 설정파일
    │   │   ├── debug.py  # 개발환경
    │   │   └── deploy.py  # 배포환경
    # 프로젝트 기본 url 설정파일. rest_framework 기본 url을 설정해준다.
    │   ├── urls.py
    # 어플리케이션 인터페이스 설정 분리
    │   └── wsgi
    │       ├── __init__.py
    │       ├── debug.py
    │       └── deploy.py
    ├── db.sqlite3
    └── manage.py
├── README.md
└── db.sqlite3


작업 중 WSGI에 대한 이해가 명확하지 않아 블로그 내 WSGI란 무엇인가?에 따로 정리하였다.


마치며

이외에도 세팅은 점차 개발을 해나가면서 필요한 데이터베이스정보, 정적파일 및 미디어 파일 저장경로 등을 개발/배포 환경 별로 지정해 줄 수 있다.

다음 포스팅은 Wordy Gallery의 앱 구조와 모델링에 대해 정리할 예정이다.



Julia Hwang

디발자를 꿈꾸는 웹개발자의 블로그입니다.