「UWSGI」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(トラブルシューティングを翻訳して追加)
(リンクを修正)
 
(同じ利用者による、間の5版が非表示)
2行目: 2行目:
 
[[Category:ウェブサーバー]]
 
[[Category:ウェブサーバー]]
 
[[en:UWSGI]]
 
[[en:UWSGI]]
uWSGI は高速で自己復機能、開発者システム管理に優しいアプリケーションコンテナサーバーです。C だけで書かれています。
+
[https://uwsgi-docs.readthedocs.io/en/latest/ uWSGI]、純粋な C でコーディングされた、高速で自己復機能、開発者/システム管理に優しいアプリケーションコンテナ サーバーです。
  +
  +
{{Pkg|gunicorn}} など、Python で書かれた代替手段もあります。
   
 
== インストール ==
 
== インストール ==
   
[[公式リポジトリ]]の {{Pkg|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}}{{Broken package link|パッケージが存在しません}} プラグインをインストールする必要があります。
 
   
  +
以下は、[[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 {
 
include uwsgi_params;
 
uwsgi_modifier1 14;
 
uwsgi_pass unix:/run/uwsgi/mysite.sock;
 
}
 
   
===== Nginx の設定 =====
+
==== Nginx (chroot 内) ====
   
  +
{{Note|このセクションは、[[Nginx#chroot でのインストール]] の説明に従って Nginx をデプロイしていることを前提としています。Nginx chroot は {{ic|/srv/http}} にあると想定されています。}}
location / {
 
  +
root /usr/share/nginx/html;
 
  +
まず、アプリケーションを指す ini ファイルを作成します。
index index.html index.htm;
 
  +
include uwsgi_params;
 
  +
{{hc|/etc/uwsgi/application1.ini|<nowiki>
# uwsgi_pass unix:/var/run/uwsgi/helloworld.sock;
 
  +
[uwsgi]
uwsgi_pass 127.0.0.1:3031;
 
  +
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>}}
   
 
== トラブルシューティング ==
 
== トラブルシューティング ==

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 と呼ばれる) を実行できるようになります。

ノート: プラグインは、そのオプションを使用する前に明示的にロードする必要があります。そうしないと、オプションが認識されません。これは、--plugins コマンドラインオプション、または設定ファイル内の plugins 変数を使用して実行できます。

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 として実行することは避けてください。

ノート: 使用中の動作モードに注意してください。--lazy-apps を使用せずにプリフォークすると、明らかではない動作が発生する可能性があります。デフォルトでは、Python プラグインは GIL を初期化しません。これは、アプリで生成されたスレッドが実行されないことを意味します。スレッドが必要な場合は、enable-threads を使用してスレッドを有効にしてください。マルチスレッドモード (スレッドオプションを使用) で uWSGI を実行すると、スレッドサポートが自動的に有効になります。この 奇妙な デフォルト動作はパフォーマンス上の理由からで、気にする必要はありません。[1]

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 サーバーのバックエンドとして使用できます。以下に構成例を示します。

ノート: パフォーマンスとセキュリティの両方の観点から構成を理解するには、uWSGI ドキュメントを一読することをお勧めします。

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;
}
# ...
ヒント: Web アプリケーションに適合する uwsgi_modifier1 パラメータのリストについては、ドキュメント を参照してください。

Nginx (chroot 内)

ノート: このセクションは、Nginx#chroot でのインストール の説明に従って Nginx をデプロイしていることを前提としています。Nginx chroot は /srv/http にあると想定されています。

まず、アプリケーションを指す 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

ノート:
  • アプリケーションが /srv/http/www/application1 内に配置されている必要があります。

設定によっては、アプリケーションはキャッシュされるかもしれません。

  • python アプリケーションをデプロイしている場合、標準の python ライブラリをコピーする必要があるかもしれません python 3 で開発している場合、/usr/lib/python3.6から/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

サービスファイル内で通知を無効にする必要があります。

/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
ノート: PID ファイルは /srv/http/run ではなく /run 内に作成されます

変更後は必ず 再起動 を行って、新しいユニットまたは変更されたユニットを組み込んでください。

その後、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;
        }
    }
...

application1127.0.0.1 で提供されるように、nginx.service再起動 してください。

uWSGI の実行

ノート: これは、使用される Web アプリケーションが適切に構成されており、Web サーバーによって提供され、使用しているソケットまたはポートにリダイレクトされ、/etc/uwsgi/ で設定されていることが前提となります。わかりやすくするために、設定ファイル名には英数字と _ のみを含めてエスケープの問題を避ける必要があります。systemd.unit(5) § STRING ESCAPING FOR INCLUSION IN UNIT NAMES を参照してください。

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 がリストに提供する可能性があり、systemdSuccessExitStatus ディレクティブを使用して成功として処理します (詳細については、[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
ノート:
  • 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 サーバーでは機能しません。詳細については、[5] を参照してください。

参照