uWSGI

uWSGIは高速で、コンパイルされた、基本サーバ以上の幅広い設定と機能を伴った一そろいのサーバです。 `uWSGI`_ is a fast, compiled server suite with extensive configuration and capabilities beyond a basic server.

  • コンパイルされたプログラムであるため、非常に高速に実行できます。 It can be very performant due to being a compiled program.

  • 基本アプリケーション以上に設定するには複雑で、非常に多くのオプションがあり、初心者が理解するには難しい場合があります。 It is complex to configure beyond the basic application, and has so many options that it can be difficult for beginners to understand.

  • Windowsはサポートしません(しかし、WSL上で走ります)。 It does not support Windows (but does run on WSL).

  • あるケースではインストールにコンパイラが必要です。 It requires a compiler to install in some cases.

このページはuWSGIを実行する基本について説明します。そのドキュメントを読んで、どの目玉機能(feature)が利用できるか理解しておいてください。 This page outlines the basics of running uWSGI. Be sure to read its documentation to understand what features are available.

Installing

uWSGIはインストール方法は複数あります。最も直感的なものは、よくあるプラットフォームようにコンパイル済みのwheel(訳注: Pythonでパッケージを配布できるファイル形式のひとつ)を提供するpyuwsgiパッケージをインストールすることです。しかしながら、それではSSLのサポートが提供されず、代わりにリバースプロキシを使って(SSLサポートは)提供されることになります uWSGI has multiple ways to install it. The most straightforward is to install the ``pyuwsgi`` package, which provides precompiled wheels for common platforms. However, it does not provide SSL support, which can be provided with a reverse proxy instead.

virtualenvを作成し、アプリケーションをインストールし、それからpyuwsgiをインストールします。 Create a virtualenv, install your application, then install ``pyuwsgi``.

$ cd hello-app
$ python -m venv venv
$ . venv/bin/activate
$ pip install .  # install your application
$ pip install pyuwsgi

もし利用可能なコンパイラがある場合、uwsgiパッケージを代わりにインストールできます。または、wheelの代わりにsdist(訳注: Pythonパッケージを配布できる別のファイル形式)からpyuwsgiパッケージをインストールします。どちらの手法でもSSLのサポートが含まれます。 If you have a compiler available, you can install the ``uwsgi`` package instead. Or install the ``pyuwsgi`` package from sdist instead of wheel. Either method will include SSL support.

$ pip install uwsgi

# or
$ pip install --no-binary pyuwsgi pyuwsgi

実行 Running

uWSGIを走らせる最も基本的なやり方は、HTTPサーバを開始しFlaskアプリケーションをimportするように伝えることです。 The most basic way to run uWSGI is to tell it to start an HTTP server and import your application.

$ uwsgi --http 127.0.0.1:8000 --master -p 4 -w hello:app

*** Starting uWSGI 2.0.20 (64bit) on [x] ***
*** Operational MODE: preforking ***
mounting hello:app on /
spawned uWSGI master process (pid: x)
spawned uWSGI worker 1 (pid: x, cores: 1)
spawned uWSGI worker 2 (pid: x, cores: 1)
spawned uWSGI worker 3 (pid: x, cores: 1)
spawned uWSGI worker 4 (pid: x, cores: 1)
spawned uWSGI http 1 (pid: x)

もしapp factoryパターンを使っている場合、Flaskアプリケーションのインスタンスを作成する小さなPythonファイルを作成し、それからuWSGIがそのスクリプトを指すようにする必要があります。 If you're using the app factory pattern, you'll need to create a small Python file to create the app, then point uWSGI at that.

wsgi.py
from hello import create_app

app = create_app()
$ uwsgi --http 127.0.0.1:8000 --master -p 4 -w wsgi:app

--httpオプションはHTTPサーバを(上の例では)127.0.0.1の8000番ポートで開始します。--masterオプションは標準のworker managerを指定します。-pオプションは4つのworkerプロセスを開始します; 開始時の値はCPU * 2にできるでしょう。-wオプションはどのようにFlaskアプリケーションをimportするかをuWSGIに伝えます。 The ``--http`` option starts an HTTP server at 127.0.0.1 port 8000. The ``--master`` option specifies the standard worker manager. The ``-p`` option starts 4 worker processes; a starting value could be ``CPU * 2``. The ``-w`` option tells uWSGI how to import your application

外部への結び付け(Binding Externally) Binding Externally

アプリケーションのコードがrootとして走るようになり、安全ではなくなるため、uWSGIは以下に示す設定でrootとして走らせないようにするべきです。しかしながら、これはポート80や443に結びつけ(bind)出来なくなることを意味します(訳注: 一般的なLinuxでは、およそ1000より小さなポート番号は、セキュリティ対策のためroot権限を持たないプログラムではbindできないようになっており、従ってroot権限がないWSGIサーバではHTTPやHTTPSで標準的に使われる80や443番ポートでリクエストを受け付けられないことになります)。代わりに、nginxまたはApache httpdのようなリバースプロキシをuWSGIの前面に使うべきです。uWSGIをrootとして安全に走らせることは可能ですが、それはこのドキュメントの範囲外です。 uWSGI should not be run as root with the configuration shown in this doc because it would cause your application code to run as root, which is not secure. However, this means it will not be possible to bind to port 80 or 443. Instead, a reverse proxy such as :doc:`nginx` or :doc:`apache-httpd` should be used in front of uWSGI. It is possible to run uWSGI as root securely, but that is beyond the scope of this doc.

uWSGIは標準のHTTPプロキシとして使う代わりに、Nginx uWSGIApache mod_proxy_uwsgi、そしておそらくその他のサーバとの統合に最適化されています。その設定はこのドキュメントの範囲外であり、更なる情報はリンク先を見てください。 uWSGI has optimized integration with `Nginx uWSGI`_ and `Apache mod_proxy_uwsgi`_, and possibly other servers, instead of using a standard HTTP proxy. That configuration is beyond the scope of this doc, see the links for more information.

外部からアクセスできる全てのIPアドレスのroot権限不要なポートは、--http 0.0.0.0:8000オプションを使って結び付け(bind)できます。これは、リバースプロキシを用意しているときは行わないでください、さもなければリバースプロキシを迂回することが可能になります。 You can bind to all external IPs on a non-privileged port using the ``--http 0.0.0.0:8000`` option. Don't do this when using a reverse proxy setup, otherwise it will be possible to bypass the proxy.

$ uwsgi --http 0.0.0.0:8000 --master -p 4 -w wsgi:app

0.0.0.0はアクセスするには適切なアドレスではないため、ブラウザでは具体的なIPアドレスを使うべきです。 ``0.0.0.0`` is not a valid address to navigate to, you'd use a specific IP address in your browser.

geventを使ったasync Async with gevent

標準設定の同期処理のworkerは多くの使用状況で適切なものです。もし非同期のサポートが必要な場合、uWSGIはgeventのworkerを提供します。これはPythonのasync/await、またはASGIサーバの仕様と同じものではありません。このworkerを使用して得られるいかなる利点も見るためには、自分のコードの中で実際にgeventを使用する必要があります。 The default sync worker is appropriate for many use cases. If you need asynchronous support, uWSGI provides a `gevent`_ worker. This is not the same as Python's ``async/await``, or the ASGI server spec. You must actually use gevent in your own code to see any benefit to using the worker.

geventを使うときは、greenlet>=1.0が必要であり、さもなければrequestのようなコンテキストの局所領域(context local)は期待通りに働かないでしょう。PyPyを使うときは、PyPy>=7.3.7が必要です。 When using gevent, greenlet>=1.0 is required, otherwise context locals such as ``request`` will not work as expected. When using PyPy, PyPy>=7.3.7 is required.

$ uwsgi --http 127.0.0.1:8000 --master --gevent 100 -w wsgi:app

*** Starting uWSGI 2.0.20 (64bit) on [x] ***
*** Operational MODE: async ***
mounting hello:app on /
spawned uWSGI master process (pid: x)
spawned uWSGI worker 1 (pid: x, cores: 100)
spawned uWSGI http 1 (pid: x)
*** running gevent loop engine [addr:x] ***