Windows + Apache2.4 + mod_wsgiにて、virtualenvのDjangoをバーチャルホストで動かす

前回の記事では、Apache + mod_wsgiによるBottleのホストを行いました。

今回は、公式ドキュメントを参考にしながら、Djangoをバーチャルホストで動かしてみます。
How to use Django with Apache and mod_wsgi | Django documentation | Django

 
目次

 

環境

  • Windows7 x64
  • Apache 2.4.20 32bit版
    • C:\Apache24
  • mod_wsgi 4.5.2
  • Python 3.5.1 32bit版
    • C:\Python35-32
  • Microsoft Visual C++ 2015 再頒布可能パッケージ 32bit版
  • Django 1.9.6
    • 静的ファイルは各アプリのstaticフォルダに置き、collectstaticを使って配信

 

Djangoアプリの準備

# virtualenv環境へDjangoをインストール
D:\Sandbox\Django_Apache_hosting>virtualenv -p c:\python35-32\python.exe env
D:\Sandbox\Django_Apache_hosting>env\Scripts\activate
(env) D:\Sandbox\Django_Apache_hosting>pip install django

# Djangoプロジェクトとアプリを作成
(env) D:\Sandbox\Django_Apache_hosting>django-admin startproject myproject .
(env) D:\Sandbox\Django_Apache_hosting>python manage.py startapp myapp

 
ひな型ができたので、引き続きDjangoアプリを作成していきます。

D:\Sandbox\apache_django\myproject\settings.py

INSTALLED_APPS = [
...
    'myapp',
]
...
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_for_deploy')

 
D:\Sandbox\apache_django\myproject\urls.py

以前見たように、namespaceの設定に変更が入っているため、注意します。
URL dispatcher | Django documentation | Django

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^mysite/', include('myapp.urls', 'my')),
]

 
D:\Sandbox\apache_django\myapp\urls.py

from django.conf.urls import url
from .views import IndexView

urlpatterns = [
    url(r'^$', IndexView.as_view(), name='index'),
]

 
D:\Sandbox\apache_django\myapp\views.py

from django.views.generic import TemplateView

class IndexView(TemplateView):
    template_name = 'myapp/index.html'

 
D:\Sandbox\apache_django\myapp\templates\myapp\index.py

{% load staticfiles %}
<link href={% static 'css/common.css' %} rel='stylesheet'>

<h1 class="hello">Hello MyApp</h1>

 
D:\Sandbox\apache_django\myapp\static\css\common.css

各アプリの中にCSSなどの静的ファイルを作成します。

.hello{
    color: red
}

 
以上でDjangoアプリの実装は完了です。

ただ、このままではApacheで静的ファイルの配信が行われないため、collectstaticを使って、静的ファイルをSTATIC_ROOTに集めます。

(env) D:\Sandbox\Django_Apache_hosting>python manage.py collectstatic

You have requested to collect static files at the destination
location as specified in your settings:

    D:\Sandbox\Django_Apache_hosting\static_for_deploy

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: yes  # yesを入力
...
57 static files copied to 'D:\Sandbox\Django_Apache_hosting\static_for_deploy'.

 

Apacheでのホスト

ここまでで開発サーバでのホストができているため、Apacheでのホストを行います。

まずはmod_wsgi.soC:\Apache24\modulesへ保存します。

 

httpd.confの編集

mod_wsgiのロードと、バーチャルホスト用設定ファイルのIncludeを記述します。

C:\Apache24\conf\httpd.conf

...
LoadModule wsgi_module modules/mod_wsgi.so

Include conf/extra/httpd-vhosts.conf

 
mod_wsgiがロードされていることを確認します。

C:\Apache24\bin>httpd -M
Loaded Modules:
...
 wsgi_module (shared)

 

httpd-vhosts.confの編集
  • virtualenv設定
  • 静的ファイル配信設定
  • Djangoアプリ本体の設定

の設定を行います。

 

virtualenv設定

WSGIPythonPathディレクティブを使います。

Djangoプロジェクトのルートディレクトリと、virtualenvのsite-packages;で連結したものを設定します。
Using a virtualenv - How to use Django with Apache and mod_wsgi | Django documentation | Django

なお、バーチャルホストを使う場合は、バーチャルホスト設定の外側に記述します。

 

静的ファイル配信設定

AliasディレクティブとDirectoryディレクティブを使います。

Aliasディレクティブの引数について、

  • 第一引数はSTATIC_URLの値
  • 第二引数はSTATIC_ROOTの値 (+ 末尾スラッシュ(/))

をそれぞれ設定します。

なお、第二引数末尾のスラッシュについては、

もし url-path の最後に / を書いたなら、サーバがエイリアスを展開するためには、最後の / が必要になることに注意してください。すなわち、Alias /icons/ /usr/local/apache/icons/ というものを使用している場合は、 /icons という url はエイリアスされません。

Alias ディレクティブ - mod_alias - Apache HTTP サーバ バージョン 2.4

ということもあり、スラッシュで終わるようにします。今回の場合だと、"D:/Sandbox/Django_Apache_hosting/static_for_deploy/"となります。

 
Directoryディレクティブの引数には、STATIC_ROOTの値を設定します。

 
また、Windowsの場合、パスの区切り文字に\/の両方が(いちおう)使えそうなのですが、静的ファイル配信のDirectoryディレクティブで\を使った場合、静的ファイルが配信されませんでした。

Apacheの公式ドキュメントにも、

The directives that accept filenames as arguments must use Windows filenames instead of Unix ones. However, because Apache may interpret backslashes as an "escape character" sequence, you should consistently use forward slashes in path names, not backslashes.

Using Apache HTTP Server on Microsoft Windows - Apache HTTP Server Version 2.4

と書かれていたため、静的ファイルに限らず、/を使うよう統一したほうが良さそうです。

 

Djangoアプリ本体の設定

公式ドキュメントに従い、WSGIScriptAlias・Directory・Filesディレクティブを使います。

  • WSGIScriptAliasには、プロジェクトのwsgi.pyファイルパス
  • Directoryには、プロジェクトのルートディレクト

をそれぞれ設定します。

 
以上を踏まえたhttpd-vhosts.confファイルの中身は、以下の通りです。

C:\Apache24\conf\extra\httpd-vhosts.conf

WSGIPythonPath "D:/Sandbox/Django_Apache_hosting;D:/Sandbox/Django_Apache_hosting/env/Lib/site-packages"

<VirtualHost *:80>
    ServerName django
    
    ErrorLog "logs/django-error.log"

    # Django static files
    Alias /static/ "D:/Sandbox/Django_Apache_hosting/static_for_deploy/"

    # Directoryディレクティブでは、区切り文字が`\`だと静的ファイル配信が動作しない
    #<Directory "D:\Sandbox\Django_Apache_hosting\static_for_deploy">
    <Directory "D:/Sandbox/Django_Apache_hosting/static_for_deploy">
        Require all granted
    </Directory>
    
    # Django app
    WSGIScriptAlias / "D:/Sandbox/Django_Apache_hosting/myproject/wsgi.py"
    <Directory "D:/Sandbox/Django_Apache_hosting/myproject">
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>
</VirtualHost>

 
あとはApacheを再起動して、

へアクセスし、静的ファイルも含めた配信が行われているかを確認します。

 

ソースコード

GitHubに上げておきました。
thinkAmi-sandbox/Django_Apache_hosting-sample