2014-06-10

Centos6.x 下 Apache2.2 + mod_wsgi + django embedded mode 之安裝設定(無廢話)

前言
Django 要能透過 mod_wsgi 結合 Apache 正常運作首先
1. 你必需要安裝好 Apache
2. 你必需要安裝好 Python, 請參考這篇
3. Apache 必需安裝好 mod_wsgi, 請參考 這篇

安裝 Django
接下來就是安裝 Django, 安裝方法很簡單, 指令如下(這裡我是雙系統, python/pip, python3.3/pip3.3, 請依自己環境使用 pip 或pipx.x)
#pip3.3  install  django




創建 Django Sample Site
假設你的 www document root 是在 /var/www
在這裡建議你不要將 django 的 site 創建在 /var/www 下, 我建議你放在非 document root 的資料夾下, 例如 /var/django

建立目錄
#cd /var
#mkdir django
#cd django

產生sample site "mysite"
#django-admin.py startproject mysite
這樣子我們便在 /var/django下創建一個叫 mysite 目錄的 Django 專案(sample site)


Config Apache -> Django
有了 Django sample site, Django sample site, 接下來我們就是要將他們兩者連結起來

這裡我使用的 Apache 是 2.2 版, 在 Apache2.2 httpd.conf 裡有一段

#    
# Load config files from the config directory "/etc/httpd/conf.d".

Include conf.d/*.conf

這行設定是很方便的, 因為這代表若是你有不同模組的 config 要設, 你可以在 conf.d 目錄下開一個任意檔名, 附屬檔名為 .conf 的檔案用來作為你的設定檔

我們就到 conf.d 下創建一個 django.conf 的檔案
# cd /etc/httpd/conf.d/
# nano django.conf

並在該檔案新增下列內容, 存檔離開


# load mod_wsgi
LoadModule wsgi_module modules/mod_wsgi.so

WSGIScriptAlias  /   /var/django/mysite/mysite/wsgi.py
WSGIPythonPath   /var/django/mysite

<VirtualHost *:80>
    ServerName  127.0.1.1
    LogLevel debug

    <Directory "/var/django/mysite/mysite">
        <Files wsgi.py>
        Order deny,allow
        Allow from all
        </Files>
    </Directory>
</VirtualHost>





重啟 Apache
設定好之後只要重啟 apache 即可
# apachectl restart

這時候你可以打開 Browser, 鍵入 IP 即可看到 "It Worked!" 頁面




其它問題

若是你遇到問題, 而且檢查 Apache Log 看到類似底下錯誤訊息
[info] [client xxx.xxx.xxx.xxx] mod_wsgi (pid=4194, process='', application='ip-xxx-xxx-xxx-xxx'): Loading WSGI script '/var/django/mysite/mysite/wsgi.py'.
[error] [client xxx.xxx.xxx.xxx] mod_wsgi (pid=4194): Target WSGI script '/var/django/mysite/mysite/wsgi.py' cannot be loaded as Python module.
[error] [client xxx.xxx.xxx.xxx]   File "<frozen importlib._bootstrap>", line 853, in _load_module
[error] [client xxx.xxx.xxx.xxx]   File "<frozen importlib._bootstrap>", line 977, in get_code
[error] [client xxx.xxx.xxx.xxx]   File "<frozen importlib._bootstrap>", line 1031, in get_data
[error] [client xxx.xxx.xxx.xxx] PermissionError: [Errno 13] Permission denied: '/usr/local/lib/python3.3/site-packages/django/__init__.py'


或者是這樣的訊息
[error] [client xxx.xxx.xxx.xxx] (13)Permission denied: access to / denied

這代表是權限問題, 權限問題有三種
1. Apache 權限 - 就是 <Directory> Tag 內容設定
2. 檔案系統權限 - chmod 755 , 請檢查
3. Centos 下的 SELinux 權限, 檢查一下 SELinux 的權限是不是被啟用
# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing    <== SELinux 被啟動了, 這會造成 www document root 目錄外的檔案不能被執行
Mode from config file:          enforcing 
Policy version:                 24
Policy from config file:        targeted

請關閉 SELinux , 然後重新 refresh Browser 再試試
# setenforce 0

若是成功, 你必需要實質改掉系統的 SELinux 參數設定才行
將它設為 disabled 或 permissive, 如下所示, 並重啟 linux 試試是否不會因為系統重開後 SELinux 又被啟動了
#nano /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
#SELINUX=enforcing
SELINUX=disabled
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted



當然 SELinux 是可以設定的, 有興趣可參考這裡



如果你遇到 logs 裡有這個錯誤訊息:client denied by server configuration xxxxxxxxx/wsgi.py
這是因為
在 apache2.4 裡權限設定語法已經改了,請把 Allow from all 改用 Require all granted
    <Directory "/var/www/urdocroot/">
        <Files wsgi.py>
        Order deny,allow
        #Allow from all   
           Require all granted
        </Files>
    </Directory>



Daemon Mode
Django Daemon Mode 跟 Embedded Mode 是類似的, 若要詳細設定請參考官網 https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/modwsgi/#using-mod-wsgi-daemon-mode

底下提供我 Daemon Mode 的 config 檔, 供參考
主要問題在於 Apache Log 目錄有權限保護, 無法讓 Socket App 存取, 解決這個問題很簡單, 在 Linux 下本來就有個 run time directory, 讓程式暫存之用, 即 /var/run, 故只要設個 WSGISocketPrefix 參數指向 run time temp dirctory即可



# load mod_wsgi

LoadModule wsgi_module modules/mod_wsgi.so

WSGISocketPrefix /var/run/wsgi


<VirtualHost *:80>
    ServerName  127.0.1.1
    LogLevel debug
    WSGIDaemonProcess foo user=apache group=apache python-path=/var/django/mysite:/usr/local/lib/python3.3/site-packages/
    WSGIProcessGroup foo     

    WSGIScriptAlias  /   /var/django/mysite/mysite/wsgi.py

    <Directory "/var/django/mysite/mysite">
        <Files wsgi.py>
        Order deny,allow
        Allow from all
        </Files>
    </Directory>
</VirtualHost>





沒有留言:

張貼留言