- 프로그래머스
- session
- spring mvc
- sql
- Git
- join
- 자바
- 문자열
- 데이터베이스
- select
- jpa
- AWS
- Django
- PYTHON
- Docker
- springboot
- 1차원 배열
- nginx
- @transactional
- java
- spring security 6
- spring
- SSL
- string
- 스프링부트
- 스프링
- DI
- ORM
- spring boot
- mysql
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
개발하는 자몽
[Django] 개발 환경 분리 본문
서버에서 개발을 하다가, 여러 명이 서버에 접근할 때 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 // 배포
'Python > Django' 카테고리의 다른 글
[Django] Swagger를 이용한 API Documentation (0) | 2024.01.20 |
---|---|
[Django] 배포 환경에서 Nginx로 media file 제공하기 on Docker (0) | 2024.01.13 |
[Django] 환경변수 관리 (django-environ) (1) | 2024.01.06 |
[Django / TIL] request와 requests (0) | 2023.10.30 |
[Django] django-crontab & Docker (1) | 2023.10.24 |