.. _howto-deployment-fastcgi: =================================== FastCGI, SCGI, AJP で Django を使う =================================== :revision-up-to: 17812 (1.4) .. highlight:: bash Django を動作させるプラットフォームとして現在推奨しているのは :doc:`WSGI ` ですが、多くの 人々が使っている共有ホスティングサービスには、 FastCGI や SCGI, AJP といっ たプロトコルしか選択肢がありません。 .. admonition:: Note このドキュメントでは、 FastCGI に重点をおいて説明しています。 SCGI や AJP といったプロトコルも、Python パッケージ ``flup`` 経由でサポートして います。 SCGI や AJP 固有の設定は、後述の 「 プロトコル_ 」の節を参照し てください。 FastCGI は、いわば外部アプリケーションによって Web サーバにページを提供させ る方法の一つです。Web サーバは (socket を介して) 受け取った Web リクエスト の処理を FastCGI に肩代りさせます。 FastCGI はコードを実行して、その応答を Web サーバに返します。 Web サーバはその内容をクライアントのWeb ブラウザに返 すというわけです。 WSGI と同様、 FastCGI はコードをメモリ上に残すので、リクエストはスクリプトの起 動時間を伴わずに処理されます。 ただし、例えば :doc:`mod_wsgi` が Apache Web サーバプロセスの 中に組み込まれるか、別のデーモンプロセスとして実行されるかを設定できるのに対 し、 FastCGI プロセスは Web サーバプロセスの中ではなく、別の永続的プロセスの中 で実行されます。 .. _mod_perl: http://perl.apache.org/ .. admonition:: なぜ別のプロセスでコードを実行するのですか? Apache における伝統的な ``mod_*`` の構成では、 Web サーバのプロセス空間 内に様々なスクリプト言語 (有名なのは PHP, Python, Perl です) を埋め込ん で実行します。この構成は、リクエストのたびにプログラムコードをディスク から読み出さなくてもよくなるため、起動時間を減らせるという利点がありま す --- その反面、メモリの消費は莫大になります。 FastCGI の性質上、Web サーバプロセスと別のユーザアカウントでプロセスを 実行できます。この特徴は、自分のコードを他のユーザから守れるという点で、 共有ホストにおいてセキュリティ上の利点になります。 必要なもの: flup ================ Django で FastCGI を使うには、まず flup_ をインストールせねばなりません。 flup は FastCGI を使えるようにするための Python ライブラリです。 Django は バージョン0.5 以降の flup で動作します。 .. _flup: http://www.saddi.com/software/flup/ FastCGI サーバを起動する ======================== FastCGI はクライアントサーバモデルで動作します。ほとんどの場合、 FastCGI プ ロセスを自分で起動することになるでしょう。 Web サーバ (Apache、 lighttpd な ど) が Djagno の FastCGI プロセスにアクセスするのは、サーバが動的ページをロー ドするときだけです。デーモンは常にコードをメモリ上にロードしたまま動作して いるので、非常に高速に応答を返せるのです。 .. admonition:: Note 共有ホスティングサービスを使っているなら、Web サーバで管理された FastCGI プロセスを使わざるを得ないかもしれません。 Django を Web サーバ で管理された FastCGI プロセスで使うには、後に出て来る節の説明を参照して ください。 Web サーバが FastCGI サーバにアクセスするには二つの方法があります。一つは Unix ドメインソケット (Win32 システムにおける「名前付きパイプ」) で、もう一 つは TCP ソケットです。どちらを選ぶかは好みの問題です。パーミッションの問題 から、通常は TCP ソケットの方が簡単です。 サーバを起動するには、プロジェクトのあるディレクトリ (``manage.py`` のある 場所) に移動して、 :doc:`manage.py ` の :djadmin:`runfcgi` コマンドを実行します:: ./manage.py runfcgi [options] :djadmin:`runfcgi` に ``help`` オプションだけを指定すると、利用可能な全ての オプションを表示します。 引数として、 :djadminopt:`socket`, :djadminopt:`protocol`, または、 :djadminopt:`host` および :djadminopt:`port` を指定せねばなりません。さらに、 Web サーバをセットアップする際に、FastCGI サーバを起動するときに使ったソケット 名か、ホスト/ポート番号の組合せを指定せねばなりません。後述の `実行例`_ を参照 してください。 プロトコル ---------- Django は flup_ のサポートしている全てのプロトコル、すなわち fastcgi_, SCGI_, `AJP1.3`_ (Apache JServ プロトコルバージョン 1.3) をサポートしていま す。使いたいプロトコルを指定するには、 :djadminopt:`protocol=` を ``./manage.py runfcgi`` のオプションに指定します。 ```` は ``fcgi`` (デフォルト)、 ``scgi`` または ``ajp`` のいずれかです。例を以下に 示します:: ./manage.py runfcgi protocol=scgi .. _flup: http://www.saddi.com/software/flup/ .. _fastcgi: http://www.fastcgi.com/ .. _SCGI: http://python.ca/scgi/protocol.txt .. _AJP1.3: http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html 実行例 ------ TCP ポートを使い、スレッドモードでサーバを起動する場合:: ./manage.py runfcgi method=threaded host=127.0.0.1 port=3033 Unix ドメインソケットを使い、 prefork モードでサーバを起動する場合:: ./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid .. .. admonition:: Socket security Django's default umask requires that the webserver and the Django fastcgi process be run with the same group **and** user. For increased security, you can run them under the same group but as different users. If you do this, you will need to set the umask to 0002 using the ``umask`` argument to ``runfcgi``. .. admonition:: ソケットのセキュリティ Django のデフォルトの umask では Web サーバと Django の fastcgi が同じグ ループ **かつ** 同じユーザで実行されることが必要です。セキュリティを強固に するには同じグループの別のユーザで実行させることができます。こうする場合は ``runfcgi`` の ``umask`` 引数を使って umask に 0002 をセットします。 デーモン化 (バックグラウンド化) させずにプロセスを起動する場合 (デバッグ時 に便利です):: ./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock maxrequests=1 FastCGI デーモンを止める ------------------------ フォアグラウンドでプロセスを走らせているのなら、止めるのは簡単で、 ``Ctrl-C`` を押して FastCGI サーバを止めるだけですみます。バックグラウンド プロセスを使っているのなら、 Unix の ``kill`` コマンドを使わねばなりません。 :djadminopt:`pidfile` オプションを指定して :djadmin:`runfcgi` を起動しているの なら、以下のようにして起動中の FastCGI デーモンを殺せます:: kill `cat $PIDFILE` ``$PIDFILE`` は起動時に指定した ``pidfile`` の値です。 Unix 上で FastCGI デーモンを簡単に再起動させたいなら、以下のようなシェルス クリプトを試してみましょう:: #!/bin/bash # 以下の 3 つの設定は自分の環境に合わせて置き換える PROJDIR="/home/user/myproject" PIDFILE="$PROJDIR/mysite.pid" SOCKET="$PROJDIR/mysite.sock" cd $PROJDIR if [ -f $PIDFILE ]; then kill `cat -- $PIDFILE` rm -f -- $PIDFILE fi exec /usr/bin/env - \ PYTHONPATH="../python:.." \ ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE Apache の設定 ============== Django を Apache と FastCGI の構成で使うには、 Apache をインストールし、さ らに `mod_fastcgi`_ をインストールして有効にせねばなりません。詳しい手順は Apache のドキュメントを参照してください。 mod_fastcgi の構成が終ったら、 ``httpd.conf`` ファイルを編集して、 Apache に Django の FastCGI インスタンスを教えます。以下の二つの設定を行わねばなり ません: * ``FastCGIExternalServer`` ディレクティブを使って、 FastCGI サーバの場 所を指定します。 * ``mod_rewrite`` を使って、リクエストが適切な FastCGI に向くようにしま す。 .. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html FastCGI サーバの場所を指定する ------------------------------ ``FastCGIExternalServer`` ディレクティブは、 Apache に FastCGI サーバの探し 方を教えます。 `FastCGIExternalServer のドキュメント`_ にもある通り、 ``socket`` または ``host`` のいずれかを指定せねばなりません。それぞれの例を 以下に示します: .. code-block:: apache # ソケットや名前付きパイプを経由して FastCGI に接続する場合 FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock # TCP でホスト名とポート番号を指定して接続する場合 FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033 いずれのケースでも、 ``/home/user/public_html/mysite.fcgi`` は実際に存在し なくてもかまいません。このパスは Web サーバが内部的に使う URL に過ぎず、 FastCGI で処理すべきリクエストを URL で区別するための単なるフックです。(次 節で詳しく説明します) .. _`FastCGIExternalServer のドキュメント`: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiExternalServer .. _FastCGIExternalServer docs: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiExternalServer mod_rewrite を使って URL が FastCGI を指すようにする ---------------------------------------------------- 第二ステップでは、特定のパターンに一致する URL では FastCGI を使うよう Apache に指示します。前節で述べたように、 `mod_rewrite`_ モジュールを使って、 URL を ``mysite.fcgi`` (または ``FastCGIExternalServer`` ディレクティブに指 定した名前) に書き換えます。 下記の例では、ファイルシステム上に存在せず、かつパスが ``/media/`` で始まら ないファイルに対するリクエストに対して FastCGI を使うよう Apache に指示して います。Django の admin サイトを使っているなら、これはよくある状況でしょう:: ServerName example.com DocumentRoot /home/user/public_html Alias /media /home/user/python/django/contrib/admin/media RewriteEngine On RewriteRule ^/(media.*)$ /$1 [QSA,L,PT] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L] .. _mod_rewrite: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html Django は、 :ttag:`{% url %}` テンプレートタグ (や、同様のメソッド) で URL を構築する際、自動的にリライト前の URL を使います。 .. Using mod_fcgid as alternative to mod_fastcgi ---------------------------------------------- mod_fastcgi の代わりに mod_fcgid を使う --------------------------------------- .. Another way to serve applications through FastCGI is by using Apache's `mod_fcgid`_ module. Compared to mod_fastcgi mod_fcgid handles FastCGI applications differently in that it manages the spawning of worker processes by itself and doesn't offer something like ``FastCGIExternalServer``. This means that the configuration looks slightly different. FastCGI 経由でアプリケーションを提供する別の方法が、 Apache の `mod_fcgid` モ ジュールを使うことです。 mod_fastcgi と比べると、 mod_fcgid の FastCGI アプリ ケーションの扱い方は、ワーカープロセスを自分自身で生成し、 ``FastCGIExternalServer`` のような何かを提供するのではないところが異なります。 このため設定が少し違った外見になります。 .. In effect, you have to go the way of adding a script handler similar to what is described later on regarding running Django in a :ref:`shared-hosting environment `. For further details please refer to the `mod_fcgid reference`_ 実際には、後ほど :ref:`共有ホスティング環境 ` での Django の動作について説明するのと同じように、スクリプトハンドラを追加すること になります。もっと詳しく知るには、どうぞ `mod_fcgid リファレンス`_ を参照して ください。 .. _mod_fcgid: http://httpd.apache.org/mod_fcgid/ .. _`mod_Fcgid リファレンス`: http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html lighttpd での FastCGI 構成 ========================== lighttpd_ は静的ファイルのサービスによく使われている軽量な Web サーバです。 lighttpd はネイティブの FastCGI サポートを持っているので、 Apache の縛りが なくて、動的ページと静的ページの両方をサービスしたい場合には良い選択肢とい えます。 .. _lighttpd: http://www.lighttpd.net/ ``mod_fastcgi`` がモジュールリストに入っているか確かめてください。このとき、 ``mod_rewrite`` や ``mod_access`` よりも後ろにして、 ``mod_accesslog`` より も前にします。 admin メディアファイルを提供するなら、 ``mod_alias`` も必要 になるでしょう。 lighttpd 設定ファイルに以下の設定を追加してください: .. code-block:: lua server.document-root = "/home/user/public_html" fastcgi.server = ( "/mysite.fcgi" => ( "main" => ( # TCP で fastcgi に接続する場合は host / port を指定する # "host" => "127.0.0.1", # "port" => 3033, "socket" => "/home/user/mysite.sock", "check-local" => "disable", ) ), ) alias.url = ( "/media/" => "/home/user/django/contrib/admin/media/", ) url.rewrite-once = ( "^(/media.*)$" => "$1", "^/favicon\.ico$" => "/media/favicon.ico", "^(/.*)$" => "/mysite.fcgi$1", ) lighttpd を使って複数の Django サイトを駆動する ----------------------------------------------- lighttpd には、ホストごとに設定をカスタマイズするための「条件付き設定 (conditional configuration)」があります。複数の FastCGI サイトを指定するに は、各サイトごとに FastCGI 設定を条件分岐のブロックにします:: # If the hostname is 'www.example1.com'... $HTTP["host"] == "www.example1.com" { server.document-root = "/foo/site1" fastcgi.server = ( ... ) ... } # If the hostname is 'www.example2.com'... $HTTP["host"] == "www.example2.com" { server.document-root = "/foo/site2" fastcgi.server = ( ... ) ... } ``fastcgi.server`` ディレクティブに複数のエントリを追加すれば、複数の Django を同じサイトでも駆動できます。各エントリごとに FastCGI ホストを追加 してください。 Cherokee を使う場合 ==================== Cherokee はとても高速で柔軟性があり、簡単に設定できる Web サーバです。 Cherokee は、FastCGI, SCGI, PHP, CGI, SSI, TLS や SSL による暗号化、バーチャ ルホスト、認証、動的エンコーディング、ロードバランシング、Apache 互換のログ ファイル、データベースのバランサ、リバース HTTP プロキシなどなど、最近の Webサーバがサポートしている様々な技術をサポートしています。 Cherokee プロジェクトのページには、 `Cherokee で Django を運用する`_ ための ドキュメントがあります。 .. _setting up Django: http://www.cherokee-project.com/doc/cookbook_django.html .. _`Cherokee で Django を運用する`: `setting up Django`_ .. _apache_shared_hosting: Apache を使っている共有ホスティングプロバイダ上で Django を使う =============================================================== 共有ホスティングプロバイダの多くでは、独自のサーバデーモンを起動できなかっ たり、 ``httpd.conf`` ファイルを編集できなかったりします。このような場合で も、サーバ起動プロセスを使えば Django を駆動できます。 .. admonition:: Note この章で説明するような方法で Web サーバ起動プロセスを使う場合、 FastCGI サーバを自分で起動する必要はありません。Apache が必要に応じて複数のプロ セスを起動してくれます。 Web コンテンツのルートディレクトリ下に、以下のような内容のファイルを ``.htaccess`` という名前で保存します: .. code-block:: apache AddHandler fastcgi-script .fcgi RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L] 次に、 Apache に FastCGI プログラムの起動方法を教える小さなスクリプトを作成 します。 ``mysite.fcgi`` というファイルを作成して Web コンテンツディレクト リに置き、実行可能にします: .. code-block:: python #!/usr/bin/python import sys, os # Python のモジュール検索パスをカスタマイズする sys.path.insert(0, "/home/user/python") # カレントディレクトリをプロジェクトのディレクトリに移す (必要なら) # os.chdir("/home/user/myproject") # 環境変数 DJANGO_SETTINGS_MODULE を設定する os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings" from django.core.servers.fastcgi import runfastcgi runfastcgi(method="threaded", daemonize="false") .. This works if your server uses mod_fastcgi. If, on the other hand, you are using mod_fcgid the setup is mostly the same except for a slight change in the ``.htaccess`` file. Instead of adding a fastcgi-script handler, you have to add a fcgid-handler: これはサーバが mod_fastcgi を使っている場合に動作します。一方、 mod_fcgid を 使っている場合、 ``.htaccess`` ファイルでの少しの変更を除けば、セットアップは ほとんど同じです。 fastcgi-script ハンドラを追加する代わりに、 fcgi-handler を 追加する必要があります: .. code-block:: apache AddHandler fcgid-script .fcgi RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L] 起動中のサーバを再起動する -------------------------- サイトを構成する Python コードを変更した場合、 FastCGI にコードが変更された ことを教えねばなりません。しかし、 FastCGI の場合には Apache を再起動する必 要はありません。その代わり、 ``mysite.fcgi`` を再度アップロードするか、ファ イルを編集して、タイムスタンプを更新してください。 Apache は、ファイルのタ イムスタンプが更新されていることを発見すると、Django アプリケーションを再起 動してくれます。 Unix システムでコマンドラインシェルへのアクセスが許されているなら、 ``touch`` コマンドを使えば簡単にタイムスタンプを更新できます:: touch mysite.fcgi Admin メディアファイルの提供 ============================ サーバやその設定がどうあれ、何らかの形で admin メディアファイルを提供する方 法を考えておかねばなりません。 :ref:`modwsgi ` のドキュメントには、上記の構成でも使えるアドバイスがあります。 URL のプレフィクス部分を特定の値にする ======================================== FastCGI を使った設置方法は、ほとんどが URL をリライトしてウェブサーバ内部の 別の場所を指すようにしています。このとき、 Django から見えるパス情報には、 もともとの URL が反映されません。そのため、 Django アプリケーションを特定の プレフィクスの下で動かしていて、 :ttag:`{% url %}` タグで表示される URL を、 ``mysite.fcgi`` のようなリライト後のものでなく、プレフィクスのついた URL にしたいときに問題が生じます。 Django は実際のスクリプト名プレフィクスが何だったかをそれなりにうまく調べよ うとします。特に、ウェブサーバが ``SCRIPT_URL`` を設定する場合(Apache の modo_rewrite 特有の機能です) や、 ``REDIRECT_URL`` を設定する場合 (Apache と mod_rewrite をある構成で使ったとき) には、もとのプレフィクスを自動的に 見つけ出します。 Django がプレフィクスを正しく見付けられない場合や、リライト前の値を URL に 使いたい場合には、設定ファイル中で :setting:`FORCE_SCRIPT_NAME` を設定して ください。この変数には、全ての URL に共通なスクリプト名を指定します。したがっ て、別々のスクリプト名を持った URL に対応するには個別に設定ファイルを用意せ ねばなりませんが、そのようなケースは稀でしょう。 例えば、全てのコンテンツを ``'/'`` 以下の URL で提供するように Django を構 成しているなら、設定ファイルには ``FORCE_SCRIPT_NAME = ''`` と指定してくだ さい。