はじめての OpenResty :  Hello World

# はじめての OpenResty : Hello World

OpenResty は nginx に luajit と様々なライブラリをパッケージし、簡単に高速な Web アプリケーションサーバーを構築できるようにした web プラットフォームです。

nginx 単体でも config ファイルでの記述によって HTTP のリクエストを書き換えてプロキシするなど複雑な処理が可能ですが、さらにそれを推し進め高速な Lua スクリプティングを足すことで、高性能なアプリケーションサーバーとして使うことが出来るようになっています。

元 CloudFlare の [OpenResty](https://openresty.org) 開発者である、現 [OpenResty, Inc](https://openresty.com/en/) の [agentzh](https://github.com/agentzh) 氏中心に開発とメンテナンスが続けられているオープンソースのプロダクトです。

日本語での OpenResty 専門の書籍が出ていないこと、以前から日本語で書かれた記事がありますが多少情報が古くなっていること、例えばバイナリパッケージが整備され現在は以前よりさらにお手軽に扱えるようになっていることもあり、今回あらためて日本語でまとめてみました。

この記事をきっかけに OpenResty に興味を持っていただけると幸いです。

## CentOS7 を準備

[OpenResty Linux Packages](https://openresty.org/en/linux-packages.html)  のページにありますように、現在は主要 Linux 向けのバイナリパッケージが用意されています。

| Distribution | Version       |
---------------+----------------
| Ubuntu       | 14.04 - 18.04 |
| Debian       | 7 - 9         |
| CentOS       | 6 - 7         |
| RHEL         | 6 - 7         |
| Fedora       | 26 - 27       |
| Amazon Linux | 2018.03       |

主要 Debian 系と RedHat 系が対象になっています。OpenResty の実際の活用の局面ではベアメタルなオンプレミスのサーバーで動かしたり、Docker や Kubernetes といったコンテナ環境で稼働させることが一般的だと思いますが、今回の記事では素朴かつ汎用的、可搬的な環境にすることを狙って、一言でいうとカジュアルに、 Windows Home PC 上の VirtualBox で CentOS 7 をインストールしました。

CentOS の設定はデフォルトのままの一般的なものですが、OpenResty に関係しているところに以下のようになっています。

* VirtualBox の NIC は `NAT`
* 転送ポート設定

| 用途 | ホストIP | ホストポート | ゲストIP  | ゲストポート |
-------+----------+--------------+-----------+---------------
| ssh  | 0.0.0.0  | 20022        | 10.0.2.15 | 22           |
| HTTP | 0.0.0.0  | 20080        | 10.0.2.15 | 80           |
| DEV  | 0.0.0.0  | 28080        | 10.0.2.15 | 8080         |

* 開発ユーザーとして restymgr を追加。sudo が使えるように管理ユーザーとしました。名前はみなさんご自由に決めてください。
* selinux, firewallは停止

CentOS 7 の設定の詳細に踏み込むとそれだけで膨大な量になるため割愛させていただきました。

## OpenResty を yum でインストール

Windows の putty や Git for Windows の Bash などの ssh terminal でホストの Windows から CentOS にログインします。

```
ssh -p 20022 restymgr@127.0.0.1
```

最初に yum-config-manager を使うために `yum-utils` をインストールします。

```
sudo yum install yum-utils
```

次に openresty の yum リポジトリを追加したのち必要なパッケージをインストールします。

```
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install openresy openresty-resty openresty-opm openresy-doc
```

以上で必要なソフトはすべて入りますが、 `nginx` コマンドにパスが通っていない場合は自分の `.bashrc` に追加します

```
echo 'export PATH=/usr/local/openresty/nginx/sbin:$PATH' >> .bashrc
exec $SHELL -l
```

nginx にパスが通っている場合は systemd のサービスとして root で起動される openresty が追加されていると思います。今回は開発でカジュアルに使うことを想定していますのでシステムワイドのサービスは起動しないように停止しておきます。

```
sudo systemctl stop openresty
sudo systemctl disable opneresty
```

## OopenResty の Hello World

OpenResty 用のルートディレクトリを作成します。場所は `restymgr` ユーザーが使えるところならどこでもかまいません。名前は `restyroot` にしてみました。直下に `conf` と `logs` ディレクトリを作成します。

```
restyroot/
├── conf
└── logs
```

次に `conf/nginx.conf` ファイルを作成します。ポート 8080 でリッスンし、`/` のパスに対してのアクションとして `content_by_lua` ディレクティブで `ngx.say("<p>Hello World</p>")` によって `Hello World` を表示する HTTP レスポンスを記述します。

```
worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 8080;
        location / {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>Hello World</p>")
            ';
        }
    }
}
```

#### nginx 起動 

`nginx -p $(pwd) -c conf/nginx.conf` で nginx をデーモン化しながら起動できます。 `-p` は path オプションで nginx のプロセスのカレントディレクトを指定するものです。
現在のディレクトリ `$(pwd)` を指定します。 `-c` はコンフィグファイルの指定です。

ブラウザで `http://127.0.0.1:28080` にアクセスしてみます。

![hello.png](https://qiita-image-store.s3.amazonaws.com/0/101020/f0effe3c-dfe8-41eb-462e-0c34934fcdfc.png)

最初の Web アプリケーションが完成しました！

#### nginx 停止と再起動

nginx コマンドの `-s` シグナルオプションで `stop` や `reload` シグナルを送ることでデーモンの停止や再起動を行います。

* 停止：`nginx -p $(pwd) -s stop`
* 再起動 : `nginx -p $(pwd) -s reload`

## ルーティングして lua スクリプトのファイルを実行

前の例は `nginx.conf` ファイルに直接 `ngx.say()` を記述しましたが、conf ファイルにスクリプトを記述していくのは好ましくないため、まずは lua スクリプトのファイルと nginx のコンフィグを分離したいです。そのために `content_by_lua_file` ディレクティブが用意されているため使います。

最初に `lua` ディレクトリを追加します。

#### ディレクトリ構成

```
restyroot/
├── client_body_temp
├── conf
├── fastcgi_temp
├── logs
├── lua <=== 追加
├── proxy_temp
├── scgi_temp
└── uwsgi_temp
```

`restyroot` ディレクトリは nginx が使う各種 temp ファイルを作成するためのディレクトリが自動生成されていますのでこのようになっています。

`/` location に対しては前と同じ設定のまま、あたらしく `/myfile` location を定義し、実行する lua スクリプトのパスを `./lua/hello_world.lua` にします。

* `conf/nginx.conf`

```
worker_processes  1;
error_log logs/error.log;
events {
        worker_connections 1024;
}
http {
    server {
       listen 8080;
       location / {
           default_type text/html;
           content_by_lua '
               ngx.say("<p>Hello World</p>")
           ';
       }

       location /myfile {
           default_type text/html;
           content_by_lua_file ./lua/hello_world.lua; 
       }
    }
}
```

`hello_world.lua` スクリプトの方は同じ ngx.say を使いますが、行末に `;` が付いているところだけ注意してください

* `lua/hello_world.lua`

```
ngx.say("<p>Hello from myfile</p>");
```

`nginx -p $(pwd) -s reload` で再起動しブラウザからアクセスしてみましょう

![fromfile.png](https://qiita-image-store.s3.amazonaws.com/0/101020/15183020-1b0e-9eb0-5cac-672b4ecca6d0.png)


ルートによって処理を変え lua スクリプトファイルを実行し HTTP レスポンスとすることが出来ました！

lua のディレクトリ構成やライブラリの読み込みなど、本格的な Web アプリとするにはまだまだやることは一杯ありますが、OpenResty によって nginx という堅牢かつ高速な Web サーバーがアプリケーション・サーバーに変身できるところを体感頂けたらと思います！

最近、`今から学ぶべきではない廃れてしまった言語` としてあげられるなど不穏なニュースもある Lua ですが、OpenResty の手軽さは今でも有用だと思いますのでこれからも紹介していきたいと思います。