FastCGI

FastCGIはnginx, lighttpd, cherokeeのようなサーバでのデプロイの選択肢です;他の選択肢についてはuWSGI独立したWSGIコンテナ(Standalone WSGI Containers)を見てください。自分のWSGIアプリケーションをそれらのサーバのどれかと一緒に使うためには、最初にFastCGIサーバが必要になるでしょう。最も人気があるものはflupであり、このガイドで使用します。以下の内容に沿ってフォローしていくには、flupを確実にインストールしておいてください。 FastCGI is a deployment option on servers like `nginx`_, `lighttpd`_, and `cherokee`_; see :doc:`uwsgi` and :doc:`wsgi-standalone` for other options. To use your WSGI application with any of them you will need a FastCGI server first. The most popular one is `flup`_ which we will use for this guide. Make sure to have it installed to follow along.

注意 Watch Out

予め自分のアプリケーションのファイル内にあるかもしれない全てのapp.run()呼び出しは、if __name__ == '__main__':ブロックの内側にあるか、別のファイルに移動していることを確実にしておいてください。FastCGIへアプリケーションをデプロイするときは望まないローカルWSGIサーバを常に開始してしまうために、app.run()が呼び出されないことを、まずは確認してください。 Please make sure in advance that any ``app.run()`` calls you might have in your application file are inside an ``if __name__ == '__main__':`` block or moved to a separate file. Just make sure it's not called because this will always start a local WSGI server which we do not want if we deploy that application to FastCGI.

.fcgiファイルの作成 Creating a `.fcgi` file

最初にFastCGIサーバのファイルを作成する必要があります。それをyourapplication.fcgiと呼ぶことにしましょう: First you need to create the FastCGI server file. Let's call it `yourapplication.fcgi`::

#!/usr/bin/python
from flup.server.fcgi import WSGIServer
from yourapplication import app

if __name__ == '__main__':
    WSGIServer(app).run()

これはApacheで動かすには十分ですが、nginxおよび古いバージョンのlighttpdではFastCGIサーバとやり取りするために、明示的にsocketを渡す必要があります。それを動かすためには、socketのpathをWSGIServerへ渡す必要があります: This is enough for Apache to work, however nginx and older versions of lighttpd need a socket to be explicitly passed to communicate with the FastCGI server. For that to work you need to pass the path to the socket to the :class:`~flup.server.fcgi.WSGIServer`::

WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()

pathはサーバの設定の中で定義したpathと正確に一致する必要があります。 The path has to be the exact same path you define in the server config.

yourapplication.fcgiファイルをどこか再び見つけ出せる場所に保存してください。/var/www/yourapplicationまたは似たような何かの中にすることは合理的です。 Save the :file:`yourapplication.fcgi` file somewhere you will find it again. It makes sense to have that in :file:`/var/www/yourapplication` or something similar.

サーバが実行できるように、そのファイルのexecutable bit(訳注: ファイルの実行を許可するか指定するための情報で、UNIX系ではchmodコマンドで設定できます)を確実に設定してください: Make sure to set the executable bit on that file so that the servers can execute it:

$ chmod +x /var/www/yourapplication/yourapplication.fcgi

Apacheの設定 Configuring Apache

上記の例は基本的なApacheでのデプロイには十分ですが、アプリケーションのURLに、例えばexample.com/yourapplication.fcgi/news/`のように、.fcgiファイルが見えるようになります。URLの中にyourapplication.fcgiが見えないようにアプリケーションを設定する方法はいくつかあります。好ましいやり方は、FastCgiサーバへのリクエストの経路を決める設定ディレクティブScriptAliasとSetHandlerを使用することです。以下の例は、全ての受信リクエストを処理するアプリケーションのインスタンスを5つ開始するFastCgiServerを使用します(訳注: 以下の例にあるmod_fastcgiは、この日本語ドキュメント作成時点(2019年1月)で開発が停止しており、ソースコードは10年以上更新がなく、Apache2.4系には未対応でコンパイルできません): The example above is good enough for a basic Apache deployment but your `.fcgi` file will appear in your application URL e.g. ``example.com/yourapplication.fcgi/news/``. There are few ways to configure your application so that yourapplication.fcgi does not appear in the URL. A preferable way is to use the ScriptAlias and SetHandler configuration directives to route requests to the FastCGI server. The following example uses FastCgiServer to start 5 instances of the application which will handle all incoming requests::

LoadModule fastcgi_module /usr/lib64/httpd/modules/mod_fastcgi.so

FastCgiServer /var/www/html/yourapplication/app.fcgi -idle-timeout 300 -processes 5

<VirtualHost *>
    ServerName webapp1.mydomain.com
    DocumentRoot /var/www/html/yourapplication

    AddHandler fastcgi-script fcgi
    ScriptAlias / /var/www/html/yourapplication/app.fcgi/

    <Location />
        SetHandler fastcgi-script
    </Location>
</VirtualHost>

それらのプロセスはApacheにより管理されます。もし独立したFastCGIサーバを使用したい場合、代わりにFastCgiExternalServerディレクティブを使用できます。以下の設定ではpathは実際のものではなく、AliasMatchのような他のディレクティブに対する単なる識別子として使用されていることに注意してください: These processes will be managed by Apache. If you're using a standalone FastCGI server, you can use the FastCgiExternalServer directive instead. Note that in the following the path is not real, it's simply used as an identifier to other directives such as AliasMatch::

FastCgiServer /var/www/html/yourapplication -host 127.0.0.1:3000

例えば共有されているwebホストのように、もしScriptAliasを設定できない場合、URLからyourapplication.fcgiを取り除くためにWSGIミドルウェアを使用できます。.htaccessの設定: If you cannot set ScriptAlias, for example on a shared web host, you can use WSGI middleware to remove yourapplication.fcgi from the URLs. Set .htaccess::

<IfModule mod_fcgid.c>
   AddHandler fcgid-script .fcgi
   <Files ~ (\.fcgi)>
       SetHandler fcgid-script
       Options +FollowSymLinks +ExecCGI
   </Files>
</IfModule>

<IfModule mod_rewrite.c>
   Options +FollowSymlinks
   RewriteEngine On
   RewriteBase /
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ yourapplication.fcgi/$1 [QSA,L]
</IfModule>

yourapplication.fcgiの設定: Set yourapplication.fcgi::

#!/usr/bin/python
#: optional path to your local python site-packages folder
import sys
sys.path.insert(0, '<your_local_path>/lib/python<your_python_version>/site-packages')

from flup.server.fcgi import WSGIServer
from yourapplication import app

class ScriptNameStripper(object):
   def __init__(self, app):
       self.app = app

   def __call__(self, environ, start_response):
       environ['SCRIPT_NAME'] = ''
       return self.app(environ, start_response)

app = ScriptNameStripper(app)

if __name__ == '__main__':
    WSGIServer(app).run()

lighttpdの設定 Configuring lighttpd

lighttpd用の基本的なFastCGIの設定は以下のようになります: A basic FastCGI configuration for lighttpd looks like that::

fastcgi.server = ("/yourapplication.fcgi" =>
    ((
        "socket" => "/tmp/yourapplication-fcgi.sock",
        "bin-path" => "/var/www/yourapplication/yourapplication.fcgi",
        "check-local" => "disable",
        "max-procs" => 1
    ))
)

alias.url = (
    "/static/" => "/path/to/your/static/"
)

url.rewrite-once = (
    "^(/static($|/.*))$" => "$1",
    "^(/.*)$" => "/yourapplication.fcgi$1"
)

FastCGIを有効にし、モジュールのaliasおよびrewriteを行うことを覚えておいてください。以下の設定はアプリケーションを/yourapplicationに結び付けます。アプリケーションをURLのrootとして働くようにしたい場合、LighttpdCGIRootFixミドルウェア(訳注: werkzeugの0.9以降、CGIRootFixに名前が変更されています)を使ってlighttpdのバグを回避する必要があります。 Remember to enable the FastCGI, alias and rewrite modules. This configuration binds the application to ``/yourapplication``. If you want the application to work in the URL root you have to work around a lighttpd bug with the :class:`~werkzeug.contrib.fixers.LighttpdCGIRootFix` middleware.

上記を適用するのは、確実に、URLをrootに取り付ける(mount)ときだけにしてください。FastCGIとPythonについてのさらなる情報についてはLightyのドキュメントを見てください(明示的にsocketをrun()へ渡すことは必要ではなくなったことに注意してください)。 Make sure to apply it only if you are mounting the application the URL root. Also, see the Lighty docs for more information on `FastCGI and Python <https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI>`_ (note that explicitly passing a socket to run() is no longer necessary).

nginxの設定 Configuring nginx

標準設定ではFastCGIのパラメータが何も転送されないため、nginxへのFastCGIのインストールは少し違います。 Installing FastCGI applications on nginx is a bit different because by default no FastCGI parameters are forwarded.

nginx用の基本的なFlaskのFastCGI設定は以下のようになります: A basic Flask FastCGI configuration for nginx looks like this::

location = /yourapplication { rewrite ^ /yourapplication/ last; }
location /yourapplication { try_files $uri @yourapplication; }
location @yourapplication {
    include fastcgi_params;
    fastcgi_split_path_info ^(/yourapplication)(.*)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}

この設定はアプリケーションを/yourapplicationに結び付けます。もしアプリケーションをURLのrootにしたい場合、どうやってPATH_INFOSCRIPT_NAMEとを計算するか理解する必要がなくなるため、少しシンプルになります: This configuration binds the application to ``/yourapplication``. If you want to have it in the URL root it's a bit simpler because you don't have to figure out how to calculate ``PATH_INFO`` and ``SCRIPT_NAME``::

location / { try_files $uri @yourapplication; }
location @yourapplication {
    include fastcgi_params;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    fastcgi_param SCRIPT_NAME "";
    fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}

FastCGIプロセスの実行 Running FastCGI Processes

nginx他はFastCGIのアプリケーションの読み込み(load)をしないため、自分で(FastCGIプロセスの実行を)行う必要があります。supervisordがFastCGIプロセスを管理可能です。他のFastCGI管理ツールを探すことも、例えばSysvのinit.dスクリプトを使い、起動時に自分の.fcgiファイルを実行するスクリプトを作成することも可能です。一時的な解決策として、.fcgiスクリプトを常にGNU screenツールの中で実行することも可能です。詳細はman screenを見てください。さらに、GNU screenはシステムを再起動したときは引き継がれない主導の解決策であることに注意してください: Since nginx and others do not load FastCGI apps, you have to do it by yourself. `Supervisor can manage FastCGI processes. <http://supervisord.org/configuration.html#fcgi-program-x-section-settings>`_ You can look around for other FastCGI process managers or write a script to run your `.fcgi` file at boot, e.g. using a SysV ``init.d`` script. For a temporary solution, you can always run the ``.fcgi`` script inside GNU screen. See ``man screen`` for details, and note that this is a manual solution which does not persist across system restart::

$ screen
$ /var/www/yourapplication/yourapplication.fcgi

デバッグ Debugging

FastCGIのデプロイは、殆どのwebサーバでデバッグが困難になる傾向があります。サーバのログは「premature end of headers」という行だけしか伝えてくれないことが、とてもよくあります。アプリケーションをデバッグするために、なぜ壊れるかというアイデアを本当に教えてくれる唯一のことは、適正なユーザに切り替え、手動でアプリケーションを実行することです。 FastCGI deployments tend to be hard to debug on most web servers. Very often the only thing the server log tells you is something along the lines of "premature end of headers". In order to debug the application the only thing that can really give you ideas why it breaks is switching to the correct user and executing the application by hand.

以下の例では、アプリケーションがapplication.fcgiと呼ばれ、webサーバのユーザはwww-dataと想定しています: This example assumes your application is called `application.fcgi` and that your web server user is `www-data`::

$ su www-data
$ cd /var/www/yourapplication
$ python application.fcgi
Traceback (most recent call last):
  File "yourapplication.fcgi", line 4, in <module>
ImportError: No module named yourapplication

このケースでは、エラーは「yourapplication」がpythonのpathにないということのようです。ありがちな問題は: In this case the error seems to be "yourapplication" not being on the python path. Common problems are:

  • 相対パスが使われています。そのときの作業ディレクトリの場所に依存しないようにしてください。 Relative paths being used. Don't rely on the current working directory.

  • コードが、webサーバによって設定されていない環境変数に依存しています。 The code depending on environment variables that are not set by the web server.

  • 違うpythonインタプリタが使用されています。 Different python interpreters being used.