AlmaLinux 8

AlmaLinux 8.5 セットアップメモ

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
[root@localhost ~]#

インストール

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

[root@localhost ~]# dnf install unit unit-python36
依存関係が解決しました。
================================================================================
 パッケージ           Arch          バージョン                Repo        サイズ
================================================================================
インストール:
 unit                 x86_64        1.26.1-1.el8.ngx          unit        354 k
 unit-python36        x86_64        1.26.1-1.el8.ngx          unit         93 k

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

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

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

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

Pythonのインストール

python3 を入れ忘れていたのでAppStreamのモジュールからインストールします。

[root@localhost ~]# dnf module list python
エラー: 表示する一致モジュールはありません

間違えました。

[root@localhost ~]# dnf module list python*
AlmaLinux 8 - AppStream
Name       Stream   Profiles           Summary
python27   2.7 [d]  common [d]         Python programming language, version 2.7
python36   3.6 [d]  build, common [d]  Python programming language, version 3.6
python38   3.8 [d]  build, common [d]  Python programming language, version 3.8
python39   3.9 [d]  build, common [d]  Python programming language, version 3.9

ヒント: [d]efault, [e]nabled, [x]disabled, [i]nstalled
[root@localhost ~]# dnf module list python39
AlmaLinux 8 - AppStream
Name       Stream   Profiles           Summary
python39   3.9 [d]  build, common [d]  Python programming language, version 3.9

ヒント: [d]efault, [e]nabled, [x]disabled, [i]nstalled

php とかと同じようにリストかしてくれれば……と思いつつ、インストールします。

[root@localhost ~]# dnf module enable python39
依存関係が解決しました。
================================================================================
 パッケージ        アーキテクチャー バージョン          リポジトリー      サイズ
================================================================================
モジュールストリームの有効化中:
 python39                           3.9

トランザクションの概要
================================================================================

これでよろしいですか? [y/N]: y
完了しました!
[root@localhost ~]# dnf install python39
依存関係が解決しました。
================================================================================
 パッケージ        Arch   バージョン                            Repo      サイズ
================================================================================
インストール:
 python39          x86_64 3.9.6-2.module_el8.5.0+2571+54860423  appstream  31 k
依存関係のインストール:
 python39-libs     x86_64 3.9.6-2.module_el8.5.0+2571+54860423  appstream 8.2 M
 python39-pip-wheel
                   noarch 20.2.4-6.module_el8.5.0+2571+54860423 appstream 1.3 M
 python39-setuptools-wheel
                   noarch 50.3.2-4.module_el8.5.0+2571+54860423 appstream 496 k
弱い依存関係のインストール:
 python39-pip      noarch 20.2.4-6.module_el8.5.0+2571+54860423 appstream 2.0 M
 python39-setuptools
                   noarch 50.3.2-4.module_el8.5.0+2571+54860423 appstream 870 k

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

ダウンロードサイズの合計: 13 M
インストール後のサイズ: 45 M
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
(中略)
完了しました!
[root@localhost ~]#

動作確認のための準備

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

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

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

[root@localhost ~]# mkdir -p /var/www/apps/python/testapp
[root@localhost ~]# cp /usr/share/doc/unit-python36/examples/python-app/wsgi.py /var/www/apps/python/testapp/wsgi.py

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

サービスの起動

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

[root@localhost ~]# systemctl enable unit

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

[root@localhost ~]# systemctl start unit

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

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

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

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

フォルダの場所を変えています。設定ファイル内を見ると、listeners の設定があり、8400とあります。8400番ポートを使うという意味なので、記憶しておきましょう。

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

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

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

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

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

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

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

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

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

Python: 3.6.8 (default, Nov 17 2021, 16:10:06)
[GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]

ENV Variables:

LANG    ja_JP.UTF-8
PATH    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
INVOCATION_ID   5dd6650f94904bc595a228c38ae71f17
JOURNAL_STREAM  9:151132
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/ にアクセスすれば何かしら表示されます。そうなれば設定完了です。