Django - WSGI에 대해서 알아보기

|

패스트캠퍼스 웹 프로그래밍 수업을 듣고 중요한 내용을 정리했습니다.
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


WSGI

앞서 collectstatic을 통해서 .static를 만들었으나 아직 우리는 웹 서버를 셋팅한 적이 없다.

그동안은 우리가 요청을 하면 아래처럼 이루어졌다.

- runserver
Browser -> EC2 -> Django

그러나 이제는

-WebServer, WSGI
Browser -> EC2 -> WebServer -> (Static)  -> STATIC_ROOT
                               (Dynamic) -> WSGI -> Django

아래같이 실행되도록 해야한다. 즉,

1. /static/이라는 요청 다음에는 STATIC_ROOT 경로에서 파일을 리턴하도록 해줘야 하고
2. 그 외의 URL요청은 Django가 처리 후 Response하도록 해야한다.

이때 Webserver는 Nginx라는 프로그램을 통해 사용할 것이며, WSGI는 uWSGI라는 프로그램을 사용할 것이다.

이제 우리가 해볼 것은 uWSGI를 통한 배포이다.

- runserver (지금까지 했던 과정)
Browser -> EC2 -> Django
---------------------------------------------여기까지 해본거,,

- uWSGI
Browser -> EC2 -> uWSGI -> Django

- Nginx, uWSGI
Browser -> EC2 -> Nginx -> uWSGI -> Django

따라서 WSGI(WebServer Gateway Interface)는 웹서버와 웹 어플리케이션의 인터페이스를 위한 파이선 프레임워크로 즉, Nginx와 Django가 동작하기 위해서 가운데서 중개해주는 인터페이스를 뜻한다.

웹서버는 외부에서 요청을 받아 리턴해주는데에 (정적파일) 특화가 되어있는데, 동적파일을 리턴해주려면 이를 django가 처리할 수 있는 명령어로 바꿔줘야 한다.

웹서버에서 어플리케이션으로 연결이 될때 어떻게 해야하는지에 대한 정의

근데 이 중간에 wsgi를 사용함으로써 어떤 인터페이스이건 간에, 이 인터페이스에 맞는 요청을 보내면 인터페이스가 그에 맞는 애플리케이션쪽으로 요청을 보내준다. (요청을 해석하는 애가 존재한다고 보면 된다.)

uwsgi설치

pipenv install uwsgi

which uwsgi를 통해 uwsgi의 위치를 파악해본다.

/Users/jihye/.local/share/tirtualenv/ec2-deploy-~/bin/uwsgi

쉘에서 uwsgi를 실행하면 실행과 동시에 종료가 되는데, 이게 uwsgi에 어떤 옵션을 줘서 그 옵션을 통해 장고를 실행해야 Django다.

Django를 실행한다는 것은 Django는 서버 어플리케이션으로 해당 프로그램 내로 어떤 입력을 보냈을 때 출력만 보내느게 된다.

즉, 이는 Django를 하나의 함수라고 생각하는 건데, 그 함수가 계속 작동할 수 있도록 외부에서 연결을 받아주는애가 필요하고, 그 동안은 그 역할은 runserver가 했다. 근데runserver는 개발서버로 개발 용이성을 위해서 굳이 Nginx, uwsgi에 연결하지 않더라도 그 결과를 보기 위해서 존재했던 것이고, 그걸 이제 Nginx가 받는다면, 즉 그 Nginx와 어플리케이션을 uwsgi를 가지고 연결을 시켜달라고 하면 그때 다시 장고를 실행시킬 수 있어야 한다.

- runserver
Browser ->  -> Django(runserver:8000)

- uWSGI
Browser -> local -> uWSGI:8000 -> Django

- Nginx, uWSGI
Browser -> local -> Nginx -> uWSGI:80 -> Django

uWSGI 정상 작동 확인

uwsgi \  
--http :(port) \  # 원래 uwsgi는 http요청을 잘 받지 않고 이는 웹서버가 많이하는데, 임의로 받도록 설정/ 어떤 port에서 받을지
--home (virtualenv경로) \  # home은 python home, 현재 python의 virtualenv를 어디를 쓰고 있는가
--chdir <django프로젝트 경로> \  # uwsgi가 실행하는 어플리케이션이 존재하는 프로젝트 경로
-w <설정 패키지명>.wsgi   # wsgi모듈로, 어플리케이션과 wsgi을 연결하는 중간 모듈을 설정

다시 쉘로 돌아가서 설정해보면

uwsgi \
--http :8000 \
--home /Users/jihye/.local/share/virtualenvs/ec2-deploy-Zes3c7vB \  # pipenv --venv로 확인
--chdir /Users/jihye/projects/deploy/ec2-deploy/app \  # pwd로 확인 + /app
--module config.wsgi

만약 uwsgi를 실행할때 runserver가 켜져있어 실행되지 않는다면

DEBUG = True
killall uwsgi를 실행하고 다시 명령어를 입력하면 된다.

혹은
lsof -i:8000
lsof -t -i:8000

kill -9 -t -i:8000

참고, settings.py/ wsgi.py에서 application이 존재하면 위와같이 실행이된다.

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

application = get_wsgi_application()

이때 위 uwsgi와 runserver가 다르게 실행되는 것을 확인해보자 (localhost:8000, localhost:8001)

그런데 우리가 항상 uwsgi를 실행하기 위해 저 긴 명령어를 기억해서 실행하기는 너무 귀찮다. 그러니까 .config폴더를 만들어본다.

.config/uwsgi.ini(plugin/ini4Idea)

[uwsgi]
;파이썬 프로젝트로 change directory
chdir = /Users/jihye/projects/deploy/ec2-deploy/app
;가상환경 경로
home = /Users/jihye/.local/share/virtualenvs/ec2-deploy-Zes3c7vB
;chdir로 바꾼 파이썬 프로젝트에서 wsgi모듈의 경로(path가 아닌 파이썬 모듈 경로)
module = config.wsgi:application

;http연결을 받으며, 8000번 포트로부터 받음
http = :8000