作って学ぶリバースプロキシ③Lua Scriptのセットアップ

## これは何?

前回記事では，OpenRestyとnginx.confの構文についてまとめました。

https://qiita.com/sigma_devsecops/items/79d243ac5354c4991d88

今回は，OpenRestyで使うLua Scriptについてまとめます。

---

## Lua Scriptとは

[公式のintroduction](https://www.lua.org/about.html)に書いてあることを軽く書いておきます。

- スクリプト言語である。
    - 手続き型プログラミング
    - 関数型
    - オブジェクト指向
    - データ駆動形プログラミング
- Luaはポルトガル後で月を意味する
- 組み込みやゲーム等で使用されている。
- スクリプト言語にしては速いらしい

  :::note info
  [kostya](https://github.com/kostya/benchmarks)にベンチマークががあるが，Python以上PHP，Ruby未満といった感じらしい。
  :::
- Cコンパイラがあればビルドできる

### 文法について

一旦これを斜め読みしておけば良さそうです。(丸投げ感)

- [しぶしぶ覚えるLua Script](https://qiita.com/aike@github/items/2023bbeb21094af6795e)
- [日本語のよさそうなpdf](https://densan-labs.net/_downloads/lua.pdf)
- [逆引きlua-nginx-module](https://gist.github.com/ykst/52205d4d4968298137ea0050c4569170)

これらに書いていない部分で個人的に重要だなと思ったのは，ifで`nil`及び，`false`以外はtrueと判定されることです。
> [Lua 5.4 Reference Manual 3.3.4 – Control Structures](https://www.lua.org/manual/5.4/manual.html)
> All values different from nil and false test true. In particular, the number 0 and the empty string also test true.

そのため，以下のように値が空でないかで判定ができ，これが多用されている印象があります。

```
if err then
  print("error");
end
```

ついでに，OpenRestyから使うということで，nginx関連のライブラリから扱える変数について補足しておきます。

1. `ngx.var`はnginx.conf上の変数を操作できる。

    ```lua
    ngx.var.pass = "https://example.com";
    ```

    ```nginx.conf
                set $pass ""; # luaで書き換える変数
    ```
2. `ngx.ctx`はリクエストスコープ内でのデータの共有に使う --> 複数ファイルで値を自動的に共有できるが一時的にしか使わない変数で使う。
---

### ライブラリの管理方法

- [LuaRocks](https://github.com/luarocks/luarocks)を使ってライブラリを管理できる。
- LuaRocksとLuaをダウンロードするための[hererocks](https://github.com/mpeterv/hererocks)がある。

Dockerfileを置いておきます。

```dockerfile
FROM openresty/openresty:1.21.4.1-0-bullseye-fat AS devcontainer

# NOTE: nginxの-pオプションの代わりにWORKDIRで指定
WORKDIR /usr/local/openresty
USER root

RUN apt-get update
# libreadline-def: For gcc build Lua
# libssl-dev, m4: For luarocks install http
RUN <<EOF bash -ex
apt install -y --no-install-recommends \
    gcc \
    unzip \
    make \
    libreadline-dev \
    libssl-dev \
    m4
EOF

# install Python3 to install HereRocks
RUN <<EOF bash -ex
apt install -y --no-install-recommends \
    python3 \
    python3-pip
    pip install hererocks
    rm -rf /var/lib/lists/
EOF

# install LuaRocks
RUN hererocks lua54 -l 5.4 -r latest

# build LuaRocks from rockspec
# TODO: ライブラリをrockspeckとかで管理したい
RUN <<EOF bash -ex
PATH=$PATH":/usr/local/openresty/lua54/bin"
luarocks install lua-resty-redis
luarocks install lua-resty-template
luarocks install lua-resty-string
luarocks install http
luarocks install lua-resty-balancer
EOF

COPY ./conf/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
EXPOSE 80
# Not using daemon mode.
CMD ["openresty", "-g", "daemon off;"]

```

### OpenRestyからの実行方法

基本的にnginx.conf経由の実行になる。
`location`で指定されたディレクトリに対して`access_by_lua_file`で実行したいLua Scriptのパスを配置する。

```nginx.conf
        location / {
            root   /usr/local/openresty/reverse_proxy/html;
            default_type 'text/html';
            access_by_lua_file /usr/local/openresty/reverse_proxy/src/main.lua;
        }

```

---

## その他興味深いドキュメントメモ

- [メルカリ ハイパーフォマンスngx_lua](https://engineering.mercari.com/blog/entry/2015-11-25-170049/)

---

## 次回

実際にOpenResty経由でサイトアクセスしてみます。

https://qiita.com/sigma_devsecops/items/02bd67936704a7307430