dockerでblueprintのコンテナを試す

## 概要
APIインターフェース仕様書を書くツールで便利なものがないか調べてみた。
ちょっと古いようだが、とりあえずblueprintを試してみる。

## ファイル構成
下記のファイル構成で構築してみました。

```:ファイル一覧
├ docs
│ └ example.md
├ public
│ └ .gitkeep
├ Dockerfile
├ docker-compose.yml
├ gulpfile.js
└ nginx.conf
```

## docker構成
コンテナとしては以下の２つを用意します。

- Blueprintコンテナ (Markdownをhtmlへ変換する)
- Nginxコンテナ (ブラウザにHTMLの仕様書を公開する)

## Dockerfile
Nginxは公式コンテナを使うので省略し、Blueprintコンテナを作成します。
※ Blueprintというよりgulpのコンテナかな・・・（まあ細かいことは気にしないw）

```dockerfile:Dockerfile
FROM node:9.11.2

RUN apt-get update

ARG USER="node"
ARG UID="1000"
ARG GID="1000"
ENV WORKSPACE="/blueprint/"

# set workspace.
RUN mkdir $WORKSPACE -p
WORKDIR $WORKSPACE

RUN npm config set unsafe-perm true

# install glup.
RUN npm init -y
RUN npm install gulp-cli -g
RUN npm install gulp -D
RUN npm install gulp-watch gulp-aglio gulp-plumber
RUN mkdir docs public
COPY gulpfile.js gulpfile.js

# support tools.
RUN apt-get install -y less vim

# set node user.
RUN groupmod -g $GID node && usermod -u $UID -g $GID $USER
RUN chown -R $UID:$GID $WORKSPACE
USER $USER

# command.
CMD gulp watch
```

## gulpfile.js
gulpを使ってMarkdownをHTMLに変換するため、作成します。
※ 色々なファイルのうち、拡張子が「***.md」のものだけ変換対象とします
※ mdファイルが追加されたり、変更されたら自動で検知してもらうためにwatchを設定する

```js:gulpfile.js
const gulp    = require('gulp');
const aglio   = require('gulp-aglio');
const watch   = require('gulp-watch');
const plumber = require('gulp-plumber');

const src  = 'docs/**/'
const dest = 'public'

gulp.task('publish', function () {
    gulp.src(`${src}*.md`)
        .pipe(plumber({
            errorHandler: function(error) {
                console.error(error.message);
                this.emit('end');
            }
        }))
        .pipe(aglio({ template: 'default' }))
        .pipe(gulp.dest(dest));
});

gulp.task('watch', function() {
    return watch(src, () => {
        return gulp.start(['publish']);
    });
});
```

## Nginx設定
公式のNginxを使いますが、DocumentRootを変更したいので、設定ファイルを作成します。

```nginx:nginx.conf
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /blueprint/public/;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
```

## docsフォルダ
Markdownのファイルを配置するフォルダです。
サンプルで、「example.md」を配置しておきます。

```md:docs/example.md
FORMAT: 1A
HOST: http://www.example.com/v1

# Auth
## login [/auth/login]
### POST
#### 概要
認証を行い、成功した場合アクセストークンなどを返す。


- Request (application/json)
    - Attribute
        - email: hoge@example.com (required) - メールアドレス
        - password: ******* (string, required) - パスワード


- Response 200 (application/json)
    - Attribute
        - auth_token: ********************* - auth token
```

## publicフォルダ
gulpにてMarkdownから生成されたHTMLを配置するフォルダです。

## docker-compose.yml
docker-composeでコンテナを起動するので、設定ファイルを作ります。

```yaml:docker-compose.yml
version: "2"

services:
  blueprint:
    #image: reflet/docker-blueprint
    build: .
    container_name: 'blueprint'
    volumes:
      - ./docs:/blueprint/docs
      - ./public:/blueprint/public

  nginx:
    image: nginx
    container_name: 'nginx'
    ports:
      - 8000:80
    volumes_from:
      - blueprint
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
```

## 起動
起動して見る。

```bash:ターミナル
$ docker-compose up -d
```

起動状況を確認してみる。

```bash:ターミナル
$ docker ps -a
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                  NAMES
0128ad99f9e7        nginx                     "nginx -g 'daemon ..."   4 seconds ago       Up 2 seconds        0.0.0.0:8000->80/tcp   nginx
06f0370cbd7a        reflet/docker-blueprint   "/bin/sh -c 'gulp ..."   5 seconds ago       Up 4 seconds                               blueprint
```

## テスト
「docs」フォルダ内に新しい仕様書を追加してみる。

```bash:ターミナル
$ cp docs/example.md docs/hoge.md
```

HTMLが生成されているか確認してみる。

```bash:ターミナル
$ ls -la public/
合計 56
drwxr-xr-x. 2 docker docker    59  6月  3 23:50 .
drwxrwxr-x. 5 docker docker   142  6月  3 23:25 ..
-rw-rw-r--. 1 docker docker     0  6月  3 23:25 .gitkeep
-rw-rw-r--. 1 docker docker 25138  6月  3 23:50 example.html
-rw-rw-r--. 1 docker docker 25138  6月  3 23:50 hoge.html
```

example.htmlとhoge.htmlが作られている。
そこで、ブラウザで確認してみる。

- http://192.168.33.10:8000/example.html
- http://192.168.33.10:8000/hoge.html

※「vagrant(192.168.33.10)」のIPアドレス部分は自分の環境に書き換える

![example.png](https://qiita-image-store.s3.amazonaws.com/0/142279/7644fa39-f2c6-88d4-a48b-0702c40d3d23.png)

閲覧できればOK。

以上

## 参考サイト
- [【API Blueprintの使い方】Web APIの仕様書を書く・読む・実行](https://dev.classmethod.jp/server-side/api-document-with-api-blueprint/)
- [DockerとAPI BlueprintでAPI仕様書とモックを同時に作成](https://qiita.com/TakashiOshikawa/items/5e06e8c15dd08d55b00f)
- [Blueprintを使ってAPIドキュメントを整備する](https://qiita.com/xsota/items/806a33b72c0224f016e2)
- [Glup - Automate and enhance your workflow](https://gulpjs.com/)
- [DockerコンテナでGulpを動かす](https://qiita.com/acro5piano/items/94d10be1c58be5113407)
- [gulpでSASSを自動コンパイルする](https://qiita.com/M_amourr/items/09c8bb4e2b2981cafe7a)
- [絶対つまずかないGulp入門(2018年版)](https://ics.media/entry/3290)
- [npm から gulp インストールまでの手順](https://qiita.com/miiitaka/items/32836ec7a00e88600de2)
- [初めてでもできるgulpの導入ととりあえず使ってみるまで](https://blog.mismithportfolio.com/web/20150822gulp-intro)