Django 웹 서버 연동 원리

jurin·2021년 8월 18일
0

개발한 것을 실제로 서비스하기 위해선 개발한 프로그램을 운영 환경에 배포하고 실행해야 한다. 개발 환경에서 운영 환경으로 옮겨가기 위해선 개발 시 지정했던 설정 사항을 변경해줘야 하고 운영 환경의 웹 서버에서도 만든 애플리케이션을 인식할 수 있도록 설정 사항 변경이 필요하다.

장고의 wsgi.py 파일

startproject 명령어를 통해 프로젝트의 뼈대를 만들 때 wsgi.py 파일이 만들어진다. 이 모듈이 장고와 웹 서버를 연결하는 데 필요한 파일WSGI 규격에 따라 호출 가능한 애플리케이션 객체를 정의하고 있다.

객체명은 반드시 application이어야 한다.
장고의 wsgi.py 파일

application = get_wsgi_application()

application 객체는 아파치와 같은 운영 웹 서버 뿐만 아니라 runserver에서도 같이 사용하는 객체다. 다른 점은 application 객체의 위치를 지정하는 방식으로 아파치나 NGINX/uWSGI 설정 파일에서 지정하고, 즉 httpd.conf 설정 파일의 WSGIScriptAlias 지시자 또는 uwsgi.ini 설정 파일의 module 항목으로 지정하고, 개발용 runserver에서는 settings 모듈의 WSGI_APPLICATION 변수로 지정한다.

웹 서버는 이 application 객체를 호출하여 장고의 애플리케이션을 실행하는데 그 전에 현재의 장고 프로젝트 및 프로젝트에 포함된 모든 애플리케이션에 대한 설정 정보를 로딩하는 작업이 필요하다.

설정 정보는 담고 있는 settings 모듈의 위치를 아래와 같이 wsgi.py 파일에서 지정해준다.

import os

from django.core.wsgi import get_wsgi_application

# settings 모듈의 위치를 testsite/wsgi.py 파일에서 지정함
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testsite.settings')

application = get_wsgi_application()

장고의 WSGI 인터페이스

운영 환경에서는 NGINX와 같은 웹 서버 프로그램이 클라이언트 요청을 수신하므로, 요청을 수신한 웹 서버가 uWSGI와 같은 WAS 서버를 통해 장고 웹 애플리케이션을 호출할 수 있어야 한다.

  • 웹 서버: Apache httpd 또는 nginx와 같은 웹 서버 프로그램
  • 웹 애플리케이션 서버: uwsgi, gunicorn과 같은 WAS 서버 프로그램

장고는 파이썬 웹 애플리케이션을 만들어주는 프레임워크라고 할 수 잇다. 그래서 장고로 만든 프로그램은 WAS 서버에서 호출될 수 있도록 WSGI 규격을 준수해야 하는데 startproject 명령을 실행하면 자동으로 생성되는 wsgi.py 파일이 이 역할을 한다.

testsite/wsgi.py

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

~/site-packages/django/core/wsgi.py

def get_wsgi_application():
	return WSGIHandler()

WAS 서버가 장고 애플리케이션의 wsgi.py 파일을 호출하여 WSGIHandler 객체를 얻을 후 다시 호출해서 최종 응답을 생성하고 이를 웹 서버에 돌려주는 것이다.

정리!
장고 : 웹 애플리케이션을 만들어주는 프레임 워크로 WSGI 규격의 애플리케이션 스펙을 구현하기 위해 wsgi.py 파일 제공
WSGI 서버 : application(wsgi.py 파일에서 정의) 호출자(장고에서는 이 호출자를 WSGIHandler 클래스로 정의)를 호출.

WAS 서버가 장고 애플리케이션을 실행하기 위해서는 application 호출자가 정의된 wsgi.py 파일의 위치를 알아야 한다. 그래서 아파치, NGINX, uWSGI 등의 웹/WAS 서버의 설정 파일에는 application 호출자의 경로가 정의되어야 한다.

개발용 웹 서버인 runserver도 WSGI 규격에 따라 application 호출자를 호출하는데 settings.py 파일에 정의된 WSGI_APPLICATION 항목으로 호출자의 경로를 파악한다.

운영 서버 적용 전 장고의 설정 변경 사항

운영 서버에서 필요한 항목들이 제대로 설정되었는지 체크하는 명령이 있다. 운영 서버에 배포한 이후에는 아래 명령으로 설정 파일을 확인할 수 있다.

python manage.py check --deploy

SECRET_KEY는 개발 모드에서는 settings.py 파일에 하드코딩되어 있는데 이 항목은 프로젝트 내에서 암호화가 필요할 때 사용되는 항목으로 외부에 노출되면 안된다. 따라서 운영 모드에서는 환경 변수에 저장하거나 파일에 저장한 후 settings.py에서 아래처럼 부르는 게 좋다.

# SECURITY WARNING: keep the secret key used in production secret!
# SECRET_KEY = 'ixf!t98=p4ymrbua(!2nqar$qdysf-gs)7b_$v2spz(uoa27$3'
# SECRET_KEY = os.environ['SECRET_KEY']
# 또는 
with open(os.path.join(BASE_DIR, 'www_dir', 'secret_key.txt')) as f:
    SECRET_KEY = f.read().strip()
# SECURITY WARNING: don't run with debug turned on in production!

개발 모드에서는 에러 발생 시 디버그를 위해 브라우저에서 여러 가지 정보를 출력해서 보여주는데 이 정보는 프로젝트에 관련된 중요 정보들이므로 운영 모드에서는 settings 모듈의 DEBUG 값을 False로 셋팅하여 노출되지 않도록 해야한다.

DEBUG = False

DEBUG = False로 설정되어 있으면 반드시 settings 모듈의 ALLOWED_HOSTS 항목을 설정해야 한다. 악의적인 공격자가 HTTP Host 헤더를 변조하여 CSRF 공격하는 것을 방지하기 위해서이다. 장고가 실행되는 서버의 IP 주소나 도메인 명을 등록한다.

ALLOWED_HOSTS = [ '192.168.56.101' ]

개발 서버에서는 이미지, jsp, CSS 등의 정적 파일들을 알아서 찾아줬지만 운영 모드에서는 아파치와 같은 웹 서버에게 정적 파일들이 어디에 있는지 알려줘야 한다. settings 모듈의 STATIC_ROOT 항목은 장고의 collectstatic 명령 실행 시 정적 파일들을 한곳에 모아주는 디렉토리이다.

STATIC_ROOT = os.path.join(BASE_DIR, 'www_dir', 'static')

collectstatic 명령은 settings 모듈의 STATICFILES_DIRS 항목에, STATIC_ROOT 항목에서 정의된 디렉토리가 포함되면 안된다는 것을 주의해야 한다. STATICFILES_DIRS 항목에 정의된 디렉토리에서 정적 파일을 찾아 STATIC_ROOT 디렉토리에서 복사해주기 때문이다.

$ python manage.py collectstatic

개발 모드에서는 runserver를 실행시킨 사용자의 권한으로 DB 파일이나 로그 파일을 엑세스한다. 그러나 운영 모드에서는 프로세스의 소유자 권한으로 해당 파일을 엑세스할 수 있어야 한다. settings 모듈의 DATABASES 항목에서 NAME속성값의 경로를 db/db.sqlite3로 변경해주고 해당 디렉토리 및 파일의 엑세스 권한을 아래처럼 변경해준다.

DATABASES = {
	...
    'NAME': os.path.join(BASE_DIR, 'db', 'db.sqlite3'),
}
mkdir db
mv db.sqlite3 db/
chmod 777 db/
dhmod 666 db/db.sqlite3

웹 환경에서는 캐시 서버와 DB 서버가 사용되는 경우가 많은데 이들 서버는 보안 기능이 취약하므로 외부에서 직접 엑세스하지 않고 웹 서버 또는 WAS 서버에서만 연결하도록 제한하는 게 좋다.

또한 DB 접속 패스워드도 개발 모드에서는 settings.py 파일에 하드코딩되어 있는데 운영 모드에서는 다른 곳에서 저장해야 한다.

프로젝트에 메일을 발송하는 기능이 있다면 장고는 발신자 주소를 디폴트로 root@localhost 및 webmaster@localhost로 지정한다. SERVER_EMAIL 및 DEFAULT_FROM_EMAIL 설정 항목을 사용해 발신자 주소를 변경하는 게 좋다.





출처: Django로 배우는 파이썬 웹 프로그래밍(기초) - 김석훈님

profile
anaooauc1236@naver.com

0개의 댓글