「UWSGI」の版間の差分
Kusanaginoturugi (トーク | 投稿記録) (→サービスの起動: 英語版より記述を追加) |
(リンクを修正) |
||
(5人の利用者による、間の14版が非表示) | |||
1行目: | 1行目: | ||
+ | {{Lowercase title}} |
||
[[Category:ウェブサーバー]] |
[[Category:ウェブサーバー]] |
||
− | [[en: |
+ | [[en: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|In the most simple configuration each application (i.e. python application) will get its own instance of uwsgi service. |
||
− | Before uwsgi service can be enabled/started a configuration file with the same name must be created within {{ic|/etc/uwsgi/}} |
||
− | When reading following lines assume that {{ic|/etc/uwsgi/helloworld.ini}} was created.}} |
||
+ | あるいは、[https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html Emperor モード] ({{ic|/etc/uwsgi/emperor.ini}} で設定) して uWSGI を実行することもできます。これにより、単一の uWSGI インスタンスが、単一のメインスーパーバイザー (Emperor と呼ばれる) を使用して、一連の異なるアプリ (vassals と呼ばれる) を実行できるようになります。 |
||
− | {{Style|does not comply with [[Help:Style#systemd units operations]]}} |
||
+ | {{Note|プラグインは、そのオプションを使用する前に明示的にロードする必要があります。そうしないと、オプションが認識されません。これは、{{ic|--plugins}} コマンドラインオプション、または設定ファイル内の {{ic|plugins}} 変数を使用して実行できます。}} |
||
− | スタートアップ時にデフォルトで uwsgi サービスを有効にするには、次を実行: |
||
− | # systemctl enable uwsgi@helloworld |
||
+ | === Web アプリケーション === |
||
− | これで {{ic|/etc/uwsgi/helloworld.ini}} 設定されたアプリケーションのサービスが有効になります。また、以下のコマンドを使ってソケットインターフェイスで有効にすることも可能です: |
||
− | # systemctl enable uwsgi@helloworld.socket |
||
+ | uWSGI はさまざまな言語をサポートしているため、多くの Web アプリケーションもサポートしています。 |
||
− | もしくは、[http://uwsgi-docs.readthedocs.org/en/latest/Emperor.html Emperor モード] サービスを実行することができます。このモードを使うと uwsgi インスタンスで (emperor と呼ばれる) メインスーパーバイザーを使って様々なアプリ (vassal と呼ばれます) が動くようになります。有効にするには、次を入力: |
||
+ | 例として、設定ファイル {{ic|/etc/uwsgi/example.ini}} と、Web アプリケーションに必要なプラグインが事前にインストールされていることを前提としています。 |
||
− | # systemctl enable emperor.uwsgi |
||
+ | ==== Python ==== |
||
− | ソケットを使うこともできます: |
||
− | # systemctl enable emperor.uwsgi.socket |
||
+ | 以下は、[[Python]] アプリケーションの簡単な例です。 |
||
− | Emperor の設定は {{ic|/etc/uwsgi/emperor.ini}} にあります。 |
||
+ | {{hc|/etc/uwsgi/example.ini|2= |
||
− | == 設定 == |
||
+ | [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 として実行することは避けてください。 |
||
+ | |||
+ | {{Note|使用中の動作モードに注意してください。--lazy-apps を使用せずにプリフォークすると、明らかではない動作が発生する可能性があります。デフォルトでは、Python プラグインは GIL を初期化しません。これは、アプリで生成されたスレッドが実行されないことを意味します。スレッドが必要な場合は、enable-threads を使用してスレッドを有効にしてください。マルチスレッドモード (スレッドオプションを使用) で uWSGI を実行すると、スレッドサポートが自動的に有効になります。この ''奇妙な'' デフォルト動作はパフォーマンス上の理由からで、気にする必要はありません。[https://uwsgi-docs.readthedocs.io/en/latest/ThingsToKnow.html]}} |
||
+ | |||
+ | ==== PHP ==== |
||
+ | |||
+ | 以下は、[[PHP]] ベースの Web サイトの簡単な例です。 |
||
+ | |||
+ | {{hc|/etc/uwsgi/example.ini|2= |
||
+ | [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 サーバーのバックエンドとして使用できます。以下に構成例を示します。 |
||
+ | |||
+ | {{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>}} |
||
+ | |||
+ | {{Tip|Web アプリケーションに適合する {{ic|uwsgi_modifier1}} パラメータのリストについては、[https://uwsgi-docs.readthedocs.io/en/latest/Protocol.html#packet-descriptions ドキュメント] を参照してください。}} |
||
+ | |||
+ | ==== Nginx (chroot 内) ==== |
||
+ | |||
+ | {{Note|このセクションは、[[Nginx#chroot でのインストール]] の説明に従って Nginx をデプロイしていることを前提としています。Nginx chroot は {{ic|/srv/http}} にあると想定されています。}} |
||
+ | |||
+ | まず、アプリケーションを指す 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 ソケットのアクセシビリティ === |
||
− | {{ic|/etc/uwsgi/}} 内のファイルを編集することで設定ができます。パッケージに含まれているビルドファイルは {{ic|/etc/uwsgi/archlinux.ini}} に存在します。 |
||
+ | {{Pkg|uwsgi}} のデフォルト (アプリケーションごと) ソケットユニット ({{ic|uwsgi@.socket}}) では、システム上のすべてのユーザーに読み取りおよび書き込みアクセスが許可されます。 |
||
− | 詳しくは [http://uwsgi-docs.readthedocs.org/en/latest/ uwsgi のドキュメント] を見て下さい。 |
||
+ | ただし、systemd では、より細かく粒度の高いアクセス管理が可能です ({{man|5|systemd.socket}} を参照) これにより、UNIX ソケットへのアクセスをより制限することができます。 |
||
+ | (事前に [[tmpfiles]] を使って作成する必要があります。参考は [[ウェブアプリケーションパッケージガイドライン]] を参照してください)、その [[グループ]] とファイルの [[パーミッション]] を変更することで、ソケットは [[root]] と [[ウェブサーバー]] だけがアクセスできるようになり、Web アプリケーションを独自のユーザーとして実行できるようになります: |
||
− | ===== アプリケーションの設定 ===== |
||
+ | {{hc|/etc/systemd/system/uwsgi-secure@.socket|<nowiki> |
||
− | 以下は python をサポートするシンプルな例です。pacman で community リポジトリから uwsgi-plugin-python または uwsgi-plugin-python2 プラグインをインストールする必要があります。 |
||
+ | [Unit] |
||
+ | Description=Socket for uWSGI %I |
||
− | + | [Socket] |
|
+ | ListenStream=/run/%I/%I.sock |
||
− | chdir = /srv/http/helloworld |
||
+ | SocketGroup=http |
||
− | module = helloworld |
||
+ | SocketMode=0660 |
||
− | plugins = python |
||
+ | [Install] |
||
− | 以下のような構文を使うことで uwsgi を別個に実行することも可能です: |
||
+ | WantedBy=sockets.target |
||
+ | </nowiki>}} |
||
+ | == トラブルシューティング == |
||
− | 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 |
||
+ | === Apache httpd === |
||
− | 上記のコマンドを root で実行するのは止めてください。 |
||
+ | ==== 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; |
||
− | } |
||
== 参照 == |
== 参照 == |
||
66行目: | 309行目: | ||
* [http://flask.pocoo.org/docs/deploying/uwsgi/ Flask uwsgi deploying] |
* [http://flask.pocoo.org/docs/deploying/uwsgi/ Flask uwsgi deploying] |
||
* [https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/uwsgi/ Django and uWSGI] |
* [https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/uwsgi/ Django and uWSGI] |
||
− | * [ |
+ | * [https://www.youtube.com/watch?v=tD6UCfPCVLA Flask with uwsgi and nginx video] |
* [http://uwsgi-docs.readthedocs.org/en/latest/Apache.html Apache and uwsgi] |
* [http://uwsgi-docs.readthedocs.org/en/latest/Apache.html Apache and uwsgi] |
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] を参照してください。