uWSGI

提供: ArchWiki
2023年10月28日 (土) 14:17時点におけるKgx (トーク | 投稿記録)による版 (ヒントとテクニックを翻訳して追加)
ナビゲーションに移動 検索に移動

uWSGI は高速で自己回復機能のある、開発者とシステム管理人に優しいアプリケーションコンテナサーバーです。C だけで書かれています。

インストール

公式リポジトリuwsgi パッケージをインストールしてください。パッケージをコンパクトにするために、プラグインは付属していません。外部プラグインは別にインストールする必要があります。C で書かれているためとても効率的なソフトウェアです。gunicorn など Python で書かれた代替も存在しますが、どうしても動作は遅くなってしまいます。

サービスの起動

ノート: アプリケーション (Python アプリケーション) ごとにそれぞれ uwsgi サービスのインスタンスを作成するのが一番シンプルな構成です。uwsgi サービスを有効化・起動する前に、/etc/uwsgi/ の中に同一の名前の設定ファイルを作成してください。以下では /etc/uwsgi/helloworld.ini を使っています。

スタートアップ時にデフォルトで uwsgi サービスを有効にするには、次を実行:

# systemctl enable uwsgi@helloworld

これで /etc/uwsgi/helloworld.ini 設定されたアプリケーションのサービスが有効になります。また、以下のコマンドを使ってソケットインターフェイスで有効にすることも可能です:

# systemctl enable uwsgi@helloworld.socket

もしくは、Emperor モード サービスを実行することができます。このモードを使うと uwsgi インスタンスで (emperor と呼ばれる) メインスーパーバイザーを使って様々なアプリ (vassal と呼ばれます) が動くようになります。有効にするには、次を入力:

# systemctl enable emperor.uwsgi

ソケットを使うこともできます:

# systemctl enable emperor.uwsgi.socket

Emperor の設定は /etc/uwsgi/emperor.ini にあります。

設定

ノート: 標準インストールでは /etc/uwsgi/archlinux.ini は付属していません。

/etc/uwsgi/ 内のファイルを編集することで設定ができます。パッケージに含まれているビルドファイルは /etc/uwsgi/archlinux.ini に存在します。

詳しくは uwsgi のドキュメント を見て下さい。

ノート: 全てのオプションのリストは次の資料を参照してください: http://uwsgi-docs.readthedocs.org/en/latest/Options.html
アプリケーションの設定

以下は python をサポートするシンプルな例です。pacman で community リポジトリから uwsgi-plugin-python または uwsgi-plugin-python2[リンク切れ: パッケージが存在しません] プラグインをインストールする必要があります。

[uwsgi]
chdir = /srv/http/helloworld
module = helloworld
plugins = python

以下のような構文を使うことで uwsgi を別個に実行することも可能です:

ノート: pacman でインストールした uwsgi から --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 プラグインをインストール: uwsgi-plugin-php

/etc/uwsgi/mysite.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

Nginx 設定:

location = /index.php {
    include uwsgi_params;
    uwsgi_modifier1 14;
    uwsgi_pass unix:/run/uwsgi/mysite.sock;
}
Nginx の設定
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;
}

ヒントとテクニック

uWSGI が提供する一部の機能は、公式リポジトリ で提供される systemd サービスファイルを使用してアクセスすることはできません。 これらの変更点については、次のセクションで説明します。詳細については、[1] を参照してください。

ソケットのアクティブ化

ソケットアクティベーションを使用して、次のことを行います。

  • 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 がリストに提供する可能性があり、systemdSuccessExitStatus ディレクティブを使用して成功として処理します (詳細については、[2] を参照)

/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) および [3] を参照してください。)

/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
ノート:
  • NoNewPrivileges=yesMailman の cgi フロントエンドでは動作しません!この設定を併用したい場合は削除してください。
  • さらに強固にしたいのであれば、名前空間を使うことをお勧めします。このトピックについては uWSGI namespaces documentation をご覧ください。

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 サーバーでは機能しません。詳細については、[4] を参照してください。

参照