[Django] Launch WSGI in Apache Server

Django 是一個以 Python 為基底開發網站服務的框架,近年來越來越多開發人員使用 Python 語言,所以要切入網站或者是 API 的開發,Django 會是一個很好的選擇,之前檸檬爸初學 Django 寫過一篇初淺的介紹文,後來,真正在進入 Production 階段的時候遇到一些問題,本篇紀錄在部署 Django 到 Apache Server 上的時候遇到的挑戰。

部署 Django 建議使用 WSGI

在學習 Django 的時候,最快速實測的方法是利用 python3 manage.py runserver 的指令啟動 Django,但是一旦進入 Production,使用 Apache WSGI 模組部署 Django 將可以享受文章中提到的 Flexibility, Scalibility, Speed, Simple, Middleware Reuse 的好處。

直接放上成功在 CentOS 7 部署 Django 的 Apache 設定:

httpd.conf 設定:

由於 WSGI 是透過 python3.6 安裝的,所以記得要找到相對應的 moduel 位置將其加入到 httpd.conf 中。 

LoadModule wsgi_module "/usr/lib64/httpd/modules/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so"

vhosts 裡的 hostname.conf / hostname.ssl.conf 設定:

由於同一個 Apache Server 通常可以部署多個網站服務,所以我們在 /usr/local/apache/conf.d/vhosts 資料夾下面新增兩個檔案,鑑於安全性,我們只打算開放 https,因此在 hostname.conf 我們只填寫重新導向的設定如下:

<VirtualHost xxx.xxx.xxx.xxx:80>
	ServerName hostname
	Redirect / https://hostname/
</VirtualHost>

主要的設定都落在 hostname.ssl.conf 裡面:

<VirtualHost xxx.xxx.xxx.xxx:443>

    ServerName hostname
    ServerAlias www.hostname
    ServerAdmin xxx@gmail.com
    DocumentRoot /home/username/public_html/django-project
    UseCanonicalName Off

    CustomLog /usr/local/apache/domlogs/hostname.bytes bytes
    CustomLog /usr/local/apache/domlogs/hostname.log combined
    ErrorLog /usr/local/apache/domlogs/hostname.error.log

    WSGIDaemonProcess django-project python-path=/root/.local/share/virtualenvs/python36-PwlmGYJW/lib/python3.6/site-packages
    WSGIScriptAlias / /home/username/public_html/django-project/django-project/wsgi.py

    IncludeOptional "/usr/local/apache/conf/userdata/username/hostname/*.conf"

    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/hostname.cert
    SSLCertificateKeyFile /etc/pki/tls/private/hostname.key
    SSLCertificateChainFile /etc/pki/tls/certs/hostname.bundle
    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

    Alias /static /home/username/public_html/django-project/django-project/static/
    <Location "/static">
            SetHandler None
    </Location>

    WSGIProcessGroup %{GLOBAL}
    WSGIApplicationGroup %{GLOBAL}
    WSGIPassAuthorization On

    <Location "/secret">
        AuthType Basic
        AuthName "Top Secret"
        Require valid-user
        AuthBasicProvider wsgi
        WSGIAuthUserScript /home/username/public_html/django-project/django-project/wsgi.py
    </Location>

    <Directory "/home/username/public_html/django-project/django-project">
	<Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

</VirtualHost>
備註(以上展示的範例有幾個假設前提):
  1. 使用者的 django project 是利用以下的指令創建在 /home/username/public_html 的路徑上面,如果利用 django-admin 創建的專案 wsgi.py 會被自動創建在 django-project/django-project 的路徑上。
    django-admin startproject django-project
  2. django 會用到的相關模組是利用 pipenv 安裝在 
  3. 有關 SSL 的檔案放在 /etc/pki/tls/certs/ 之下
WSGIPassAuthorization On 記得開啟 !!

檸檬爸一開始這個 property 沒有設定到,結果就是一直沒有辦法通過 Django 原生的認證機制認證,卡超久。