公開日:2023/1/8 0:00:00

AlmaLinux 8.7

AlmaLinux 8.7 セットアップメモ

Section 5.3 Webサーバー(nginx)構築編 nginx unit と python

About

python等を使うのに、アプリケーションサーバーが必要になるので、nginx unit(https://unit.nginx.org/)をセットアップします。公式サイトに手順もあるのでそれに従ってセットアップします。

環境は、Section 5.1を行った直後の状態からとなります。

リポジトリを追加する

CentOSの後継みたいに思うかもしれませんが、AlmaLinuxの位置付け的にはRHEL系ですし、公式際の手順にも書いてあるのでRHELの手順を見つつ追加します。

vimなどで編集してもいいのですが、rootでコマンドを使って作成してしまいましょう。

[root@localhost ~]# cat << 'EOS' > /etc/yum.repos.d/unit.repo
[unit]
name=unit repo
baseurl=https://packages.nginx.org/unit/rhel/$releasever/$basearch/
gpgcheck=0
enabled=1
EOS
[root@localhost ~]#

repo ファイルができたら、dnfコマンドで検索してみます。出てこなければ設定が間違っているという事で。

[root@localhost ~]# dnf search nginx unit
============================================ 概要 & 名前 一致: nginx, unit =============================================
unit.x86_64 : NGINX Unit
unit-devel.x86_64 : NGINX Unit (development files)
unit-go.x86_64 : Go module for NGINX Unit
unit-go.noarch : Go module for NGINX Unit
unit-jsc-common.noarch : Java shared packages for NGINX Unit
unit-jsc11.x86_64 : Java 11 module for NGINX Unit
unit-jsc8.x86_64 : Java 8 module for NGINX Unit
unit-perl.x86_64 : Perl module for NGINX Unit
unit-php.x86_64 : PHP module for NGINX Unit
unit-python27.x86_64 : Python 2.7 module for NGINX Unit
unit-python36.x86_64 : Python 3.6 module for NGINX Unit
unit-python38.x86_64 : Python 3.8 module for NGINX Unit
unit-python39.x86_64 : Python 3.9 module for NGINX Unit
[root@localhost ~]#

インストール

検索に出てきたら、nginx unit 本体とモジュールをインストールします。unit-phpもありますが、php-fpmの方がパフォーマンスが良いという話もあるので、特段の理由が無ければ入れる必要は無いかなと。今回は、python3 関連をインストールします。
python3 も同時にインストールしてくれるので個別にインストールせずに進めます。

[root@localhost ~]# dnf install unit unit-python39
依存関係が解決しました。
========================================================================================================================
 パッケージ                        Arch           バージョン                                    リポジトリー      サイズ
========================================================================================================================
インストール:
 unit                              x86_64         1.29.0-1.el8.ngx                              unit              669 k
 unit-python39                     x86_64         1.29.0-1.el8.ngx                              unit               94 k
依存関係のインストール:
 python39-libs                     x86_64         3.9.13-2.module_el8.7.0+3351+e02cdf9b         appstream         8.2 M
 python39-pip-wheel                noarch         20.2.4-7.module_el8.6.0+2780+a40f65e1         appstream         1.1 M
 python39-setuptools-wheel         noarch         50.3.2-4.module_el8.6.0+2780+a40f65e1         appstream         496 k
弱い依存関係のインストール:
 python39                          x86_64         3.9.13-2.module_el8.7.0+3351+e02cdf9b         appstream          32 k
 python39-pip                      noarch         20.2.4-7.module_el8.6.0+2780+a40f65e1         appstream         1.9 M
 python39-setuptools               noarch         50.3.2-4.module_el8.6.0+2780+a40f65e1         appstream         870 k
モジュールストリームの有効化中:
 python39                                         3.9

トランザクションの概要
========================================================================================================================
インストール  8 パッケージ

ダウンロードサイズの合計: 13 M
インストール後のサイズ: 48 M
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
(中略)

完了しました!
[root@localhost ~]#

これで、systemd 用の service ファイルや、アプリケーションサーバーを動作させるユーザー unit が追加されます。

動作確認のための準備

いろいろと動作させるのがアプリケーションサーバーなわけで、何もないのに動作させることはできない……という事でいろいろと作成します。

Pythonを使う環境に仕上げたいので、最終的にはDjangoを使うようにしたいと思いますが、それは別の章で。

まずはアプリケーションを設置するための場所の作成とスクリプトを配置します。スクリプトはインストールしたパッケージ内にあるサンプルをコピーして使いましょう。

[root@localhost ~]# mkdir -p /var/www/apps/python
[root@localhost ~]# cp -r /usr/share/doc/unit-python39/examples/* /var/www/apps/python/

nginx unit はいろいろなアプリケーションサーバーになりえるので、/var/www/apps に言語毎に配置できるように分けてみました。この辺りは、サーバー管理者の運営方針などにもよるでしょう。

サービスの起動

まずはサービスの有効化。

[root@localhost ~]# systemctl enable unit

そのあとは、起動します。

[root@localhost ~]# systemctl start unit

nginx unit のアプリケーション登録設定

サービスを起動したままだと何も起きません。設定はファイル編集ではなく、設定が書かれたjsonファイルを流し込むことで起動します。アプリケーションサーバーを再起動せずに、アプリケーションを立ち上げたり閉じたりできるという点でメリットはありますが、どういう設定だっけ?となりそうなのが少し面倒なところですね。

という事で、設定もコピーしたサンプル内にあるので、それを編集して使います。

[root@localhost ~]# vi /var/www/apps/python/unit.config
*** /usr/share/doc/unit-python39/examples/unit.config   YYYY-mm-dd hh:ii:ss.000000000 +0900
--- /var/www/apps/python/unit.config                    YYYY-mm-dd hh:ii:ss.000000000 +0900
***************
*** 3,9 ****
                        "example_python": {
                                "type": "python 3.9",
                                "processes": 2,
!                               "path": "/usr/share/doc/unit-python39/examples/python-app",
                                "module": "wsgi"
                        }
                },
--- 3,9 ----
                        "example_python": {
                                "type": "python 3.9",
                                "processes": 2,
!                               "path": "/var/www/apps/python/python-app",
                                "module": "wsgi"
                        }
                },

アプリケーションがあるフォルダの場所を変えています。

設定ファイルの全貌は下記の通り。

{
        "applications": {
                "example_python": {
                        "type": "python 3.9",
                        "processes": 2,
                        "path": "/var/www/apps/python/python-app",
                        "module": "wsgi"
                }
        },

        "listeners": {
                "*:8400": {
                        "pass": "applications/example_python"
                }
        }
}

listeners の設定があり、8400とあります。8400番ポートを使うという意味なり、pass はその上のapplicationブロックからたどったパスになります。

では、設定を流し込みます。curl を使ってunix domain socket経由でHTTPアクセスを行ってサービスに流し込むという……慣れていてもなにやっているんだ?となるようなやり方ですね……

PUTコマンドは設定を指定したjsonの内容で全部入れ替えという意味で、localhost/config/ は設定を受け付けるためのREST APIのようなものと考えればOKです。

[root@localhost ~]# curl -X PUT --data-binary @/var/www/apps/python/unit.config \
 --unix-socket /var/run/unit/control.sock http://localhost/config
{
        "success": "Reconfiguration done."
}
[root@localhost ~]# 

結果もjson形式で返ってきます。errorの場合は**“error”**となるので、その場合は設定を見直してください。

なお、設定されている内容を見るにはGETするだけです。

[root@localhost ~]# curl --unix-socket /var/run/unit/control.sock localhost/config/
{
        "applications": {
                "example_python": {
                        "type": "python 3.9",
                        "processes": 2,
                        "path": "/var/www/apps/python/python-app",
                        "module": "wsgi"
                }
        },

        "listeners": {
                "*:8400": {
                        "pass": "applications/example_python"
                }
        }
}
[root@localhost ~]# 

では、動作しているか確認しましょう。

[root@localhost ~]# curl http://localhost:8400/
2023-01-08 00:00:00 AM

Python: 3.9.13 (main, Nov 16 2022, 10:51:39)
[GCC 8.5.0 20210514 (Red Hat 8.5.0-15)]

ENV Variables:

LANG    ja_JP.UTF-8
PATH    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
INVOCATION_ID   7ffc701e895642e68f88d52ab3e7a23c
JOURNAL_STREAM  9:63389
RUNTIME_DIRECTORY       /run/unit
UNITD_OPTIONS   --log /var/log/unit/unit.log --pid /var/run/unit/unit.pid
[root@localhost ~]# 

サンプルが悪すぎて、コマンドの結果なのかこういうHTMLのページなのかわかりにくいですが、こういうものです。

わかりにくい場合は、wsgi.pyを修正して、unitのサービスを再起動して確認してみてください。

nginxとの連携設定について

これまで設定してきた内容であるなら8400で待ち受けしているので、nginxからそこにアクセスするように設定すれば良いという事になります。

という事で、設定を作成しましょう。

[root@localhost ~]# cat << 'EOS' > /etc/nginx/default.d/unit-python-testapp.conf
location = /testapp/ {
        proxy_pass http://127.0.0.1:8400;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
EOS

あとは、サービスを再起動しましょう。

[root@localhost ~]# systemctl restart unit
[root@localhost ~]# systemctl restart nginx

動作確認

ブラウザで、/testapp/ にアクセスすれば何かしら表示されます。そうなれば設定完了です。