HTTPリクエストの内容を出力するお手軽なWebサーバを作ってDocker対応させてみた

# はじめに

HTTPリクエストの内容を表示するだけ、という単機能WebサーバをExpressで作ってみました。
告知を兼ねて記事としてシェアします。

## TL;DR 

作ったコードは一式GitHubに上がっています。

* GitHub: [kulikala/http-ephemeral-server](https://github.com/kulikala/http-ephemeral-server)
* npm: [http-ephemeral-server](https://www.npmjs.com/package/http-ephemeral-server)

## 用途

こんな時に使うと便利だと思います。

* APIでリクエストする時に、正しくHTTPヘッダが設定できているか確認したい
* POSTした値が正しく解釈されるか確認したい
* 複数のコンテナアプリケーションを作って、互いに通信する構成を作る時、とりあえずのイメージを使いたい
* ALBでECSに振り分ける構成をCloudFormationで作る時、アプリがまだできていないけど、とりあえずECRのリポジトリがほしい時

## 背景

用途の4つ目を叶えたかったのが、今回一番の目的でした。

### PHPからインスパイア

PHPには`<? phpinfo(); ?>`という便利メソッドがあって、Apache + PHPで環境作った後、この`phpinfo();`でサーバの構成情報やHTTPリクエスト情報を確認していました。

### Dockerに載せやすい形

Node.jsには[`http-server`](https://www.npmjs.com/package/http-server)という便利サーバがあって、簡単にインストール＆静的ファイルをサーブできます。
このツールと同じくらい簡単にインストールできて、HTTPリクエスト情報が目視しやすくって、Dockerに載せやすい形を模索していました。

## 便利ポイント

### 環境変数でポートを指定できる

環境変数でサーバがリスニングするポートを変えることができます。
Dockerはポートマッピングが重要だからこそ、イメージを作成した後にポートを変更できるのは便利です。

# 使い方

3つの使い方ができます。

1. コマンドラインツールとしてインストール
2. Dockerイメージとしてビルド
3. `npm`パッケージとしてライブラリ利用

## コマンドラインツールとしてインストール

`npm`でグローバルインストールすると、どのワーキングディレクトリからでも一発起動します。

### インストール

```shell
$ npm install http-ephemeral-server -g
```

### 起動

```shell
$ http-ephemeral-server
```

デフォルトポートは`3000`になっているので、 http://localhost:3000 にアクセスすると、こんな感じの画面が表示されます。

![Screenshot_2018-07-06 Screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/84173/de9dfb03-ae9f-5d52-f4d0-918cc1939584.png)

### ポート番号を変更する

ポート番号は、環境変数`PORT`で指定します。

```shell
$ PORT=8000 http-ephemeral-server
```

今度は、 http://localhost:8000 で表示されます。

### 短いコマンド

`http-ephemeral-server`は長すぎてタイポしそうです。
短いバージョンを用意しています。

```shell
$ hes
```

### URLは自由

http://localhost:3000/hoge/bar/foo?The:quick:brown:fox:jumps:over:the:lazy:dog
というURLにアクセスすると、画面は同じで`url`の項目が変化します。

![Screenshot_2018-07-06 Screenshot(1).png](https://qiita-image-store.s3.amazonaws.com/0/84173/d1e215fd-57e2-4c71-ef20-3046992b3a11.png)

## Dockerイメージとしてビルド

`Dockerfile`をリポジトリ内に用意しています。
GitHubからcloneしてローカルでビルドします。

### ローカルにclone

```bash
$ git clone https://github.com/kulikala/http-ephemeral-server.git
$ cd http-ephemeral-server
```

### `docker`コマンドを使う

`docker image build`でビルドします。
`-t http-ephemeral-server:latest`でビルドしたイメージにタグを付けています。

```bash
$ docker image build -t http-ephemeral-server:latest .
```

`docker container run`で起動します。

```bash
$ docker container run -d -p 3000:80 http-ephemeral-server:latest
```

デフォルトでは、コンテナ内では`EXPOSE 80`するように`Dockerfile`で記述しています。
ブラウザからアクセスできるようにするには、`-p 3000:80`などホストポートをコンテナポートにマッピングしてあげます。
`-d`オプションを指定しないで起動すると、Nodeのプロセスにアタッチします。

### ポートを変更してビルド

`--build-arg`オプションで`PORT`変数に値を渡してあげます。

```shell
$ docker image build -t http-ephemeral-server:latest --build-arg PORT=3000 .
```

### 起動時にポート番号を変更

`PORT`環境変数を渡して起動すると、実行時のポート番号を変更します。
実行時に`8000`番ポートに変更し、 http://localhost:8000 にマッピングするには次のようにします。

```shell
$ docker container run -d -p 8000:8000 -e PORT=8000 http-ephemeral-server:latest
```

### `docker-compose`コマンドを使う

便利ですよね、`docker-compose`。
`docker`起動時のオプションなどはよく忘れてしまうので、起動するコンテナが1つの場合でも、`docker-compose.yml`書いておくことにしています。

```shell
$ docker-compose build
$ docker-compose start
```

リポジトリ内の`docker-compose.yml`ではホストの`8000`番ポートにマッピングしているので、ブラウザから http://localhost:8000 にアクセスすると応答するようになります。

## `npm`パッケージとしてライブラリ利用

`http-ephemeral-server`は、[Express application generator](http://expressjs.com/en/starter/generator.html) で生成したExpressアプリケーションになっています。

### `npm`でインストール

```shell
$ npm install http-ephemeral-server --save
```

### `require()`する

`require('http-ephemeral-server')`すると[ExpressのApplicationインスタンス](https://expressjs.com/en/4x/api.html#app)が取得できるので、

```javascript
const app = require('http-ephemeral-server')

app.listen(3000)
```

みたいな形で利用できます。

ぜひ、使ってみてください！