본문 바로가기

Back-end & Server/Django

[Django] 배포

728x90
반응형

지금까지 Django 실습을 할 때 항상 다음과 같은 명령어로 Django를 실행해 실습을 진행했음

python manage.py runserver

이 방법은 웹 서버 설정에 대해 걱정할 필요가 없지만 공용 웹에 노출되지 않고 로컬 컴퓨터에서의 개발용으로만 사용됨

공용 웹에 Django 응용 프로그램을 배포하려면 아파치 같은 웹 서버에 연결해야함

 

배포 체크리스트

Django 응용 프로그램을 배포하기전 보안, 성능 및 작업을 염두에 두고 설정을 검토해야함

Django에는 많은 보안 기능(일부는 내장돼 있으며 항상 활성화 상태임)이 포함돼 있음, 이외의 기능들은 항상 적절하지 않거나 개발에 불편하기 때문에 선택사항임(ex. HTTPS는 모든 웹 사이트에 적절하지 않을 수 있음)

 

체크리스트에 포함된 설정들

  • Django가 예상되는 보안 수준을 제공하도록 적절하게 설정되어야 함
  • 각 환경마다 다를 것으로 예상
  • 선택적 보안 기능을 사용 가능하게 함
  • 성능 최적화를 활성화 시킴
  • 오류 보고를 제공할 수 있도록 함

 

이러한 설정들은 대부분이 민감한 부분이기 때문에 기밀로 처리해야함

프로젝트의 소스 코드를 공개하는 경우, 일반적으로 개발에 적합한 설정을 게시하고 프로덕션용 개인 설정 모듈을 사용하는 것이 일반적임

 

다음 코드를 통해 검사를 자동화 할 수 있음

python manage.py check --deploy

 

중요 설정

SECRET_KEY

  • 큰 임의의 값이여야 하며, 비밀이 유지되어야 함
  • 프로덕션 환경(라이브 환경)에서 사용되는 키가 다른 곳에서 사용되지 않고, 소스 제어에 커밋되지 않도록 해야함
  • settings.py 에서 비밀 키를 하드코딩하는 대신, 환경 변수에서 로드하는 것을 고려

환경 변수 설정(Mac zsh 기준, 각 OS에 맞는 환경변수 설정을 통해 SECRET_KEY를 환경 변수로 등록)

# 원하는 텍스트 편집기 사용(vim, vi, vscode 등)
vim ~/.zshrc

# .zshrc에 아무 위치에 환경 변수 설정
export TEST_SECRET_KEY="비밀키 값"
# 저장 후 편집기 나오기

# 변경사항 적용
source ~/.zshrc

# 환경 변수 확인
echo $TEST_SECRET_KEY
# 설정한 값이 나오면 성공

settings.py에서 환경 변수 불러오기 

# 환경변수에서 비밀키 로드
import os
SECRET_KEY = str(os.environ.get('환경 변수 이름'))

# 또는 파일로 부터 환경 변수 로드

with open('환경변수가 저장되어있는 파일 경로') as f:
    SECRET_KEY = f.read().strip()

비밀키를 교체하는 경우 다음을 사용함

import os
SECRET_KEY = str(os.environ.get('CURRENT_SECRET_KEY')) # 새로운 비밀키
SECRET_KEY_FALLBACKS = [
    os.environ['OLD_SECRET_KEY'], # 이전 비밀키
]
  • SECRET_KEY_FALLBACKS이전 비밀 키가 적시에 제거되었는지 확인

 

 

디버그(Debug)

  • 프로덕션 환경에서는 settings.py의 디버그를 활성화 하지 말아야 함
  • DEBUGTrue일 경우
- 모든 데이터베이스 쿼리는 django.db.connection.queries 객체로 메모리에 저장됨
- 모든 404 오류는 Django의 특수 404 오류 웹 페이지에 의해 렌더링됨
- 이 페이지는 잠재적으로 민감한 정보를 포함하므로 공개적으로 노출되면 안됨
- Django 응용 프로그램에서 캐치되지 않은 예외는 Django 웹 페이지로 렌더링됨
- 404 웹 페이지보다 중요한 정보를 담고 있으므로 공개적으로 노출되면 안됨
  • DEBUG True는 Django는 신뢰할 수 있는 개발자만 웹 사이트를 사용한다고 가정
  • 인터넷에는 신뢰할 수 없는 사용자가 넘쳐나므로 배포전에 DEBUGfalse로 설정해야함

 

환경별 설정

ALLOWED_HOSTS

  • DEBUG가 False일 때 Django는 ALLOWED_HOSTS에 대한 적절한 값이 없으면 작동하지 않음
  • CSRF 공격으로 부터 웹 사이트를 보호하기 위해 필요
  • 와일드 카드를 사용하는 경우 Host HTTP 헤더에 대한 자체 검증을 수행하거나 그렇지 않으면 이 공격 범주에 취약하지 않은지 확인해야 함
  • 호스트 검증을 휘해 Django 앞의 웹서버도 구성해야함
    • Django에 요청을 전달하는 대신 정적 오류 페이지로 응답하거나 잘못된 호스트에 대한 요청을 무시해야함

 

CACHES

  • 캐시 사용 시 연결 파라미터가 개발 및 프로덕션 환경에 따라 다를 수 있음
  • 캐시 서버의 인증은 약한 경우가 많으므로 응용 프로그램 서버로부터의 연결만 수락하는지 확인함

 

DATABASES

  • DB 연결 개수는 개발 및 운영에서 다를 수 있음
  • DB 암호는 매우 중요하기 때문에 SECRET_KEY와 같이 보호 해야함
  • 최상의 보안을 위해 DB 서버는 응용 프로그램서버의 연결만 허용해야함
  • DB의 백업 설정은 반드시 설정해야함

 

EMAIL_BACKEND 및 관련 설정

  • 웹 사이트에서 전자 메일을 보내는 경우, 이 값을 올바르게 설정해야 함

 

STATIC_ROOT 및 STATIC_URL

  • 정적 파일은 개발 서버에서 자동으로 제공함
  • 프로덕션에서는 collectstatic이 복사할 STATIC_ROOT 디렉터리를 정의해야함

 

MEDIA_ROOT 및 MEDIA_URL

  • 미디어 파일은 사용자에 의해 업로드됨
  • 이 미디어 파일은 신뢰할 수 없음
  • 웹 서버가 미디어 파일을 해석하지 않도록 해야함

 

HTTPS

  • 사용자가 로그인 할 수 있도록 하는 웹 사이트는 액세스 토큰을 명확하게 전송하지 않도록 웹 사이트 전체의 HTTPS를 시행해야함
  • Django에서 액세스 토큰에는 로그인/암호, 세션 쿠키 및 암호 재설정 토큰이 포함됨
  • 동일한 세션 쿠키가 HTTP, HTTPS에 사용되므로 사용자 계정이나 관리자와 같은 민감한 영역을 보호하기 위해 웹 서버는 HTTP 트래픽을 HTTPS로 리디렉션해야하며 HTTPS 요청만 Django로 전송해야함

 

HTTPS를 설정했으면 다음 설정을 사용할 수 있음

 

CSRF_COOKIE_SECURE

  • 실수로 HTTP를 통해 CSRF 쿠키를 전송하지 않으려면 이 값을 True로 설정해야함

 

SESSION_COOKIE_SECURE

  • 실수로 HTTP를 통해 세션 쿠키를 전송하지 않으려면 이 값을 True로 설정해야함

 

성능 최적화

CONN_MAX_AGE

  • 영구 데이터베이스 연결을 사용할 수 있도록 요청 처리 시간의 상당 부분을 데이터베이스 계정에 연결할 때 속도가 향상됨
  • 제한된 네트워크 성능으로 가상화된 호스트에서 많은 도움이 됨

 

템플릿

  • 캐시된 템플릿 로더를 사용하면 렌더링 때마다 각 템플릿을 컴파일하지 않아도 되므로 성능이 크게 향상됨

 

오류 보고

로깅

  • 프로덕션 환경에 웹 사이트를 배치하기 전에 로깅 구성을 검토하고, 트래픽이 발생하자마자 예상대로 작동하는지 확인

 

ADMIN 및 관리자

  • ADMINS에 전자 메일로 에러를 통지함
  • 관리자는 404 에러를 통지 받음
  • IGNORABLE_404_URLS은 가짜 보고서를 걸러낼 수 있음
  • 이메일에 에러 보고서가 쇄도하기 전에 오류 모니터링 시스템을 사용하는것을 권장함

 

기본 오류 보기 사용자 정의

  • Django는 여러 HTTP 오류 코드에 대한 기본 보기 및 템플릿이 있음
  • 루트 템플릿 디렉터리에 404.html, 500.html, 403.html, 400.html 등의 템플릿을 작성하여 기본 템플릿을 대체 할 수 있음

 

 

프로덕션에 다른 설정 사용

지금까지 실습은 settings.py 파일 하나만 다뤘음, 개발 환경과 프로덕션 환경을 나눠서 각각 설정 파일이 필요함

다음과 같은 방법 중 하나를 수행하여 개발 환경 마다 다른 설정을 사용할 수 있음

  • 독립적인 2개의 설정 파일을 생성하고 설정
  • 기본 설정 파일(개발용)과 첫 번째 설정 파일을 가져와 정의할 필요가 있는 모든 오버라이드를 정의하는 두 번째 설정 파일(프로덕션)을 설정
  • 설정을 콘텍스트 기반으로 변경하려면 파이썬 로직이 있는 단일 설정 파일만 사용

 

대부분 첫번째 방법을 사용함

  • 먼저 settings 파일들이 저장될 폴더를 하나 만들고 그 안에 setting 파일들을 만들어 각각 설정(공통, 개발, 배포)을 설정함

python manage.py runserver --settings=파일 경로
# ex. local.py의 경우
# mysite.settings.local
# base.py
...

# settings 폴더를 하나 만들고 그 안에 넣었으므로 parent 하나를 추가해 경로를 수정 
BASE_DIR = Path(__file__).resolve().parent.parent.parent

...
# local.py

from .base import *
DEBUG = True

# ------------------------------------

# production.py

from .base import *
DEBUG = False
  • 다음과 같은 명령어를 통해 원하는 설정으로 서버 실행(local.py)
python manage.py runserver 8080 settings=mysite.settings.local

 

WSGI 배포

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

ASGI 배포

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

728x90
반응형

'Back-end & Server > Django' 카테고리의 다른 글

[Django] 캐시 프레임워크  (0) 2023.02.04
[Django] 비 HTML 콘텐츠와 세션  (0) 2023.02.01
[Django] 테스팅  (0) 2023.01.22
[Django] 고급 기능들  (0) 2023.01.20
[Django] 폼(Form)  (0) 2023.01.20