데비안에서 Django + nginx + uwsgi 설정 기록

데비안 6 버전을 기준으로 설명을 하겠다.

1. django 설치
1.2 버전은 apt 를 이용하여 설치.
1.3 버전 이상은 pip 를 이용하여 설치(static 파일에 관한 쉬운 설정 방식이 제공된다.)


2. nginx 설치
0.8 버전 이상부터 uwsgi에 관한 지원이 기본적으로 제공된다. 따라서 이를 설치하기 위해 /etc/apt/source.list 에 아래 저장소(nginx 저장소)를 추가하여 설치하면 된다.
deb http://nginx.org/packages/debian/ squeeze nginx
deb-src http://nginx.org/packages/debian/ squeeze nginx
그리고 설치 시에 저장소의 키가 인증되지 않아서 경고가 발생하는데, 이를 해결하려면 http://nginx.org/packages/keys/ 로부터 nginx_signing.key 를 받은 후, cat nginx_signing.key | sudo apt-key add - 를 하여 키를 추가해주자.
* 참고 자료: http://wiki.nginx.org/Install

* 주의 사항: nginx 0.7 버전의 경우 문제가 없지만, nginx 저장소를 이용하여 설치한 버전의 경우 nginx 를 삭제할 때 nginx 가 실행되지 않으면 삭제 진행이 안된다. 예를 들어, nginx 의 설정 파일이 없어서 실행이 안될 경우 오류가 발생한다. 또, nginx 가 사용할 포트가 이미 연결되어 있어서 nginx가 포트 연결을 하지 못할 경우 삭제가 안된다. 즉, nginx를 실행한 상태에서 삭제를 진행하는 경우에 깔끔하게 지울 수 있었다.


3. uwsgi 설치
데비안 7 버전부터 uwsgi 이 지원이 되고, 6 버전에는 패키지가 존재하지 않는다.
따라서 pip 를 통해서 uwsgi 를 설치하자. 이때, build-essential 과 python-dev, libxml2-dev 가 필요하다.
* 참고 자료: http://projects.unbit.it/uwsgi/wiki/Install

그리고 설치 후에는 컴파일이 되어 설치되므로, 이후에 pip uninstall을 하여도 실행 파일이 지워지지 않고 남는 현상이 있다.


4. django, nginx 및 uwsgi 설정
uwsgi 의 경우 init.d 에 실행 스크립트가 제공되지 않고, 직접 실행하는 방식으로 작동하기 때문에 서비스를 실행하고 중지하는데 불편하다.
그리고 단일 스크립트로 여러 어플리케이션을 실행하려면 복잡하므로, uwsgi 에서 제공하는 emperor 모드를 사용하기로 하였다.
* 참고 자료: http://projects.unbit.it/uwsgi/wiki/Emperor

먼저, init.d 에 uwsgi 스크립트를 추가하였다.
#! /bin/bash

### BEGIN INIT INFO
# Provides:          uwsgi
# Required-Start:    $network $remote_fs $local_fs 
# Required-Stop:     $network $remote_fs $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Stop/start uwsgi
### END INIT INFO

# Custom init.d script for uwsgi

NAME=uwsgi
PIDFILE=/pid/파일/경로/$NAME.pid
LOGFILE=/로그/파일/경로/$NAME.log
VASSALS=/uwsgi/하위/앱의/설정/파일이/있는/경로
DAEMON=/uwsgi/실행/경로
CHUID=<uwsgi을 실행시킬 UID>
CHGID=<uwsgi을 실행시킬 GID>

OPTION="--emperor $VASSALS --uid=$CHUID --gid=$CHGID --daemonize $LOGFILE --pidfile $PIDFILE --master"

case "$1" in
    start)
        echo -n "Starting $NAME: "
        start-stop-daemon --start --pidfile $PIDFILE \
            --exec $DAEMON -- $OPTION
        echo "Done."
        ;;
    stop)
        echo -n "Stoping $NAME: "
        start-stop-daemon --signal INT --stop --pidfile $PIDFILE \
            --exec $DAEMON -- $OPTION
        echo "Done."
        ;;
    restart)
        echo -n "Restarting $NAME: "
        start-stop-daemon --signal INT --stop --pidfile $PIDFILE \
            --exec $DAEMON -- $OPTION
        sleep 1
        start-stop-daemon --start --pidfile $PIDFILE \
            --exec $DAEMON -- $OPTION
        echo "Done."
        ;;
    *)
        echo "Usage: $NAME {start|stop|restart}"
        exit 1
        ;;
esac

exit 0
스크립트에서 "VASSALS=/uwsgi/하위/앱의/설정/파일이/있는/경로"의 경우 emperor 모드에서 각 앱들의 설정 파일이 존재하는 폴더로 지정해주면 된다.

예를 들어, 장고 프로젝트가 2개가 있어서 따로 실행을 해주어야 할 경우, uwsgi 설정 파일을 두 개를 만들고 이를 하나의 폴더에 넣은 다음, 그 폴더의 경로를 적어주면 된다.

그리고 스크립트를 추가한 후에 시스템의 종료 및 시작 시에 스크립트를 작동하기 위해서 sudo update-rc.d uwsgi defaults 명령을 내려주자.
* 참고 자료: http://www.mrj0.com/2011/05/06/outage/


uwsgi을 실행할 스크립트는 완료되었고, uwsgi를 위한 설정 파일을 추가하면 된다. 예를 들어,
[uwsgi]
socket = 127.0.0.1:포트번호
chdir = /장고/프로젝트/폴더/경로
pythonpath = /장고/프로젝트/폴더의/하위/경로
env = DJANGO_SETTINGS_MODULE=프로젝트 폴더 명.settings
module = django.core.handlers.wsgi:WSGIHandler()
master = true
workers = 2
이 외에 자세한 옵션은 아래를 참고하면 된다.
* 참고 자료: http://projects.unbit.it/uwsgi/wiki/Doc


uwsgi 설정은 모두 끝났다. 이제, nginx 설정을 하면 된다. nginx 설정은 매우 쉽다. 일반적인 설정 부분은 아래를 참고하자.
* 참고 자료: http://wiki.nginx.org/Configuration

uwsgi 을 사용하는 주요 부분의 설정은 아래와 같이 하면 된다.
location /url/경로 {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:포트번호;
}
포트번호는 설정 파일에서 적은 것과 같이 하면 된다.


이제 nginx 설정도 끝났다. 이제 실행만 하면 서버가 작동 한다.
sudo /etc/init.d/nginx start
sudo /etc/init.d/uwsgi start


추가로, 아파치의 mod-wsgi과는 다르게, location으로 지정한 정확한 url 주소가 django 앱으로 넘어간다.
mod-wsgi에서는 http://test.com/project 주소에 django 프로젝트를 지정해두면, urls.py에서 project 뒤부터 경로를 파악한다.
그러나 nginx에서는 project 부터 경로를 파악하므로, urls.py 에 r'^$' 주소의 경우 작동하지 않게 된다.

이를 간단히 해결하려면, extra_patterns라는 새로운 patterns를 만들고, urlpatterns에는 r'^project/', include(extra_patterns)를 하여 project 에 연결하는 방법을 사용하면 된다.


5. 참고 자료 정리
* http://wiki.nginx.org/Main
* http://projects.unbit.it/uwsgi/
* http://hako.04p.kr/?p=145
* http://www.mrj0.com/2011/05/06/outage/

댓글 없음:

댓글 쓰기