Django Apache mod_wsgi 연동해보자 (CentOS 7) - 어렵지 않아요
Django 와 Apache 연동
Django 는 python 기반의 오픈소스 프레임워크이다. 웹 개발에 필요한 다양한 기능을 제공하고, 수많은 플러그인을 지원하기 때문에 인기가 높은 프레임워크 중 하나이다. 이번 포스팅에서는 웹서버 중 가장 많이 사용되는 Apache와 django를 연동하는 방법을 소개한다.
웹서버 연동 없이 Django 만 사용할 수 없나?
물론 단독으로 사용이 가능하다. django 에서 제공하는 runserver를 이용하면 된다.
root@~~# django-admin.py runserver <IP_ADDRESS>:<PORT>
그렇다면 왜 굳이 웹서버와의 연동이 필요한가?
Django가 제공하는 runserver 기능은 개발의 편의를 위해 테스트 목적으로 제공되는 기능이다. Django 측에서도 실제 서비스 환경에서는 runserver 기능을 이용하는 것을 권장하지 않는다. 안정성과 성능 측면을 고려하지 않은 기능이기 때문이다. multi threading 처리도 불가하며, audit 기능과 같은 보안에 관련된 기본 설정도 불가하다.
DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that’s how it’s gonna stay. We’re in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.)
[ Django 는 비지니스 로직 개발을 위한 web framework 를 목적으로 개발된 것이지, web server는 아니라는 설명 ]
따라서 실제 서비스 환경을 위해서는 반드시 HTTP 기반 요청을 처리해줄 웹서버를 이용하는게 좋다.
이번 예제는 웹서버 중 가장 많이 사용되는 apache를 사용한 설정 방법이다. 그리고 apache가 받은 요청을 django로 전달해주는 WSGI (Web Server Gateway Interface) 모듈로 mod_wsgi를 사용하는 방법을 소개한다.
참고로, OS는 CentOS 7 기준으로 작성하였다.
Django + Apache + mod_wsgi 설정 방법
1. Apache 설치
root@~~# yum install httpd
2. pip 설치
django 설치를 위해 pip를 설치한다.
root@~~# yum install python-pip
3. Django 설치
root@~~# pip install django
만약 버전을 지정하여 설치하고 싶다면, 아래와같이 "==" 을 붙이면 된다. 1.8버전을 설치하고 싶을 경우,
root@~~# pip install django==1.8
4. mod_wsgi 설치
mod_wsgi 는 웹서버에서 받은 요청을 django 같은 python application 으로 전달해주는 interface 역할을 하는 패키지이다. 웹서버를 apache로 사용할 경우, django 와 웹서버 연동을 위해 가장 많이 사용되는 패키지 중 하나이다.
설치는 아래와 같이 yum 으로 쉽게 가능하다.
root@~~# yum install mod_wsgi
5. Django 초기 프로젝트(project) 생성
Apache와 Django를 연동하기 전에 먼저 Django의 초기 프로젝트를 생성하여야 한다. Django는 프로젝트와 프로젝트 하위 app 이라는 단위로 동작하기 때문에 가장 기본 단위인 project 를 먼저 생성해 주어야 한다.
이번 설정에는 django 프로젝트의 Path를 /opt/ 아래로 해보기로 한다. (암때나 해도 상관없다)
먼저 /opt 디렉토리로 이동한다.
root@~~# cd /opt
프로젝트 생성은 Django에서 지원하는 django-admin 명령어를 이용하면 된다.
프로젝트 이름은 원하는 대로-
(여기서는 django_demo로 만들어 보았다.)
root@~~# django-admin startproject django_demo
프로젝트를 생성하면 /opt 디렉토리 밑에 django_demo 라는 디렉토리가 생겼음을 볼 수 있다.
django_demo 프로젝트의 디렉토리 구조를 보면 아래와 같다.
root@~~# tree /opt
/opt
└── django_demo
├── django_demo
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
이제 기본적인 준비는 되었으니 apache 설정을 해보자
6. apache 설정
/etc/httpd/conf.d 디렉토리 아래에 새로운 설정파일을 하나 만들자. 파일이름은 상관없다. (*.conf)
주의할 점은, /etc/httpd/conf/httpd.conf 설정 파일에 IncludeOptional 설정이 되어 있어야 한다.
설정 내용을 그냥 /etc/httpd/httpd.conf 에 추가해도 상관은 없지만, 파일 관리가 쉽도록 conf.d 에 분리해서 만드는게 좋다.
(여기서는 django.conf 로 만들어보았다)
root@~~# vim /etc/httpd/conf.d/django.conf
<VirtualHost *:80>
WSGIScriptAlias / /opt/django_demo/django_demo/wsgi.py
<Directory /opt/django_demo/django_demo>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
</VirtualHost>
위 설정 내용을 간단히 설명하면,
- 요청 url의 / 아래 모든 요청은 /opt/django_demo/django_demo/wsgi.py 를 호출하게 된다.
- 이 wsgi.py는 Django 프로젝트 생성시 자동으로 생성된 파일이다.
- wsgi.py 파일은 모든 접근을 allow 하도록 설정된다.
[추가 팁]
만약 이미지 파일이나 js나 css 같은 static 파일이 있을 경우 conf 파일에 static 파일 경로를 추가로 설정할 경우 쉽게 처리가 가능하다.
Django는 기본적으로 static 파일에 대한 접근을 허락하지 않으므로 따로 static 파일을 settings.py 에 설정하여 관리한다.
그렇지만, static 파일 같은 경우 굳이 wsgi를 통해 django로 오지 않아도 되므로
static 파일은 웹서버에서 처리해주는게 성능 상 더 이득이다.
아래와 같이 django 디렉토리 설정 전에 static 파일에 대한 설정을 해주면 된다.
물론 static 파일을 저장할 디렉토리는 새로 만들어서 설정하면 된다.
아래 예제에서는 /opt/django_demo/APP/static 으로 설정하였다.
<VirtualHost *:80>
Alias /static/ /opt/django_demo/APP/static/
<Directory /opt/django_demo/APP/static>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /opt/django_demo/django_demo/wsgi.py
<Directory /opt/django_demo/django_demo>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
</VirtualHost>
7. django wsgi.py 설정
wsgi.py 를 열어 아래와 같이 수정한다.
wsgi.py는 위에서 생성했던 django_demo 프로젝트 안에 있다. ( /opt/django_demo/django_demo/wsgi.py )
import os, sys
path = os.path.abspath(__file__+'/../..')
if path not in sys.path:
sys.path.append(path)
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_demo.settings")
application = get_wsgi_application()
8. apache 재시작
Apache를 재시작해 설정 내용을 반영한다.
root@~~# systemctl restart httpd.service
[참고]
- https://docs.djangoproject.com/en/1.9/ref/django-admin/#runserver