SSLとWebサーバとドメインが必要なrailsのローカル開発環境をdockerで構築する

## はじめに
![eyecatch_base_AdventCalendar2018_02.png](https://qiita-image-store.s3.amazonaws.com/0/165443/da66e764-d2fa-cae0-d90d-91bff1880f28.png)

これは [ドリコム Advent Calendar 2018](https://adventar.org/calendars/3421) の2日目です。
1日目は ogwmtnr さんによる、 [スマートコントラクトの Method ID 衝突はどのように回避されるのか](https://tech.drecom.co.jp/test-smart-contract-duplicated-method-ids/) です。
ドリコム新卒1年目のそのだです！！！
業務ではRailsでゲームのAPIサーバーを作っています。

## 困ったこと
ローカル開発時、APIのWebhookサーバー側がSSLのみだったり、IPアドレス直接指定の禁止だったり、
クライアント側が`If-Modified-Since`をHEADに含めたりすると、Webサーバの準備も必要になり開発環境の準備が大変な上、お気に入りのパソコンに変なソフトウェアをインストールしたくありませんよね！！！
そこでdockerでngrokとh2oを使ったローカル開発環境の例を紹介します。
サンプルではRailsを使いますが、Rubyやnodeをパソコンにインストールせずに実装します。

## 動作環境
- macOS Mojave version 10.14.1
- Docker Desktop Community Version 2.0.0.0-mac78(28905)
  - Compose: 1.23.1

## ngrokとは
https://ngrok.com/
ローカルPC上で稼働しているネットワーク（TCP）サービスを外部公開できるサービスです。
無料枠では起動するたびにサブドメインが変わりますが、会員登録無しで外部に公開することができます。
誰でもアクセスできますので、用法を守って適切に利用しましょう。
また、有料だと、セキュリティの強化や、サブドメイン固定などができます。

## プロジェクトのディレクトリを作成

```bash
$ mkdir test-local-server
$ cd test-local-server
```

## `docker-compose.yml`を作成します。

```docker-compose.yml
version: '3.4'
services:
  app:
    image: circleci/ruby:3-node-browsers
    command: >
      bash -c 'rm -rf tmp/pids/server.pid &&
      bin/rails s -b 0.0.0.0 ||
      bin/setup &&
      bin/rails s -b 0.0.0.0'
    volumes:
      - .:/app
      - bundle-volume:/usr/local/bundle
      - node-modules-volume:/home/circleci/node_modules
    ports:
      - 3000:3000

  h2o:
    image: lkwg82/h2o-http2-server:v2.2.3
    working_dir: /etc/h2o
    ports:
      - 443:443
    volumes:
      - ./docker/h2o:/etc/h2o:cached
    depends_on:
      - app

  ngrok:
    image: wernight/ngrok
    container_name: ngrok
    depends_on:
      - h2o
    ports:
      - 4040:4040
    environment:
      - NGROK_PORT=h2o:443

volumes:
  bundle-volume:
  node-modules-volume:
```
今回は、h2oは[lkwg82/h2o-http2-server](https://hub.docker.com/r/lkwg82/h2o-http2-server)を、ngrokは[wernight/ngrok](https://hub.docker.com/r/wernight/ngrok/)のコンテナイメージを使います。


## Gemfileの作成

```Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "rails"
```

## h2oのconfigを作成

docker/h2o/h2o.confを作成します

```h2o.conf
access-log: /dev/stdout
error-log: /dev/stderr

hosts:
  default:
    listen:
      port: 8080
    paths:
      /:
        proxy.reverse.url: http://app:3000/
```
`proxy.reverse.url:`にはdocker-compose.ymlにて指定したRailsのserviceとportを入力しています。
portの8080はh2oが公開するポート番号です

## rails applicationの作成
bundle installし、railsアプリケーションを作成します

```bash
docker-compose run app bundle
docker-compose run app bundle exec rails new . -f
```

## アプリケーションを立ち上げ

```bash
$ docker-compose up -d
```

## アプリケーションを開く
ngrokが開いているサーバーを確認します

```bash
$ curl -s $(docker port ngrok 4040)/api/tunnels
=> {"tunnels":[{"name":"command_line (http)","uri":"/api/tunnels/command_line+%28http%29","public_url":"http://905f7fd6.ngrok.io","proto":"http","config":{"addr":"rp:443","inspect":true},"metrics":{"conns":{"count":3,"gauge":0,"rate1":0.04060856509152551,"rate5":0.009592005588775135,"rate15":0.003287361283382928,"p50":7966700,"p90":136764200,"p95":136764200,"p99":136764200},"http":{"count":3,"rate1":0.04060856509152551,"rate5":0.009592005588775135,"rate15":0.003287361283382928,"p50":358400,"p90":1718900,"p95":1718900,"p99":1718900}}},{"name":"command_line","uri":"/api/tunnels/command_line","public_url":"https://905f7fd6.ngrok.io","proto":"https","config":{"addr":"rp:443","inspect":true},"metrics":{"conns":{"count":0,"gauge":0,"rate1":0,"rate5":0,"rate15":0,"p50":0,"p90":0,"p95":0,"p99":0},"http":{"count":0,"rate1":0,"rate5":0,"rate15":0,"p50":0,"p90":0,"p95":0,"p99":0}}}],"uri":"/api/tunnels"}
```
実行結果からだとわかりづらいですが、`https://905f7fd6.ngrok.io`が公開されたドメインです

もし[jq](https://github.com/stedolan/jq)をインストールしている場合は

```bash
$ curl -s $(docker port ngrok 4040)/api/tunnels | jq '.tunnels[] | select(.name == "command_line").public_url'
=> "https://905f7fd6.ngrok.io"
```
で見つけることができます！！

## ブラウザで確認する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/165443/303088d3-91ab-f450-ef53-8d47f6e9d0b8.png)

`https://905f7fd6.ngrok.io`にアクセスするとrailsが起動してるが確認できると思います。
また、
http://localhost:3000/ でRailsのアプリケーションサーバー
http://localhost:8080/ でh2oのwebサーバーで確認することもできます。