.. _howto-deployment-modpython:
=========================================
Apache と mod_python で Django を動かす
=========================================
:revision-up-to: 17812 (1.4)
.. .. warning::
Support for mod_python has been deprecated, and will be removed in
Django 1.5. If you are configuring a new deployment, you are
strongly encouraged to consider using :doc:`mod_wsgi
` or any of the other :doc:`supported
servers `.
.. warning::
mod_python のサポートは非推奨となっており Django 1.5 で取り除かれる予定
です。新しいデプロイ設定をするなら :doc:`mod_wsgi
` または他の :doc:`サポートされている
サーバ ` を使うことを強くお勧めします。
.. highlight:: apache
Apache_ の `mod_python`_ モジュールを使えば、本番環境で Django をデプロイで
きます。ただし、この方法は、よりシンプルな
:doc:`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`_ を使うよう
勧めます。
.. seealso::
* Apache は大規模で複雑な代物です。このドキュメントは、 Apache でできる
ことのほんの表面的なことしか解説していません。もっと詳しい情報を知り
たければ、 `Apache の公式ドキュメント`_ がなによりの情報源です。
* 興味があれば :doc:`FastCGI, SCGI, AJP で Django を動かす
` もどうぞ。
.. _Apache: http://httpd.apache.org/
.. _mod_python: http://www.modpython.org/
.. _mod_perl: http://perl.apache.org/
.. _prefork MPM: http://httpd.apache.org/docs/2.2/mod/prefork.html
.. _worker MPM: http://httpd.apache.org/docs/2.2/mod/worker.html
.. _apache's own official documentation: http://httpd.apache.org/docs/
.. _`Apache の公式ドキュメント`: `apache's own official documentation`_
基本的な設定
============
Django を mod_python で動かすようにするには、まず Apache がインストールされ、
mod_python モジュールが有効になっていることを確かめます。
次に、 ``httpd.conf`` ファイルを編集し、以下のような設定を追加します::
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
``mysite.settings`` は、 Django プロジェクトの設定ファイルを指す Python
import パスになるよう、自分の環境に合わせて置き換えて下さい。
この設定は、 Apache に 「/mysite/ の下の全ての URL は mod_python で処理し、
処理には Django mod_python ハンドラを使うように」命令します。また、
:ref:`DJANGO_SETTINGS_MODULE ` を渡して、
mod_python にどこに設定ファイルがあるのか教えます。
mod_python は、サイトを ``/mysite/`` プレフィクスの下で提供していることを自
動的に検出できないので、 ``PythonOption django.root ...`` を使ってハンドラ
に通知してやる必要があります。この行に設定する値は、 ````
の引数と一致していなければなりません。 ``django.root`` を設定すると、
Django はリクエストの URL から ``django.root`` に設定されたプレフィクスを除
去した上で ``URLConf`` のパターンマッチングを行います。このため、後でサイト
を ``/mysite2`` に動かした際に、 ``djnago.root`` だけを変更すればよくなりま
す。
``django.root`` を使う場合、必ず、プレフィクスを除去した後の URL がスラッシュ
で開始するようにしてください。 そうでないと、先頭にスラッシュの入る URLConf
の設定があった場合、パターンマッチングがうまくいきません。上の例では、
``/mysite/admin/`` を ``/admin/`` に変えたいので、先頭から除去すべきなのは
``/mysite`` です。従って、 ``django.root`` の値を ``/mysite`` にしているの
です。この場合、 ``/mysite/`` (末尾にスラッシュがついている) にしてしまうと、
エラーをひき起こすでしょう。
上の例では ```` ではなく ```` ディレクティブを使って
います。前者はファイルシステム上の場所を指定するのに使い、後者はウェブサイ
トのURL 構造上の場所を指定するのに使います。従って、 ```` を使っ
た指定は意味をなさないのです。
また、 Django プロジェクトがデフォルトの ``PYTHONPATH`` 上になければ、以下
のような設定を mod_python に教えておく必要があります:
.. parsed-literal::
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"**
``PythonPath`` には、アプリケーションから import したいモジュールの各々の
親ディレクトリを入れなければなりません。また、 :ref:`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`` だったとします。上の例のように
:ref:`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 を再起動する必要があります。
.. _`mod_python のドキュメント`: http://modpython.org/live/current/doc-html/directives.html
ひとつの Apache に複数の Django をインストールする
==================================================
ひとつの Apache に複数の Django をインストールするのは簡単です。
``VirtualHost`` を使って、以下のようにするだけです::
NameVirtualHost *
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
ServerName www2.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
一つの ``VirtualHost`` 設定の中に複数の Django をインストールしたい場合、
mod_python のキャッシュが Django の動作を台無しにしないように特に気を配る必
要があります。 ``PythonInterpreter`` ディレクティブで、 ```` ディ
レクティブごとに別のインタプリタが使われるよう設定してください::
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter othersite
``PythonInterpreter`` の値は、二つの ``Location`` ブロックの間で違う値にさ
えなっていれば何でもかまいません。
mod_python 上で開発用サーバを動かす
===================================
開発用サーバに mod_python をえば、コードを変更する度にサーバを再起動するよ
うなやんちゃは避けられます。 ``MaxRequestsPerChild 1`` を Apache の
``httpd.conf`` ファイルに指定し、Apache にリクエストごとに全てをリロードさ
せてください。とはいえ、これを実運用のサーバでやらないでください。さもない
と、 Django ならではの恩恵が失われてしまいます。
あなたが ``print`` 文を散りばめてデバッグするタイプのプログラマなら、
``stdout`` への出力は Apache のログには何も出力されず、
`レスポンスエラーの原因になる` ことさえある点に注意しましょう。
.. _`レスポンスエラーの原因になる`: http://blog.dscpl.com.au/2009/04/wsgi-and-printing-to-standard-output.html
.. If you have the need to print debugging information in a mod_python setup, you
have a few options. You can print to ``stderr`` explicitly, like so::
mod_python のセットアップでデバッグ情報を出力する必要があるなら、いくつかの方
法があります。次のように ``stderr`` に明示的に print することができます::
print >> sys.stderr, 'debug text'
sys.stderr.flush()
.. (note that ``stderr`` is buffered, so calling ``flush`` is necessary if you wish
debugging information to be displayed promptly.)
(``stderr`` はバッファされるので、即座にデバッグ情報を表示されたいなら
``flush`` の呼び出しが必要なことに注意してください)
.. A more compact approach is to use an assertion::
もっと簡潔なアプローチはアサーション (assertion) を使うことです::
assert False, 'debug text'
.. Another alternative is to add debugging information to the template of your page.
もう一つの方法は、ページのテンプレートにデバッグ情報を追加することです。
メディアファイルの提供
========================
Django は、自分ではメディアファイルの提供を行わず、ユーザの選んだ Web サー
バにその仕事を任せます。
メディアの提供には、別のウェブサーバ、すなわち Django を動かしていないサー
バを使うよう勧めます。お勧めはいくつかあります:
* lighttpd_
* Nginx_
* TUX_
* Apache_ の軽量化 (stripped-down) 版
* Cherokee_
とはいえ、Django を動作させているのと同じ Apache の ``VirtualHost`` でメディ
アファイルや静的ファイルを提供せざるを得ない場合には、以下のようにして特定の
場所でだけ mod_python を切ります::
SetHandler None
``Location`` ディレクティブの引数を、メディアファイルを置いている場所のルー
ト URL に置き換えて下さい。 ```` を使って、正規表現に一致さ
せるようにもできます。
以下の例では、 Django をサイトのルートで設定し、 ``media`` と ``static`` サ
ブディレクトリの下と、 ``.jpg`` 、 ``.gif`` 、および ``.png`` で終わる URL
だけでは明示的に Django を無効にしています::
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
SetHandler None
SetHandler None
SetHandler None
.. _lighttpd: http://www.lighttpd.net/
.. _Nginx: http://wiki.nginx.org/Main
.. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
.. _Apache: http://httpd.apache.org/
.. _Cherokee: http://www.cherokee-project.com/
管理サイト用メディアファイルの提供
==================================
Django の開発サーバは自動的に管理サイトの静的ファイルを提供しますが、他
の構成では提供しません。管理サイトのメディアファイルを提供するには、 Apache
なりその他のメディアサーバなりで設定を行う必要があります。
管理サイトのメディアファイルは Django 配布物の
(:file:`django/contrib/admin/static/admin`) ディレクトリ下に入っています。
.. We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle the
admin files (this means using the :djadmin:`collectstatic` management command
to collect the static files in :setting:`STATIC_ROOT`, and then configuring
your Web server to serve :setting:`STATIC_ROOT` at :setting:`STATIC_URL`), but
here are two other approaches:
:mod:`django.contrib.staticfiles` を使って admin のファイルを扱うことを
**強く** お勧めします。 (これは :djadmin:`collectstatic` 管理コマンドで
:setting:`STATIC_ROOT` にファイルを集め、
:setting:`STATIC_ROOT` を Web サーバに :setting:`STATIC_URL` で提供させるよう
に設定するということです) しかし、ここでは別の方法を 2 つ述べておきます:
1. ドキュメントルートから admin メディアファイルへのシンボリックリンク
を作ります。
2. または、 admin メディアファイルをコピーして Apache のドキュメントルー
トに入れます。
mod_python 上で "egg" パッケージを使う
=======================================
Django を Python egg_ でインストールしたり、 Django から egg 化されたモジュー
ルを使っている場合、いくつか追加の設定が必要です。プロジェクト中 (か、どこ
か import できる場所) にファイルを作り、以下の内容を入れておきます:
.. code-block:: python
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 パスを変更する操作がまだ完了していないからです。
.. _Egg: http://peak.telecommunity.com/DevCenter/PythonEggs
.. PythonImport: http://www.modpython.org/live/current/doc-html/dir-other-pimp.html
.. _PythonImport: http://www.python.jp/doc/contrib/modpython/dir-other-pimp.html
.. _mod_python manual: PythonImport_
.. _`mod_python マニュアル`: `mod_python manual`_
__ `ひとつの Apache に複数の Django をインストールする`_
エラー処理
==========
Apache/mod_python を使っている場合、エラーは Django によって捕捉されます。
別の言い方をすれば、 エラーは Apache レベルまで伝播せず、 Apache の
``error_log`` には出力されないということです。
例外は Django のセットアップが全くうまくいっていない場合で、この場合には
"Internal Server Error" がブラウザに表示され、 ``error_log`` ファイルには完
全な Python のトレースバックが出力されます。 (``error_log`` トレースバック
は複数のログエントリ行に展開されます (これは見苦しくて読みづらいのですが、
mod_python のやり方なので仕方ありません)。
セグメンテーション違反を起こす場合
===================================
Apache がセグメンテーション違反 (segumentation fault) を引き起こす場合、 2
種類の原因が考えられます。いずれも Django 自体とは関係のない原因です。
1. Python コードが "pyexpat" モジュールを import している場合。
"pyexpat" は Apache に埋め込まれているバージョンと衝突する場合があり
ます。詳しくは、 `Expat Causing Apache Crash`_ を参照してください。
2. mod_python と mod_php を同じ Apache のインスタンスで動作させ、バック
エンドに MySQL を使っている場合。PHP と Python MySQL バックエンドと
のバージョン衝突で引き起こされる既知の問題かもしれません。これについ
ては `mod_python FAQ entry`_ に詳しく書かれています。
mod_python を使った設定で問題を解決できない場合、まずは Django フレームワー
クなしの素の mod_python サイトを動かすようにしてみるとよいでしょう。そうす
れば、mod_python 固有の問題を簡単に切り分けられます。この手順については
`Getting mod_python Working`_ で詳しく説明しています。
次のステップでは、テストコードを編集して、自分が使っている全ての Django 関
係のコード -- ビュー、モデル、 URLconf, RSS の設定など -- を import してみ
ます。これらのモジュールを import する文をテストハンドラ関数に入れ、ブラウ
ザでテストハンドラの URL にアクセスしてください。クラッシュするようなら、
Django コードの import が問題の原因だということになります。クラッシュしなく
なるまで段階的に import するモジュールを減らしてゆき、原因のモジュールを特
定してください。原因のモジュールを調べて、中で import しているモジュールを
必要に応じて調べて下さい。
.. _Expat Causing Apache Crash: http://www.dscpl.com.au/wiki/ModPython/Articles/ExpatCausingApacheCras
.. _mod_python FAQ entry: http://modpython.org/FAQ/faqw.py?req=show&file=faq02.013.htp
.. _Getting mod_python Working: http://www.dscpl.com.au/wiki/ModPython/Articles/GettingModPythonWorking
UnicodeEncodeError が出る場合
===============================
Django の国際化機能 (:doc:`/topics/i18n/index` 参照) を使っていて、ユーザにファイ
ルアップロードをさせたいなら、 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 を再
起動してください。