「UWSGI」の版間の差分
Kusakata.bot (トーク | 投稿記録) 細 (文字列「http://www.youtube.com/」を「https://www.youtube.com/」に置換) |
(リンクを修正) |
||
(2人の利用者による、間の7版が非表示) | |||
2行目: | 2行目: | ||
[[Category:ウェブサーバー]] |
[[Category:ウェブサーバー]] |
||
[[en:UWSGI]] |
[[en:UWSGI]] |
||
− | uWSGI は高速で自己 |
+ | [https://uwsgi-docs.readthedocs.io/en/latest/ uWSGI] は、純粋な C でコーディングされた、高速で自己修復機能があり、開発者/システム管理者に優しいアプリケーションコンテナ サーバーです。 |
+ | |||
+ | {{Pkg|gunicorn}} など、Python で書かれた代替手段もあります。 |
||
== インストール == |
== インストール == |
||
− | + | {{Pkg|uwsgi}} パッケージを [[インストール]] します。プラグインは個別にインストールする必要があります (パッケージ名は {{ic|uwsgi-plugin-}} で始まります。) |
|
− | == |
+ | == 設定 == |
+ | uWSGI によって提供される [[ウェブアプリケーション]] は、{{ic|/etc/uwsgi/}} で設定されており、それぞれに独自の構成ファイル (ini 形式) が必要です。詳細については、[https://uwsgi-docs.readthedocs.org/en/latest/ uWSGI ドキュメント] をご覧ください。 |
||
− | {{Note|アプリケーション (Python アプリケーション) ごとにそれぞれ uwsgi サービスのインスタンスを作成するのが一番シンプルな構成です。uwsgi サービスを有効化・起動する前に、{{ic|/etc/uwsgi/}} の中に同一の名前の設定ファイルを作成してください。以下では {{ic|/etc/uwsgi/helloworld.ini}} を使っています。}} |
||
+ | あるいは、[https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html Emperor モード] ({{ic|/etc/uwsgi/emperor.ini}} で設定) して uWSGI を実行することもできます。これにより、単一の uWSGI インスタンスが、単一のメインスーパーバイザー (Emperor と呼ばれる) を使用して、一連の異なるアプリ (vassals と呼ばれる) を実行できるようになります。 |
||
− | スタートアップ時にデフォルトで uwsgi サービスを有効にするには、次を実行: |
||
− | # systemctl enable uwsgi@helloworld |
||
+ | {{Note|プラグインは、そのオプションを使用する前に明示的にロードする必要があります。そうしないと、オプションが認識されません。これは、{{ic|--plugins}} コマンドラインオプション、または設定ファイル内の {{ic|plugins}} 変数を使用して実行できます。}} |
||
− | これで {{ic|/etc/uwsgi/helloworld.ini}} 設定されたアプリケーションのサービスが有効になります。また、以下のコマンドを使ってソケットインターフェイスで有効にすることも可能です: |
||
− | # systemctl enable uwsgi@helloworld.socket |
||
+ | === Web アプリケーション === |
||
− | もしくは、[http://uwsgi-docs.readthedocs.org/en/latest/Emperor.html Emperor モード] サービスを実行することができます。このモードを使うと uwsgi インスタンスで (emperor と呼ばれる) メインスーパーバイザーを使って様々なアプリ (vassal と呼ばれます) が動くようになります。有効にするには、次を入力: |
||
− | # systemctl enable emperor.uwsgi |
||
+ | uWSGI はさまざまな言語をサポートしているため、多くの Web アプリケーションもサポートしています。 |
||
− | ソケットを使うこともできます: |
||
+ | 例として、設定ファイル {{ic|/etc/uwsgi/example.ini}} と、Web アプリケーションに必要なプラグインが事前にインストールされていることを前提としています。 |
||
− | # systemctl enable emperor.uwsgi.socket |
||
+ | ==== Python ==== |
||
− | Emperor の設定は {{ic|/etc/uwsgi/emperor.ini}} にあります。 |
||
+ | 以下は、[[Python]] アプリケーションの簡単な例です。 |
||
− | == 設定 == |
||
+ | {{hc|/etc/uwsgi/example.ini|2= |
||
− | {{Note|標準インストールでは {{ic|/etc/uwsgi/archlinux.ini}} は付属していません。}} |
||
+ | [uwsgi] |
||
+ | chdir = /srv/http/example |
||
+ | module = example |
||
+ | plugins = python |
||
+ | }} |
||
+ | たとえば、次の構文を使用して uWSGI を個別に実行することもできます。 |
||
− | {{ic|/etc/uwsgi/}} 内のファイルを編集することで設定ができます。パッケージに含まれているビルドファイルは {{ic|/etc/uwsgi/archlinux.ini}} に存在します。 |
||
+ | $ uwsgi --socket 127.0.0.1:3031 --plugin python2 --wsgi-file ~/foo.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 --uid --gid |
||
− | 詳しくは [http://uwsgi-docs.readthedocs.org/en/latest/ uwsgi のドキュメント] を見て下さい。 |
||
+ | このコマンドを root として実行することは避けてください。 |
||
− | {{Note|全てのオプションのリストは次の資料を参照してください: http://uwsgi-docs.readthedocs.org/en/latest/Options.html 。}} |
||
+ | {{Note|使用中の動作モードに注意してください。--lazy-apps を使用せずにプリフォークすると、明らかではない動作が発生する可能性があります。デフォルトでは、Python プラグインは GIL を初期化しません。これは、アプリで生成されたスレッドが実行されないことを意味します。スレッドが必要な場合は、enable-threads を使用してスレッドを有効にしてください。マルチスレッドモード (スレッドオプションを使用) で uWSGI を実行すると、スレッドサポートが自動的に有効になります。この ''奇妙な'' デフォルト動作はパフォーマンス上の理由からで、気にする必要はありません。[https://uwsgi-docs.readthedocs.io/en/latest/ThingsToKnow.html]}} |
||
− | ===== アプリケーションの設定 ===== |
||
+ | ==== PHP ==== |
||
− | 以下は python をサポートするシンプルな例です。pacman で community リポジトリから {{Pkg|uwsgi-plugin-python}} または {{Pkg|uwsgi-plugin-python2}} プラグインをインストールする必要があります。 |
||
+ | 以下は、[[PHP]] ベースの Web サイトの簡単な例です。 |
||
− | [uwsgi] |
||
− | chdir = /srv/http/helloworld |
||
− | module = helloworld |
||
− | plugins = python |
||
+ | {{hc|/etc/uwsgi/example.ini|2= |
||
− | 以下のような構文を使うことで uwsgi を別個に実行することも可能です: |
||
− | |||
− | {{Note|pacman でインストールした uwsgi から {{ic|--wsgi-file}} オプションを使うことはできません。公式ガイドではソースからビルドすることを推奨しています (http://uwsgi-docs.readthedocs.org/en/latest/WSGIquickstart.html#installing-uwsgi-with-python-support を参照)。}} |
||
− | |||
− | uwsgi --socket 127.0.0.1:3031 --plugin python2 --wsgi-file ~/foo.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 --uid --gid |
||
− | |||
− | 上記のコマンドを root で実行するのは止めてください。 |
||
− | |||
− | ==== Php アプリケーション ==== |
||
− | uwsgi の php プラグインをインストール: {{Pkg|uwsgi-plugin-php}} |
||
− | |||
− | {{hc|/etc/uwsgi/mysite.ini|<nowiki> |
||
[uwsgi] |
[uwsgi] |
||
; maximum number of worker processes |
; maximum number of worker processes |
||
73行目: | 63行目: | ||
; clear environment on exit |
; clear environment on exit |
||
vacuum = true |
vacuum = true |
||
+ | }} |
||
+ | |||
+ | === Web サーバー === |
||
+ | |||
+ | uWSGI は、アクセスの転送をサポートする多くの Web サーバーのバックエンドとして使用できます。以下に構成例を示します。 |
||
+ | |||
+ | {{Note|パフォーマンスとセキュリティの両方の観点から構成を理解するには、uWSGI ドキュメントを一読することをお勧めします。}} |
||
+ | |||
+ | ==== Nginx ==== |
||
+ | |||
+ | [[nginx]] は、Web アプリケーションに応じて、UNIX ソケットまたはポート (ローカルホストまたはリモートマシン上) にアクセスをリダイレクトできます。 |
||
+ | |||
+ | {{hc|/etc/nginx/example.conf|<nowiki> |
||
+ | # ... |
||
+ | # forward all access to / towards |
||
+ | location / { |
||
+ | root /usr/share/nginx/html; |
||
+ | index index.html index.htm; |
||
+ | include uwsgi_params; |
||
+ | # this is the correct uwsgi_modifier1 parameter for a php based application |
||
+ | uwsgi_modifier1 14; |
||
+ | # uncomment the following if you want to use the unix socket instead |
||
+ | # uwsgi_pass unix:/var/run/uwsgi/example.sock; |
||
+ | # access is redirected to localhost:3031 |
||
+ | uwsgi_pass 127.0.0.1:3031; |
||
+ | } |
||
+ | # ... |
||
</nowiki>}} |
</nowiki>}} |
||
+ | {{Tip|Web アプリケーションに適合する {{ic|uwsgi_modifier1}} パラメータのリストについては、[https://uwsgi-docs.readthedocs.io/en/latest/Protocol.html#packet-descriptions ドキュメント] を参照してください。}} |
||
− | Nginx 設定: |
||
+ | |||
− | location = /index.php { |
||
+ | ==== Nginx (chroot 内) ==== |
||
− | include uwsgi_params; |
||
+ | |||
− | uwsgi_modifier1 14; |
||
+ | {{Note|このセクションは、[[Nginx#chroot でのインストール]] の説明に従って Nginx をデプロイしていることを前提としています。Nginx chroot は {{ic|/srv/http}} にあると想定されています。}} |
||
− | uwsgi_pass unix:/run/uwsgi/mysite.sock; |
||
+ | |||
− | } |
||
+ | まず、アプリケーションを指す ini ファイルを作成します。 |
||
+ | |||
+ | {{hc|/etc/uwsgi/application1.ini|<nowiki> |
||
+ | [uwsgi] |
||
+ | chroot = /srv/http |
||
+ | chdir = /www/application1 |
||
+ | wsgi-file = application1.py |
||
+ | plugins = python |
||
+ | socket = /run/application1.sock |
||
+ | uid = http |
||
+ | gid = http |
||
+ | threads = 2 |
||
+ | stats = 127.0.0.1:9191 |
||
+ | vacuum = true |
||
+ | </nowiki>}} |
||
+ | |||
+ | 上記の設定では {{ic|/srv/http}} に chroot しているため、次のような UNIX ソケットが作成されます {{ic|/srv/http/run/application1.sock}} |
||
+ | |||
+ | {{Note| |
||
+ | * アプリケーションが {{ic|/srv/http/www/application1}} 内に配置されている必要があります。 |
||
+ | 設定によっては、アプリケーションはキャッシュされるかもしれません。 |
||
+ | * python アプリケーションをデプロイしている場合、標準の python ライブラリをコピーする必要があるかもしれません python 3 で開発している場合、{{ic|/usr/lib/python3.6}}から{{ic|/srv/http/lib/python3.6}} にコピーできます。 |
||
+ | 以下を実行してみてください: |
||
+ | # cp -r -p /usr/lib/python3.6 /srv/http/lib |
||
+ | # cp -r -p /usr/lib/*python*so /srv/http/lib |
||
+ | }} |
||
+ | |||
+ | サービスファイル内で通知を無効にする必要があります。 |
||
+ | |||
+ | {{hc|/etc/systemd/system/multi-user.target.wants/uwsgi\@application1.service|<nowiki> |
||
+ | [Unit] |
||
+ | Description=uWSGI service unit |
||
+ | After=syslog.target |
||
+ | |||
+ | [Service] |
||
+ | PIDFile=/run/%I.pid |
||
+ | RemainAfterExit=yes |
||
+ | ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini |
||
+ | ExecReload=/bin/kill -HUP $MAINPID |
||
+ | ExecStop=/bin/kill -INT $MAINPID |
||
+ | Restart=always |
||
+ | StandardError=syslog |
||
+ | KillSignal=SIGQUIT |
||
+ | |||
+ | [Install] |
||
+ | WantedBy=multi-user.target |
||
+ | </nowiki>}} |
||
+ | |||
+ | {{Note|PID ファイルは {{ic|/srv/http/run}} ではなく {{ic|/run}} 内に作成されます}} |
||
+ | |||
+ | 変更後は必ず [[再起動]] を行って、新しいユニットまたは変更されたユニットを組み込んでください。 |
||
+ | |||
+ | その後、{{ic|uwsgi@application1.service}} を [[有効化]] および [[起動]] して下さい。 |
||
+ | |||
+ | {{ic|/srv/http/etc/nginx/nginx.conf}} を編集し、その中に少なくとも以下を含む新しい {{ic|server}} セクションを追加します。 |
||
+ | {{hc|/srv/http/etc/nginx/nginx.conf|<nowiki> |
||
+ | ... |
||
+ | server |
||
+ | { |
||
+ | listen 80; |
||
+ | server_name 127.0.0.1; |
||
+ | location / |
||
+ | { |
||
+ | root /www/application1; |
||
+ | include uwsgi_params; |
||
+ | uwsgi_pass unix:/run/application1.sock; |
||
+ | } |
||
+ | |||
+ | error_page 500 502 503 504 /50x.html; |
||
+ | location = /50x.html |
||
+ | { |
||
+ | root /usr/share/nginx/html; |
||
+ | } |
||
+ | } |
||
+ | ... |
||
+ | </nowiki>}} |
||
+ | |||
+ | {{ic|application1}} が {{ic|127.0.0.1}} で提供されるように、{{ic|nginx.service}} を [[再起動]] してください。 |
||
+ | |||
+ | == uWSGI の実行 == |
||
+ | |||
+ | {{Note|これは、使用される Web アプリケーションが適切に構成されており、Web サーバーによって提供され、使用しているソケットまたはポートにリダイレクトされ、{{ic|/etc/uwsgi/}} で設定されていることが前提となります。わかりやすくするために、設定ファイル名には英数字と {{ic|_}} のみを含めてエスケープの問題を避ける必要があります。{{man|5|systemd.unit|STRING ESCAPING FOR INCLUSION IN UNIT NAMES}} を参照してください。}} |
||
+ | |||
+ | Web アプリケーションを (オンデマンドでアクティブ化せずに) 常に使用する予定がある場合は、単に [[起動]] および [[有効化]] {{ic|uwsgi@example}} を実行できます。 |
||
+ | |||
+ | Web アプリケーションをオンデマンドで開始する予定の場合は、[[起動]] および [[有効化]] {{ic|uwsgi@example.socket}} を実行できます。 |
||
+ | |||
+ | Emperor モードを使用するには、{{ic|emperor.uwsgi.service}} を [[起動]] および [[有効化]] します。 |
||
+ | |||
+ | このモードのソケットアクティベーションを使用するには、{{ic|emperor.uwsgi.socket}} を [[起動]] および [[有効化]] します。 |
||
+ | |||
+ | == ヒントとテクニック == |
||
+ | |||
+ | uWSGI が提供する一部の機能は、[[公式リポジトリ]] で提供される [[systemd]] サービスファイルを使用してアクセスすることはできません。 |
||
+ | これらの変更点については、次のセクションで説明します。詳細については、[https://sleepmap.de/2016/securely-serving-webapps-using-uwsgi/] を参照してください。 |
||
+ | |||
+ | === ソケットのアクティブ化 === |
||
+ | |||
+ | ソケットアクティベーションを使用して、次のことを行います。 |
||
+ | * Web サーバーを unix ソケットに誘導し、アプリケーションを実行している uWSGI インスタンスを起動します。 |
||
+ | * アイドリング時間が経過すると、uWSGI によってアプリケーションがクローズされます。 |
||
+ | * アプリケーションがアクセスされた後、ウェブサーバが再びアプリケーションを起動できるようにしたい。 |
||
+ | |||
+ | uWSGI には、インスタンスにアプリケーションを閉じるための設定が用意されています。 |
||
+ | |||
+ | {{hc|/etc/uwsgi/example.ini|<nowiki> |
||
+ | [uwsgi] |
||
+ | # ... |
||
+ | |||
+ | # set idle time in seconds |
||
+ | idle = 600 |
||
+ | # kill the application after idle time was reached |
||
+ | die-on-idle = true |
||
+ | |||
+ | # ... |
||
+ | </nowiki>}} |
||
+ | |||
+ | しかし、現在の {{ic|uwsgi@.service}} ファイルはこれを許さない。なぜなら、[[systemd]] はゼロ以外の終了コードを失敗として扱い、それによってユニットを失敗としてマークするからであり、さらに {{ic|1=Restart=always}} ディレクティブはアイドル時間後に終了することを無意味にしてしまうからです。 |
||
+ | これを修正するには、終了コードを追加します。終了コードは、アプリケーションを単独で閉じた後に uWSGI がリストに提供する可能性があり、[[systemd]] が {{ic|SuccessExitStatus}} ディレクティブを使用して成功として処理します (詳細については、[https://sleepmap.de/2016/securely-serving-webapps-using-uwsgi/] を参照) |
||
+ | |||
+ | {{hc|/etc/systemd/system/uwsgi-socket@.service|<nowiki> |
||
+ | [Unit] |
||
+ | Description=uWSGI service unit |
||
+ | After=syslog.target |
||
+ | |||
+ | [Service] |
||
+ | ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini |
||
+ | ExecReload=/bin/kill -HUP $MAINPID |
||
+ | ExecStop=/bin/kill -INT $MAINPID |
||
+ | Type=notify |
||
+ | SuccessExitStatus=15 17 29 30 |
||
+ | StandardError=syslog |
||
+ | NotifyAccess=all |
||
+ | KillSignal=SIGQUIT |
||
+ | |||
+ | [Install] |
||
+ | WantedBy=multi-user.target |
||
+ | </nowiki>}} |
||
+ | |||
+ | これにより、アイドル後の Kill 機能を使用してソケットを適切にアクティブ化できるようになります。 |
||
+ | |||
+ | === uWSGI サービスの強化 === |
||
+ | |||
+ | Web アプリケーションは実際に公開されており、その品質と基礎となる言語のセキュリティに応じて、実行するのが他のアプリケーションよりも危険なものもあります。 |
||
+ | 安全でない可能性のある Web アプリケーションへの対処を始める良い方法は、それらを刑務所に入れることです。 [[systemd]] には、使用できる機能がいくつかあります。 |
||
+ | 次の例を見てください (詳細については、{{man|5|systemd.exec}} および [https://sleepmap.de/2016/securely-serving-webapps-using-uwsgi/] を参照してください。) |
||
+ | |||
+ | {{hc|/etc/systemd/system/uwsgi-secure@.service|<nowiki> |
||
+ | [Unit] |
||
+ | Description=uWSGI service unit |
||
+ | After=syslog.target |
||
+ | |||
+ | [Service] |
||
+ | ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini |
||
+ | ExecReload=/bin/kill -HUP $MAINPID |
||
+ | ExecStop=/bin/kill -INT $MAINPID |
||
+ | Type=notify |
||
+ | SuccessExitStatus=15 17 29 30 |
||
+ | StandardError=syslog |
||
+ | NotifyAccess=all |
||
+ | KillSignal=SIGQUIT |
||
+ | PrivateDevices=yes |
||
+ | PrivateTmp=yes |
||
+ | ProtectSystem=full |
||
+ | ReadWritePaths=/etc/webapps /var/lib/ |
||
+ | ProtectHome=yes |
||
+ | NoNewPrivileges=yes |
||
+ | |||
+ | [Install] |
||
+ | WantedBy=multi-user.target |
||
+ | </nowiki>}} |
||
+ | |||
+ | {{Note| |
||
+ | * {{ic|1=NoNewPrivileges=yes}} は [[Mailman]] の cgi フロントエンドでは動作しません!この設定を併用したい場合は削除してください。 |
||
+ | * さらに強固にしたいのであれば、名前空間を使うことをお勧めします。このトピックについては [https://uwsgi-docs.readthedocs.io/en/latest/Namespaces.html uWSGI namespaces documentation] をご覧ください。 |
||
+ | }} |
||
+ | |||
+ | === uWSGI ソケットのアクセシビリティ === |
||
+ | |||
+ | {{Pkg|uwsgi}} のデフォルト (アプリケーションごと) ソケットユニット ({{ic|uwsgi@.socket}}) では、システム上のすべてのユーザーに読み取りおよび書き込みアクセスが許可されます。 |
||
+ | ただし、systemd では、より細かく粒度の高いアクセス管理が可能です ({{man|5|systemd.socket}} を参照) これにより、UNIX ソケットへのアクセスをより制限することができます。 |
||
+ | |||
+ | (事前に [[tmpfiles]] を使って作成する必要があります。参考は [[ウェブアプリケーションパッケージガイドライン]] を参照してください)、その [[グループ]] とファイルの [[パーミッション]] を変更することで、ソケットは [[root]] と [[ウェブサーバー]] だけがアクセスできるようになり、Web アプリケーションを独自のユーザーとして実行できるようになります: |
||
+ | |||
+ | {{hc|/etc/systemd/system/uwsgi-secure@.socket|<nowiki> |
||
+ | [Unit] |
||
+ | Description=Socket for uWSGI %I |
||
+ | |||
+ | [Socket] |
||
+ | ListenStream=/run/%I/%I.sock |
||
+ | SocketGroup=http |
||
+ | SocketMode=0660 |
||
+ | |||
+ | [Install] |
||
+ | WantedBy=sockets.target |
||
+ | </nowiki>}} |
||
+ | |||
+ | == トラブルシューティング == |
||
+ | |||
+ | === Apache httpd === |
||
+ | ==== AH00957: uwsgi: attempt to connect to 127.0.0.1:0 (*) failed ==== |
||
− | ===== Nginx の設定 ===== |
||
+ | デフォルトの uWSGI ポート (3031) は、(現時点では?) Apache httpd サーバーでは機能しません。詳細については、[https://github.com/unbit/uwsgi/issues/1491] を参照してください。 |
||
− | location / { |
||
− | root /usr/share/nginx/html; |
||
− | index index.html index.htm; |
||
− | include uwsgi_params; |
||
− | # uwsgi_pass unix:/var/run/uwsgi/helloworld.sock; |
||
− | uwsgi_pass 127.0.0.1:3031; |
||
− | } |
||
== 参照 == |
== 参照 == |
2023年10月28日 (土) 14:43時点における最新版
uWSGI は、純粋な C でコーディングされた、高速で自己修復機能があり、開発者/システム管理者に優しいアプリケーションコンテナ サーバーです。
gunicorn など、Python で書かれた代替手段もあります。
目次
インストール
uwsgi パッケージを インストール します。プラグインは個別にインストールする必要があります (パッケージ名は uwsgi-plugin-
で始まります。)
設定
uWSGI によって提供される ウェブアプリケーション は、/etc/uwsgi/
で設定されており、それぞれに独自の構成ファイル (ini 形式) が必要です。詳細については、uWSGI ドキュメント をご覧ください。
あるいは、Emperor モード (/etc/uwsgi/emperor.ini
で設定) して uWSGI を実行することもできます。これにより、単一の uWSGI インスタンスが、単一のメインスーパーバイザー (Emperor と呼ばれる) を使用して、一連の異なるアプリ (vassals と呼ばれる) を実行できるようになります。
Web アプリケーション
uWSGI はさまざまな言語をサポートしているため、多くの Web アプリケーションもサポートしています。
例として、設定ファイル /etc/uwsgi/example.ini
と、Web アプリケーションに必要なプラグインが事前にインストールされていることを前提としています。
Python
以下は、Python アプリケーションの簡単な例です。
/etc/uwsgi/example.ini
[uwsgi] chdir = /srv/http/example module = example plugins = python
たとえば、次の構文を使用して uWSGI を個別に実行することもできます。
$ uwsgi --socket 127.0.0.1:3031 --plugin python2 --wsgi-file ~/foo.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191 --uid --gid
このコマンドを root として実行することは避けてください。
PHP
以下は、PHP ベースの Web サイトの簡単な例です。
/etc/uwsgi/example.ini
[uwsgi] ; maximum number of worker processes processes = 4 ; the user and group id of the process once it’s started uid = http gid = http socket = /run/uwsgi/%n.sock master = true chdir = /srv/http/%n ; php plugins = php ; jail our php environment php-docroot = /srv/http/%n php-index = index.php ; clear environment on exit vacuum = true
Web サーバー
uWSGI は、アクセスの転送をサポートする多くの Web サーバーのバックエンドとして使用できます。以下に構成例を示します。
Nginx
nginx は、Web アプリケーションに応じて、UNIX ソケットまたはポート (ローカルホストまたはリモートマシン上) にアクセスをリダイレクトできます。
/etc/nginx/example.conf
# ... # forward all access to / towards location / { root /usr/share/nginx/html; index index.html index.htm; include uwsgi_params; # this is the correct uwsgi_modifier1 parameter for a php based application uwsgi_modifier1 14; # uncomment the following if you want to use the unix socket instead # uwsgi_pass unix:/var/run/uwsgi/example.sock; # access is redirected to localhost:3031 uwsgi_pass 127.0.0.1:3031; } # ...
Nginx (chroot 内)
まず、アプリケーションを指す ini ファイルを作成します。
/etc/uwsgi/application1.ini
[uwsgi] chroot = /srv/http chdir = /www/application1 wsgi-file = application1.py plugins = python socket = /run/application1.sock uid = http gid = http threads = 2 stats = 127.0.0.1:9191 vacuum = true
上記の設定では /srv/http
に chroot しているため、次のような UNIX ソケットが作成されます /srv/http/run/application1.sock
サービスファイル内で通知を無効にする必要があります。
/etc/systemd/system/multi-user.target.wants/uwsgi\@application1.service
[Unit] Description=uWSGI service unit After=syslog.target [Service] PIDFile=/run/%I.pid RemainAfterExit=yes ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -INT $MAINPID Restart=always StandardError=syslog KillSignal=SIGQUIT [Install] WantedBy=multi-user.target
変更後は必ず 再起動 を行って、新しいユニットまたは変更されたユニットを組み込んでください。
その後、uwsgi@application1.service
を 有効化 および 起動 して下さい。
/srv/http/etc/nginx/nginx.conf
を編集し、その中に少なくとも以下を含む新しい server
セクションを追加します。
/srv/http/etc/nginx/nginx.conf
... server { listen 80; server_name 127.0.0.1; location / { root /www/application1; include uwsgi_params; uwsgi_pass unix:/run/application1.sock; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } ...
application1
が 127.0.0.1
で提供されるように、nginx.service
を 再起動 してください。
uWSGI の実行
Web アプリケーションを (オンデマンドでアクティブ化せずに) 常に使用する予定がある場合は、単に 起動 および 有効化 uwsgi@example
を実行できます。
Web アプリケーションをオンデマンドで開始する予定の場合は、起動 および 有効化 uwsgi@example.socket
を実行できます。
Emperor モードを使用するには、emperor.uwsgi.service
を 起動 および 有効化 します。
このモードのソケットアクティベーションを使用するには、emperor.uwsgi.socket
を 起動 および 有効化 します。
ヒントとテクニック
uWSGI が提供する一部の機能は、公式リポジトリ で提供される systemd サービスファイルを使用してアクセスすることはできません。 これらの変更点については、次のセクションで説明します。詳細については、[2] を参照してください。
ソケットのアクティブ化
ソケットアクティベーションを使用して、次のことを行います。
- Web サーバーを unix ソケットに誘導し、アプリケーションを実行している uWSGI インスタンスを起動します。
- アイドリング時間が経過すると、uWSGI によってアプリケーションがクローズされます。
- アプリケーションがアクセスされた後、ウェブサーバが再びアプリケーションを起動できるようにしたい。
uWSGI には、インスタンスにアプリケーションを閉じるための設定が用意されています。
/etc/uwsgi/example.ini
[uwsgi] # ... # set idle time in seconds idle = 600 # kill the application after idle time was reached die-on-idle = true # ...
しかし、現在の uwsgi@.service
ファイルはこれを許さない。なぜなら、systemd はゼロ以外の終了コードを失敗として扱い、それによってユニットを失敗としてマークするからであり、さらに Restart=always
ディレクティブはアイドル時間後に終了することを無意味にしてしまうからです。
これを修正するには、終了コードを追加します。終了コードは、アプリケーションを単独で閉じた後に uWSGI がリストに提供する可能性があり、systemd が SuccessExitStatus
ディレクティブを使用して成功として処理します (詳細については、[3] を参照)
/etc/systemd/system/uwsgi-socket@.service
[Unit] Description=uWSGI service unit After=syslog.target [Service] ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -INT $MAINPID Type=notify SuccessExitStatus=15 17 29 30 StandardError=syslog NotifyAccess=all KillSignal=SIGQUIT [Install] WantedBy=multi-user.target
これにより、アイドル後の Kill 機能を使用してソケットを適切にアクティブ化できるようになります。
uWSGI サービスの強化
Web アプリケーションは実際に公開されており、その品質と基礎となる言語のセキュリティに応じて、実行するのが他のアプリケーションよりも危険なものもあります。 安全でない可能性のある Web アプリケーションへの対処を始める良い方法は、それらを刑務所に入れることです。 systemd には、使用できる機能がいくつかあります。 次の例を見てください (詳細については、systemd.exec(5) および [4] を参照してください。)
/etc/systemd/system/uwsgi-secure@.service
[Unit] Description=uWSGI service unit After=syslog.target [Service] ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/%I.ini ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -INT $MAINPID Type=notify SuccessExitStatus=15 17 29 30 StandardError=syslog NotifyAccess=all KillSignal=SIGQUIT PrivateDevices=yes PrivateTmp=yes ProtectSystem=full ReadWritePaths=/etc/webapps /var/lib/ ProtectHome=yes NoNewPrivileges=yes [Install] WantedBy=multi-user.target
uWSGI ソケットのアクセシビリティ
uwsgi のデフォルト (アプリケーションごと) ソケットユニット (uwsgi@.socket
) では、システム上のすべてのユーザーに読み取りおよび書き込みアクセスが許可されます。
ただし、systemd では、より細かく粒度の高いアクセス管理が可能です (systemd.socket(5) を参照) これにより、UNIX ソケットへのアクセスをより制限することができます。
(事前に tmpfiles を使って作成する必要があります。参考は ウェブアプリケーションパッケージガイドライン を参照してください)、その グループ とファイルの パーミッション を変更することで、ソケットは root と ウェブサーバー だけがアクセスできるようになり、Web アプリケーションを独自のユーザーとして実行できるようになります:
/etc/systemd/system/uwsgi-secure@.socket
[Unit] Description=Socket for uWSGI %I [Socket] ListenStream=/run/%I/%I.sock SocketGroup=http SocketMode=0660 [Install] WantedBy=sockets.target
トラブルシューティング
Apache httpd
AH00957: uwsgi: attempt to connect to 127.0.0.1:0 (*) failed
デフォルトの uWSGI ポート (3031) は、(現時点では?) Apache httpd サーバーでは機能しません。詳細については、[5] を参照してください。