この記事では、NGINX Unitのインストール・設定手順をまとめています。
本記事の内容
- NGINX Unitをインストールする前に
- NGINX Unitのインストール環境
- NGINX Unitのインストール
- NGINX Unitの設定
- 残された課題
それでは、上記に沿ってNGINX Unitをインストールしていきます。
NGINX Unitをインストールする前に
PythonでWebアプリを動かすには、次の記事が参考になります。
上記記事の内容を簡単に言うと、Webサーバーとアプリケーションサーバーの話です。
「Webサーバーは、ApacheではなくNginxを使っていきましょう」
「アプリケーションサーバーは、何個か候補があります」
この記事では、NGINX Unitをアプリケーションサーバーとして選んでいます。
そして、インストールするという流れです。
NGINX Unitのインストール環境
インストールに関係のあるモノは以下。
- Ubuntu 18.04
- Nginx 1.14.0
- NGINX Unit 1.20.0
Linuxでのインストール作業は、OSと各バージョンには注意が必要です。
同じディストリビューションであれば、それほど問題になりません。
しかし、CentOSとUbuntuでは、かなり異なります。
そのため、ディストリビューションには特に注意してください。
Ubuntu 18.04
OSのバージョン確認です。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
利用可能な最新(安定版)バージョンは、 Ubuntu 20.04です。
でも、利用しているVPSでは、Ubuntu 18.04までしか選択できませんでした。
まあ、月額349円という格安なので全く文句はありません。
格安VPSの契約から利用までについては、次の記事で解説しています。
Nginx 1.14.0
Nginxのバージョン確認です。
$ nginx -V nginx version: nginx/1.14.0 (Ubuntu)
Nginxのインストールに関しては、次の記事で解説しています。
NGINX Unit 1.20.0
2020年の10月8日に公開されたばかりです。
Nginx同様、もちろんオープンソースとなります。
対応言語は以下。
- Assembly
- Go
- JavaScript(Node.js)
- Java
- Perl
- PHP
- Python
- Ruby
対応と言っても、すべてが組み込んであるわけではありません。
利用するためには、何かしらのインストールや設定が必要になります。
なお、Pythonに関しては以下のように表記されています。
では、NGINX Unitをインストールしていきます。
NGINX Unitのインストール
公式サイトのインストール手順
https://unit.nginx.org/installation/
上記の参考にして、インストールを行ないます。
インストール
いつもの感じでsudoで。
$ sudo curl -sL https://nginx.org/keys/nginx_signing.key | apt-key add -
でも、これは失敗します。
E: This command can only be used by root. (23) Failed writing body
仕方がないので、rootになります。
$ sudo su
では、気を取り直して。
# curl -sL https://nginx.org/keys/nginx_signing.key | apt-key add - OK
次に、NGINX Unitインストールに必要な情報をリポジトリ追加します。
ただし、/etc/apt/sources.listに追記する形ではありません。
公式では、/etc/apt/sources.list.dの下に「unit.list」を作成します。
そのファイルの内容は以下。
deb https://packages.nginx.org/unit/ubuntu/ bionic unit deb-src https://packages.nginx.org/unit/ubuntu/ bionic unit
結果的には、次のようになればOKです。
# cat /etc/apt/sources.list.d/unit.list deb https://packages.nginx.org/unit/ubuntu/ bionic unit deb-src https://packages.nginx.org/unit/ubuntu/ bionic unit
いざ、インストールコマンドですね。
パッケージを更新してからのインストールです。
# apt update # apt install unit # apt install unit-dev unit-go unit-jsc8 unit-jsc11 unit-perl unit-php unit-python2.7 unit-python3.6 unit-python3.7 unit-ruby
利用予定の言語のパッケージだけを選択するようにと記載されています。
今回であれば、Pythonです。
よって、「unit-python2.7 unit-python3.6 unit-python3.7」を選択すればOK。
個人的には、他の言語も機会があれば動かしてみたいと考えています。
そのため、他言語のパッケージもインストールしています。
その辺りの判断はご自由に。
ただし、本番環境では一つだけ「unit-python3.6」 とバージョンまで絞り込んでインストールします。
本番環境ではできる限りで、無駄なモノはインストールしたくありません。
確認
パッケージからインストールした場合は、自動で起動しているようです。
そのように公式サイトには、記載されています。
起動状況を確認します。
$ systemctl status unit ● unit.service - NGINX Unit Loaded: loaded (/lib/systemd/system/unit.service; disabled; vendor preset: enabled) Active: active (running) since Sun 2020-10-18 11:31:56 JST; 15min ago Main PID: 15070 (unitd) Tasks: 3 (limit: 1152) CGroup: /system.slice/unit.service ├─15070 unit: main v1.20.0 [/usr/sbin/unitd --log /var/log/unit.log --pid /var/run/unit.pid] ├─15072 unit: controller └─15073 unit: router 10月 18 11:31:56 meet systemd[1]: Starting NGINX Unit... 10月 18 11:31:56 meet unitd[15069]: 2020/10/18 11:31:56 [info] 15069#15069 unit started 10月 18 11:31:56 meet systemd[1]: unit.service: Can't open PID file /var/run/unit.pid (yet?) after start: No such file or directory 10月 18 11:31:56 meet systemd[1]: Started NGINX Unit.
「active (running)」です。
以上、NGINX Unitのインストールは完了です。
次は、設定ですね。
Nginx上でPythonアプリが起動するように設定を行います。
NGINX Unitの設定
インストール同様、公式サイトを参考にします。
https://unit.nginx.org/howto/samples/
Pythonアプリ(プログラム)の作成
まずは、アプリ(プログラム)の作成からです。
以下の内容のファイルを作成します。
def application(environ, start_response): start_response("200 OK", [("Content-Type", "text/plain")]) return (b"Hello, Python on Unit!")
公式では、/www/wsgi.pyファイルを作成するように記載があります。
でも、「/」の直下にディレクトリを増やすのは嫌ですね。。。
なので、/var/wwwの下に専用のディレクトリを作成します。
$ sudo mkdir /var/www/python
ここにwsgi.pyを作成します。
$ cat /var/www/python/wsgi.py def application(environ, start_response): start_response("200 OK", [("Content-Type", "text/plain")]) return (b"Hello, Python on Unit!")
Pythonアプリの登録
NGINX UnitにPythonアプリを登録します。
その際の設定方法は、特殊です。
curlによりjsonをNGINX Unitに送り付けて登録するのです。
以下は公式サイトに記載されている方法の一つです。
# curl -X PUT --data-binary '{ \ "listeners": { \ "*:8080": { \ "pass": "applications/python_app"\ } \ }, \ "applications": { \ "python_app": { \ "type": "python", \ "path": "/www/", \ "module": "wsgi" \ } \ } \ }' --unix-socket /path/to/control.unit.sock http://localhost/config/
コマンドラインでjsonを送るのは、ちょっと違和感あります。
そのため、ファイルにして送ります。
まず、/var/www/pythonにconf.jsonを作成します。
# cat conf.json { "listeners": { "*:8080": { "pass": "applications/python_app" } }, "applications": { "python_app": { "type": "python", "path": "/var/www/python/", "module": "wsgi" } } }
pathやmoduleは各自の環境に変更する必要があります。
今回は、/var/www/pythonの下にwsgi.pyファイルを作成しました。
よって、pathは/var/www/pythonとなります。
また、moduleは、wsgi.pyよる「.py」を除去したモノとなります。
NGINX Unitにconf.jsonの内容を反映させます。
以下のコマンドとなります。
# cd /var/www/python/ # curl -X PUT --data-binary @conf.json --unix-socket /var/run/control.unit.sock http://localhost/config
成功した場合、失敗した場合の結果を載せておきます。
成功した場合
{ "success": "Reconfiguration done." }
失敗した場合
私は、2種類のエラーを確認しました。
パターン別に表示します。
jsonファイルに問題がある場合
{ "error": "Invalid JSON.", "detail": "A double quote (\") is expected here. There must be a valid JSON object member starts with a name, which is a string enclosed in double quotes.", "location": { "offset": 14, "line": 1, "column": 15 } }
jsonviewerなどで適切なjsonファイルになるように修正してください。
モジュール(json上ではtypeで指定)が存在しない場合
{ "error": "Invalid configuration.", "detail": "The module to run \"python\" is not found among the available application modules." }
エラー内容は、python用のモジュールが見つからないと言っています。
ubuntuの場合は、「/usr/lib/unit/modules/」を確認します。
$ ls /usr/lib/unit/modules/ java11.unit.so java8.unit.so perl.unit.so php.unit.so python2.7.unit.so python3.6.unit.so python3.7.unit.so ruby.unit.so
存在しているのに、見つからないことがありえます。
その場合は、NGINX Unitを再起動します。
$ sudo systemctl restart unit
これで、モジュールが見つからない問題は解決します。
Pythonアプリの動作確認
8080ポートにcurlでアクセスします。
$ curl localhost:8080 Hello, Python on Unit!
上記のように「Hello, Python on Unit!」と表示されれば、OKです。
Pythonアプリの動作確認は完了です。
残された課題
念のため、ブラウザでも確認しておきましょう。
そのためには、ポートの開放が必要です。
$ sudo ufw allow 8080
conf.json上で8080を登録しましたよね。
そのため、ポート8080を開放しています。
この状態で次のURLにアクセス。
http://サーバIP:8080
ブラウザで確認できてこそ、Webアプリと言えますね。
めでたし、めでたし。
という訳にはいかないのです。
上記表示を行うプログラムを再度確認しましょう。
def application(environ, start_response): start_response("200 OK", [("Content-Type", "text/plain")]) return (b"Hello, Python on Unit!")
これをどうやって、htmlタグと組み合わせるのでしょうか?
PHPなら、次のようにPHPの処理を簡単に埋め込むことができました。
<div><?php echo "テスト"; ?></div>
Pythonでは?
この問いに答えるために、便利なモノが用意されています。
それはフレームワークと呼ばれています。
Django、Flaskとか聞いたことはありませんか?
これらのフレームワークを利用すると、上記の問い(課題)を解決できます。
ただし、本記事ではここまでとします。
また、別の記事でフレームワークについて解説します。