revision-up-to: | 17812 (1.4) |
---|
Warning
mod_python のサポートは非推奨となっており Django 1.5 で取り除かれる予定 です。新しいデプロイ設定をするなら mod_wsgi または他の サポートされている サーバ を使うことを強くお勧めします。
Apache の mod_python モジュールを使えば、本番環境で Django をデプロイで きます。ただし、この方法は、よりシンプルな mod_wsgi による運用 を使う方法に取 って代わられつつあります。
mod_python は mod_perl とよく似ていて (影響を受けていて)、 Apache の中に Python を埋め込み、サーバ起動時に Python のコードをメモリ上に読み込みます。 読み込まれたコードは Apache のプロセスが生きている間ずっと残るので、他のや りかたに比べて明確なパフォーマンスの向上につながります。
Django を mod_python で動かす場合、 Apache 2.x と mod_python 3.x が必要です。 また、 Apache を使う場合、 worker MPM ではなく prefork MPM を使うよう 勧めます。
See also
Django を mod_python で動かすようにするには、まず Apache がインストールされ、 mod_python モジュールが有効になっていることを確かめます。
次に、 httpd.conf
ファイルを編集し、以下のような設定を追加します:
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
</Location>
mysite.settings
は、 Django プロジェクトの設定ファイルを指す Python
import パスになるよう、自分の環境に合わせて置き換えて下さい。
この設定は、 Apache に 「/mysite/ の下の全ての URL は mod_python で処理し、 処理には Django mod_python ハンドラを使うように」命令します。また、 DJANGO_SETTINGS_MODULE を渡して、 mod_python にどこに設定ファイルがあるのか教えます。
mod_python は、サイトを /mysite/
プレフィクスの下で提供していることを自
動的に検出できないので、 PythonOption django.root ...
を使ってハンドラ
に通知してやる必要があります。この行に設定する値は、 <Location ...>
の引数と一致していなければなりません。 django.root
を設定すると、
Django はリクエストの URL から django.root
に設定されたプレフィクスを除
去した上で URLConf
のパターンマッチングを行います。このため、後でサイト
を /mysite2
に動かした際に、 djnago.root
だけを変更すればよくなりま
す。
django.root
を使う場合、必ず、プレフィクスを除去した後の URL がスラッシュ
で開始するようにしてください。 そうでないと、先頭にスラッシュの入る URLConf
の設定があった場合、パターンマッチングがうまくいきません。上の例では、
/mysite/admin/
を /admin/
に変えたいので、先頭から除去すべきなのは
/mysite
です。従って、 django.root
の値を /mysite
にしているの
です。この場合、 /mysite/
(末尾にスラッシュがついている) にしてしまうと、
エラーをひき起こすでしょう。
上の例では <Directory>
ではなく <Location>
ディレクティブを使って
います。前者はファイルシステム上の場所を指定するのに使い、後者はウェブサイ
トのURL 構造上の場所を指定するのに使います。従って、 <Directory>
を使っ
た指定は意味をなさないのです。
また、 Django プロジェクトがデフォルトの PYTHONPATH
上になければ、以下
のような設定を mod_python に教えておく必要があります:
<Location "/mysite/"> SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE mysite.settings PythonOption django.root /mysite PythonDebug On PythonPath "['/path/to/project'] + sys.path" </Location>
PythonPath
には、アプリケーションから import したいモジュールの各々の
親ディレクトリを入れなければなりません。また、 DJANGO_SETTINGS_MODULE の親ディレクトリも入れねばなりません。対話シェル
を使う場合に Python パスを設定するのと同じです。何かモジュールを import す
る際には、Python は必ず sys.path
の各ディレクトリを順に調べ、その下から
該当モジュールを import しようと試み、 import に成功するまで探索を続けます。
ところで、Python のソースファイルのパーミッションが、 Apache のプロセスを駆
動しているユーザ (たいていのシステムでは apache
とか httpd
というユー
ザ名がついている) から読み出せるように設定されているか確かめておいてください。
さて、分かりやすくするために例を挙げましょう。アプリケーションを
/usr/local/django-apps/
の下に配置しているとします (例えば、
/usr/local/django-apps/weblog/
のようにです) 。そして、設定ファイルが
/var/www/mysite/settings.py
だったとします。上の例のように
DJANGO_SETTINGS_MODULE を設定しているなら、
PythonPath
は以下のように書かねばなりません:
PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path"
これで、 import weblog
と import mysite.settings
は両方とも正しく実
行できます。コード中で import blogroll
していて、 blogroll
が
weblog/
ディレクトリの下にあるのなら、
/usr/local/django-apps/weblog/
も PythonPath
に加えねばなりません。
import したいモジュールの 親ディレクトリ を Python パスに入れねばならな
いことに注意してください。
Note
Windows を使っているなら、パスの表記に注意してください。 Windows は通常 バックスラッシュをネイティブのパス区切り文字に使いますが、それでもスラッ シュを使ってパスを表記するよう進めます。 Apache はスラッシュをプラット フォームネイティブのパス区切り文字に変換する方法を知っているので、スラッ シュを使った方が、可搬性や視認性を持たせられるのです。 (それに、バックス ラッシュの二重エスケープのようなトリッキーな問題を回避できます)。
Windows システムでも、以下のパス表記を利用できます:
PythonPath "['c:/path/to/project'] + sys.path"
また、 PythonAutoReload Off
のようなディレクティブを設定して、パフォー
マンスを向上させられます。使えるオプションのリストは
mod_python のドキュメント を参照してください。
注意しなければならないのは、実運用のためのサーバでは、 PythonDebug Off
を設定すべきであるということです。 PythonDebug
が On
に設定されたま
まだと、 mod_python に不具合が生じたときに、恰好の悪い (そして赤裸々な)
Python トレースバックを表示してしまいます。
Apache を再起動しましょう。 /mysite/
やその下の URL へのリクエストが
Django によって提供されているはずです。 Django の URLconf は /mysite/
を切り取りらず、完全な URL を渡すことに注意して下さい。
Django で作られたサイトを mod_python 上で運営している場合、 Python コードに 対して変更を加える度に Apache を再起動する必要があります。
ひとつの Apache に複数の Django をインストールするのは簡単です。
VirtualHost
を使って、以下のようにするだけです:
NameVirtualHost *
<VirtualHost *>
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</VirtualHost>
<VirtualHost *>
ServerName www2.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
</VirtualHost>
一つの VirtualHost
設定の中に複数の Django をインストールしたい場合、
mod_python のキャッシュが Django の動作を台無しにしないように特に気を配る必
要があります。 PythonInterpreter
ディレクティブで、 <Location>
ディ
レクティブごとに別のインタプリタが使われるよう設定してください:
<VirtualHost *>
ServerName www.example.com
# ...
<Location "/something">
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite
</Location>
<Location "/otherthing">
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter othersite
</Location>
</VirtualHost>
PythonInterpreter
の値は、二つの Location
ブロックの間で違う値にさ
えなっていれば何でもかまいません。
開発用サーバに mod_python をえば、コードを変更する度にサーバを再起動するよ
うなやんちゃは避けられます。 MaxRequestsPerChild 1
を Apache の
httpd.conf
ファイルに指定し、Apache にリクエストごとに全てをリロードさ
せてください。とはいえ、これを実運用のサーバでやらないでください。さもない
と、 Django ならではの恩恵が失われてしまいます。
あなたが print
文を散りばめてデバッグするタイプのプログラマなら、
stdout
への出力は Apache のログには何も出力されず、
レスポンスエラーの原因になる ことさえある点に注意しましょう。
mod_python のセットアップでデバッグ情報を出力する必要があるなら、いくつかの方
法があります。次のように stderr
に明示的に print することができます:
print >> sys.stderr, 'debug text'
sys.stderr.flush()
(stderr
はバッファされるので、即座にデバッグ情報を表示されたいなら
flush
の呼び出しが必要なことに注意してください)
もっと簡潔なアプローチはアサーション (assertion) を使うことです:
assert False, 'debug text'
もう一つの方法は、ページのテンプレートにデバッグ情報を追加することです。
Django は、自分ではメディアファイルの提供を行わず、ユーザの選んだ Web サー バにその仕事を任せます。
メディアの提供には、別のウェブサーバ、すなわち Django を動かしていないサー バを使うよう勧めます。お勧めはいくつかあります:
とはいえ、Django を動作させているのと同じ Apache の VirtualHost
でメディ
アファイルや静的ファイルを提供せざるを得ない場合には、以下のようにして特定の
場所でだけ mod_python を切ります:
<Location "/media">
SetHandler None
</Location>
Location
ディレクティブの引数を、メディアファイルを置いている場所のルー
ト URL に置き換えて下さい。 <LocationMatch>
を使って、正規表現に一致さ
せるようにもできます。
以下の例では、 Django をサイトのルートで設定し、 media
と static
サ
ブディレクトリの下と、 .jpg
、 .gif
、および .png
で終わる URL
だけでは明示的に Django を無効にしています:
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location>
<Location "/media">
SetHandler None
</Location>
<Location "/static">
SetHandler None
</Location>
<LocationMatch "\.(jpg|gif|png)$">
SetHandler None
</LocationMatch>
Django の開発サーバは自動的に管理サイトの静的ファイルを提供しますが、他 の構成では提供しません。管理サイトのメディアファイルを提供するには、 Apache なりその他のメディアサーバなりで設定を行う必要があります。
管理サイトのメディアファイルは Django 配布物の
(django/contrib/admin/static/admin
) ディレクトリ下に入っています。
django.contrib.staticfiles
を使って admin のファイルを扱うことを
強く お勧めします。 (これは collectstatic
管理コマンドで
STATIC_ROOT
にファイルを集め、
STATIC_ROOT
を Web サーバに STATIC_URL
で提供させるよう
に設定するということです) しかし、ここでは別の方法を 2 つ述べておきます:
Django を Python egg でインストールしたり、 Django から egg 化されたモジュー ルを使っている場合、いくつか追加の設定が必要です。プロジェクト中 (か、どこ か import できる場所) にファイルを作り、以下の内容を入れておきます:
import os
os.environ['PYTHON_EGG_CACHE'] = '/some/directory'
/some/directory
は Apache httpd を動作させているプロセスが読み書き可能
なディレクトリにします。このディレクトリは、 egg のコードを展開する必要があ
るときに使われます。
次に、 mod_python の PythonImport ディレクティブを使って、 mod_python が一
番最初にこのファイルを import するよう指定します。まず、前述の
上の節 で説明した
PythonInterpreter
ディレクティブを設定しておきます (複数の Django をイ
ンストールしない場合でも必要です)。
次に、メインのサーバ設定 (Location
や VirtualHost
セクションの外)
に、以下のように PythonImport
行を追加します:
PythonInterpreter my_django
PythonImport /path/to/my/project/file.py my_django
mod_python マニュアル で定義されている通り、モジュールの指定は絶対パス
(またはドット区切りの import パス表記) で行えます。ここでは絶対パスを使って
いますが、これは、 PythonImport
を処理する時点では、プロジェクトへの
Python パスを変更する操作がまだ完了していないからです。
Apache/mod_python を使っている場合、エラーは Django によって捕捉されます。
別の言い方をすれば、 エラーは Apache レベルまで伝播せず、 Apache の
error_log
には出力されないということです。
例外は Django のセットアップが全くうまくいっていない場合で、この場合には
“Internal Server Error” がブラウザに表示され、 error_log
ファイルには完
全な Python のトレースバックが出力されます。 (error_log
トレースバック
は複数のログエントリ行に展開されます (これは見苦しくて読みづらいのですが、
mod_python のやり方なので仕方ありません)。
Apache がセグメンテーション違反 (segumentation fault) を引き起こす場合、 2 種類の原因が考えられます。いずれも Django 自体とは関係のない原因です。
mod_python を使った設定で問題を解決できない場合、まずは Django フレームワー クなしの素の mod_python サイトを動かすようにしてみるとよいでしょう。そうす れば、mod_python 固有の問題を簡単に切り分けられます。この手順については Getting mod_python Working で詳しく説明しています。
次のステップでは、テストコードを編集して、自分が使っている全ての Django 関 係のコード – ビュー、モデル、 URLconf, RSS の設定など – を import してみ ます。これらのモジュールを import する文をテストハンドラ関数に入れ、ブラウ ザでテストハンドラの URL にアクセスしてください。クラッシュするようなら、 Django コードの import が問題の原因だということになります。クラッシュしなく なるまで段階的に import するモジュールを減らしてゆき、原因のモジュールを特 定してください。原因のモジュールを調べて、中で import しているモジュールを 必要に応じて調べて下さい。
Django の国際化機能 (国際化とローカライズ 参照) を使っていて、ユーザにファイ
ルアップロードをさせたいなら、 Apache が非 ASCII のファイルを受け入れるよ
うに、 Apache を起動する環境変数をしかるべく設定してください。環境変数が正
しく設定されていないと、非 ASCII のファイル名を os.path()
に渡したとき
に UnicodeEncodeError
例外を引き起こすからです。
UnicodeEncodeError
の問題を回避するには、 Apache を起動するときの環境変
数に、以下のような設定を入れておきます:
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'
正しい環境変数の設定方法や設定場所は、オペレーティングシステムごとのドキュ
メントを参照してください。 Unix プラットフォームでは、
/etc/apache2/envvars
を使うのが一般的です。設定を行ったら、 Apache を再
起動してください。
Oct 26, 2017