---
title: "あなたの最初のOpenRestyプログラム: Hello World - API7.ai"
description: "この投稿に従って、OpenRestyでHello Worldを実装しましょう！"
url: "https://api7.ai/ja/learning-center/openresty/hello-world-in-openresty"
---

# あなたの最初のOpenRestyプログラム: Hello World

API7.ai

September 9, 2022

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

新しい開発言語を学び始める際、チュートリアルでは簡単な `hello world` の例が提供されます。そこで、まずインストールをスキップして、OpenResty でこの例をどのように書くかを見てみましょう。

```
$ resty -e "ngx.say('hello world')"
hello world
```

これはおそらく最もシンプルな hello world コードでしょう。Python と似ていますね。

```
$ python -c 'print("hello world")'
hello world
```

この背後には、OpenResty の哲学が表れています。コードは簡潔であるべきで、「入門から挫折まで」という考えを捨てられるようにするべきです。この記事では、hello world の例に焦点を当てます。

[OpenResty と NGINX の違い](https://api7.ai/learning-center/openresty/openresty-vs-nginx/)の記事で述べたように、OpenResty は `NGINX` をベースにしています。そのため、ここで NGINX の影が見えないのはなぜかと疑問に思うかもしれません。心配ありません。1行のコードを追加して、resty の背後で何が動いているのかを見てみましょう。

```
$ resty -e "ngx.say('hello world'); ngx.sleep(10)" &
```

[ngx.sleep](https://github.com/openresty/lua-nginx-module#ngxsleep) メソッドを追加したので、文字列 `hello world` を出力した後にプログラムが終了しなくなります。これにより、次のように確認できます。

```
$ ps -ef | grep nginx
root     15944  6380  0 13:59 pts/6    00:00:00 grep --color=auto nginx
```

ついに NGINX プロセスが現れました！どうやら `resty` コマンドは本質的に NGINX サービスを起動しているようです。では、`resty` とは何でしょうか？

あなたのマシンには OpenResty がインストールされていないかもしれません。そこで、最初にスキップしたインストール手順に戻り、OpenResty をインストールしてから続けましょう。

## インストール

他のオープンソースソフトウェアと同様に、OpenResty はさまざまな方法でインストールできます。例えば、OS のパッケージマネージャーを使う、ソースコードからコンパイルする、Docker イメージを使うなどです。しかし、まずは `yum`、`apt-get`、`brew` などのパッケージマネージャーを使って OpenResty をインストールすることをお勧めします。この記事では、macOS を例にします。

```
$ brew tap openresty/brewbrew install openresty
```

他の OS でも同様です。まず、OpenResty のリポジトリ URL をパッケージマネージャーに追加し、その後パッケージマネージャーを使って OpenResty をインストールします。詳細な手順は、[公式ドキュメント](https://openresty.org/en/linux-packages.html)を参照してください。

しかし、この一見シンプルなインストールの背後には、2つの問題があります。

1. なぜソースコードからインストールすることを勧めないのか？
2. なぜ OS の公式リポジトリから直接インストールできず、別のリポジトリを設定する必要があるのか？

これらの質問についてまず考えてみてください。

ここで一つ追加したいことがあります。このコースでは、表面的なものの背後にある多くの「なぜ」を取り上げます。新しいことを学びながら考えることを望んでいます。結果が正しいかどうかは重要ではありません。残念ながら、技術分野でも独立した思考は希少です。各人の技術分野や深さの違いにより、どのコースでも教師は個人的な意見や知識の誤りを持ちます。学習プロセスでいくつかの「なぜ」を問い、それを理解することで、徐々に自分の技術体系を形成できます。

多くのエンジニアはソースコードからビルドすることを楽しんでいます。私も何年も前はそうでした。しかし、オープンソースプロジェクトを使う際、私は常に手動で `configure` や `make` を行い、いくつかのコンパイルパラメータを変更したいと思っていました。これがこのマシンの環境に最適で、性能を最大限に引き出す最良の方法だと感じていました。

しかし、現実はそうではありません。毎回ソースコードをコンパイルする際に奇妙な環境問題に遭遇し、つまずきながらインストールするしかありませんでした。今では、私たちの本来の目的はオープンソースプロジェクトを使ってビジネスニーズを解決することであり、環境との戦いに時間を浪費すべきではないと理解しています。パッケージマネージャーやコンテナ技術は、まさにこれらの問題を解決するために存在します。

本題に戻りましょう。OpenResty をソースコードからインストールする場合、手順が煩雑で、`PCRE` や `OpenSSL` などの外部依存関係を解決する必要があります。さらに、対応するバージョンの OpenSSL に手動でパッチを当てる必要があります。そうしないと、`SSL セッション` を扱う際に機能が不足します。例えば、`yield` を引き起こす [ngx.sleep](https://github.com/openresty/lua-nginx-module#ngxsleep) のような Lua API が使えなくなります。この部分について詳しく知りたい場合は、[公式ドキュメント](https://github.com/openresty/lua-nginx-module#ssl_session_fetch_by_lua_block)を参照してください。

OpenResty はこれらのパッチを [OpenSSL パッケージスクリプト](https://github.com/openresty/openresty-packaging/blob/master/rpm/SPECS/openresty-openssl.spec)で自ら管理しています。OpenResty が `OpenSSL` のバージョンをアップグレードする際には、対応するパッチを再生成し、完全な回帰テストを行う必要があります。

```
Source0: https://www.openssl.org/source/openssl-%{version}.tar.gz

Patch0: https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0d-sess_set_get_cb_yield.patch
Patch1: https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.1.0j-parallel_build_fix.patch
```

同時に、CentOS での OpenResty の [パッケージスクリプト](https://github.com/openresty/openresty-packaging/blob/master/rpm/SPECS/openresty.spec)を見て、他の隠れたポイントがあるかどうか確認できます。

```
BuildRequires: perl-File-Temp
BuildRequires: gcc, make, perl, systemtap-sdt-devel
BuildRequires: openresty-zlib-devel >= 1.2.11-3
BuildRequires: openresty-openssl-devel >= 1.1.0h-1
BuildRequires: openresty-pcre-devel >= 8.42-1
Requires: openresty-zlib >= 1.2.11-3
Requires: openresty-openssl >= 1.1.0h-1
Requires: openresty-pcre >= 8.42-1
```

ここでわかるように、OpenResty は独自のバージョンの `OpenSSL` と `zlib`、`PCRE` を管理しています。ただし、後者の2つはコンパイルパラメータを調整しており、パッチは保持していません。

これらの要素を考慮すると、詳細を知らない限り、ソースコードから OpenResty をコンパイルすることはお勧めしません。

ソースインストールが勧められない理由は明らかでしょう。最初の質問に答える際に、2番目の質問にも答えました。なぜ OS の公式パッケージリポジトリから直接インストールできず、別のリポジトリを設定する必要があるのか？

これは、公式リポジトリがサードパーティが管理する `OpenSSL`、`PCRE`、`zlib` パッケージを受け入れたくないためです。他のユーザーがどれを選ぶべきか混乱を招くのを防ぐためです。一方、OpenResty は正常に動作するために特定のバージョンの `OpenSSL` と `PCRE` ライブラリを必要とし、システムのデフォルトバージョンは比較的古いものです。

## OpenResty CLI

OpenResty をインストールすると、OpenResty CLI `resty` がデフォルトでインストールされます。これは `Perl` スクリプトであり、前述の通り、OpenResty のエコシステムツールはすべて `Perl` で書かれています。これは OpenResty の作者の技術的嗜好によるものです。

```
$ which resty
/usr/local/bin/resty

$ head -n 1 /usr/local/bin/resty
#!/usr/bin/env perl
```

resty CLI は非常に強力で、`resty -h` を使うか、[公式ドキュメント](https://github.com/openresty/resty-cli)を読むことで完全な機能リストを確認できます。次に、2つの興味深い機能を紹介します。

```
$ resty --shdict='dogs 1m' -e 'local dict = ngx.shared.dogs dict:set("Tom", 56) print(dict:get("Tom"))'

56
```

上記の例は、`Lua` コードを含む `Nginx` 設定を示しています。これは、共有メモリ辞書の設定とクエリを実現しています。`dogs 1m` は、`dogs` という名前の共有メモリスペースを `1m` のサイズで宣言する `Nginx` 設定です。この共有メモリは、Lua コード内で辞書として使用されます。

また、`--http-include` と `--main-include` パラメータは `NGINX` 設定ファイルを設定するために使用されるため、上記の例を次のように書き換えることができます。

```
$ resty --http-conf 'lua_shared_dict dogs 1m;' -e 'local dict = ngx.shared.dogs dict:set("Tom", 56) print(dict:get("Tom"))'
```

OpenResty の世界での標準的なデバッグツール、例えば `gdb`、`valgrind`、`sysetmtap`、`Mozilla rr` も、resty と一緒に使用できます。これらは通常の開発とテストを容易にするため、`resty` の異なるコマンドに対応しています。内部実装は非常にシンプルで、コマンドライン呼び出しの追加レイヤーに過ぎません。`valgrind` を例に挙げましょう。

```
$ resty --valgrind -e "ngx.say('hello world'); "

ERROR: failed to run command "valgrind /usr/local/openresty/nginx/sbin/nginx -p /tmp/resty_rJeOWaYGIY/ -c conf/nginx.conf": No such file or directory
```

これらは OpenResty の世界だけでなく、サーバーサイドの一般的なツールでもあります。そのため、段階的に学んでいきましょう。

## より正式な「hello world」

最初に書いた OpenResty プログラムは、`resty` コマンドを使って `master` プロセスなしで、特定のポートをリッスンせずに実行しました。次に、別の `hello world` プログラムを実装してみましょう。

これを完了するには、少なくとも3つのステップが必要です。

1. 作業ディレクトリを作成する。
2. `NGINX` 設定ファイルを修正し、`Lua` コードを埋め込む。
3. `OpenResty` サービスを起動する。

まず、作業ディレクトリを作成しましょう。

```
$ mkdir openresty-sample
$ cd openresty-sample
$ mkdir logs/ conf/
```

以下は、OpenResty の `content_by_lua` ディレクティブを含む最小限の `nginx.conf` です。これにより、[ngx.say](https://github.com/openresty/lua-nginx-module#ngxsay) メソッドが埋め込まれます。

```
events {
    worker_connections 1024;
}

http {
    server {
        listen 8080;
        location / {
            content_by_lua '
                ngx.say("hello, world")
            ';
        }
    }
}
```

まず、openresty が `PATH` 環境変数に追加されていることを確認してください。その後、OpenResty サービスを起動します。

```
$ openresty -p `pwd` -c conf/nginx.conf
```

エラーが発生しなければ、OpenResty サービスは正常に起動しています。cURL コマンドを使ってアクセスし、返される結果を確認できます。

```
$ curl -i 127.0.0.1:8080

HTTP/1.1 200 OK
Server: openresty/1.13.6.2
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
hello, world
```

おめでとうございます！OpenResty での正式な `Hello World` が完成しました！

## まとめ

今日学んだことを振り返りましょう。まず、OpenResty のインストールと CLI を「hello, world」の簡単なコードから始め、最後に OpenResty プロセスを起動し、実際のバックエンドプログラムを実行しました。

その中で、resty は今後頻繁に使用するコマンドラインツールです。そのため、このコースのデモコードは、バックグラウンドで OpenResty サービスを起動するのではなく、resty を使って実行されます。

さらに重要なのは、OpenResty の背後には多くの文化的・技術的な詳細が隠れており、海に浮かぶ氷山のようです。このコースを通じて、表面的な API だけでなく、より包括的な OpenResty を紹介できればと思います。

Share article link

Share

Related Posts

[![OpenResty FAQ | OpenRestyの実践的な使い方](https://static.api7.ai/uploads/2023/02/12/jbv9M0zi_Hello%20World%20in%20OpenResty%20%283%29.png)](https://api7.ai/learning-center/openresty/faq-5)

## [OpenResty FAQ | OpenRestyの実践的な使い方](https://api7.ai/learning-center/openresty/faq-5)

[![第3部：OpenRestyを使用してマイクロサービスAPIゲートウェイを構築する方法](https://static.api7.ai/uploads/2023/02/07/3XJXY9Jy_45.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

## [第3部：OpenRestyを使用してマイクロサービスAPIゲートウェイを構築する方法](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [インストール](#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
- [OpenResty CLI](#openresty-cli)
- [より正式な「hello world」](#%E3%82%88%E3%82%8A%E6%AD%A3%E5%BC%8F%E3%81%AAhello-world)
- [まとめ](#%E3%81%BE%E3%81%A8%E3%82%81)
