삽질도 두드려 보고,

DESIGN YOUR EXPERIENCE

mod_wsgi 연동

토픽 삽질도 두드려 보고, > 서버 프로그래밍 > Apache HTTPD for Windows

개요

 WSGI(Web Server Gateway Interface)는 Python 애플리케이션과 웹 서버의 인터페이스 역할을 하는 규격이다. Python에는 레거시 CGI를 지원하는 모듈(import cgi)이 존재하나 더 효율적인 구조로 설계되어 성능이 향상된 WSGI 기술을 사용하는 것이 바람직하다. WSGI 규격을 기반하여 만들어진 WAS는 mod_wsgi, uWSGI, Gunicorn이 있다. 이 문서에서는 mod_wsgi 모듈을 Apache와 연동하는 과정을 설명한다.

환경변수 설정

 Apache가 Python 라이브러리 및 모듈 폴더를 찾을 수 있도록 환경변수 PYTHONPATH를 등록한다.

C:\Program Files\Python37\Lib\;C:\Program Files\Python37\DLLs\
 환경변수를 지정하지 않을 시 Apache 오류 로그에 Fatal Python error: initfsencoding: unable to load the file system codec ModuleNotFoundError: No module named 'encodings' 또는 ModuleNotFoundError: No module named '_socket'로 기록된다.

mod_wsgi 컴파일

 mod_wsgi 모듈을 직접 컴파일하거나, 또는 비공식 컴파일된 모듈을 다운로드하는 두 가지 방법을 소개한다. 간단히 모듈을 다운로드 받으려면 이 과정은 생략하도록 한다.

 mod_wsgi 모듈을 컴파일 하기 위해선 C++ 컴파일러가 필요하다. Visual Studio 다운로드 페이지에서 'Visual Studio 2019용 Build Tools' 메뉴에서 다운로드할 수 있다. Build Tools Installer를 실행한 후 Visual C++ 빌드 도구를 선택하고 오른쪽에 보이는 체크 요소들을 추가로 선택하여 설치한다.

 예상 설치 용량은 약 5GB. 설치가 완료되면 pip install mod_wsgi를 실행한다.

 Python 가상환경에서 실행한다면 Python 설치 디렉터리에서 libs 폴더를 복사하여 가상환경 디렉터리의 Scripts 폴더안에 복사한 후 진행한다.

 성공적으로 설치되었으면 mod_wsgi-express 명령어가 동작한다. Windows 환경에서는 WSGI 내장 테스트 서버(mod_wsgi-express start-server)를 지원하지 않는다. mod_wsgi-express module-config 실행 시 Apache 설정 파일에 등록할 구문이 출력된다.

 그대로 복사해서 사용해도 상관없으나 Apache 설치 디렉터리의 modules 폴더에 복사해서 사용해도 된다. 다음은 Apache 환경설정 파일(httpd.conf)에서 모듈을 로드하는 구문이다.

LoadModule wsgi_module modules/mod_wsgi.cp37-win_amd64.pyd

mod_wsgi 다운로드

 mod_wsgi 모듈의 Windows 바이너리는 공식적으로 제공하지 않는다. 캘리포니아대학교, Fluorescence Dynamics 연구실에서 비공식으로 컴파일된 바이너리를 제공한다. *.whl 파일을 압축 해제하면 *.pyd 파일을 찾을 수 있다. Apache 설치 디렉터리의 modules 폴더에 복사한 후 Apache 환경설정 파일(httpd.conf)에서 모듈을 로드하는 구문을 추가한다.

LoadModule wsgi_module modules/mod_wsgi.cp37-win_amd64.pyd

연동 환경설정

 Apache에서 mod_wsgi 모듈을 내장모드로 연동하여 가상호스트 설정하는 예제이다.

# 가상환경을 사용한다면 가상환경 경로를 지정해준다. 그렇지 않다면 Python 설치 디렉터리를 지정한다.
# 여러 가상 호스트에서 사용할 Python 가상환경 경로를 지정한다.
WSGIPythonHome "${SRVROOT}/htdocs/venv"
<VirtualHost *:80>
    ServerName example.com
    Define PUBDIR "<PROJECT-ROOT-DIRECTORY>"
# Apache가 wsgi.py을 액세스할 수 있도록 경로 지정과 권한 설정을 해야 한다.
    WSGIScriptAlias / "${SRVROOT}/htdocs/${PUBDIR}/<PROJECT-DIRECTORY>/wsgi.py"
    <Directory "${SRVROOT}/htdocs/${PUBDIR}/<PROJECT-DIRECTORY>">
        <Files "wsgi.py">
            Require all granted
        </Files>
    </Directory>
# 정적 파일에 대한 경로 지정과 권한 설정을 한다.
    Alias /static "c:/apache24/htdocs/${PUBDIR}/<COLLECTSTATIC-DIRECTORY>"
    <Directory "c:/apache24/htdocs/${PUBDIR}/<COLLECTSTATIC-DIRECTORY>">
        Require all granted
    </Directory>
</VirtualHost>

 wsgi.py 파일을 열어 PYTHONPATH 값을 추가한다.

 Apache 환경설정 파일에서 WSGIPythonPath 지시자를 지정할 수도 있으나 여러 Python 웹 프로젝트를 가상 호스팅할 경우 중복 선언되므로 각 프로젝트마다 wsgi.py 파일을 수정하는 방법을 사용한다.
import sys

sys.path.append('C:/Apache24/htdocs/<PROJECT-ROOT-DIRECTORY>')

 마지막으로 Apache 서버를 완전히 종료한 후 다시 시작한다.

httpd -k stop
httpd -k start

 정상적으로 앱이 실행되지 않는다면 Apache 오류 로그를 참조한다.

댓글

댓글 본문
  1. loopback.kr
    안녕하세요. 환경변수 경로를 다시 한번 확인해보시겠어요? 모듈을 찾지 못해서 오류가 발생하는 것으로 보아, Python 가상환경의 경로 및 아파치 가상호스트에서 명시한 경로를 확인해봐야 할 것 같습니다.
    대화보기
    • 산마로
      윈도우 10에서 anaconda를 이용하여 가상환경 python 3.7 을 만들어서 사용하는 경우에는 mod_wsgi 설치를 어떻게 해야 하나요? apache 만 설치해서는 잘 실행되는데, mod_wsgi를 설치를 하려는데, 계속 문제가 발생합니다.
      인터넷 게시글들을 따라서 실행하는데, 계속
      Fatal Python error: initfsencoding: unable to load the file system codec
      ModuleNotFoundError: No module named 'encodings'
      가 errors.log에 기록됩니다.