docker expose プラグイン便利そうなので試す

Docker 19.03 から Dockerコマンドをプラグインで拡張できるようになったとのこと。

https://github.com/docker/docker-ce/releases/tag/v19.03.0

> Basic framework for writing and running CLI plugins. docker/cli#1564 docker/cli#1898

lukaszlach 氏の「expose」が便利そうなので使ってみることにした。

* https://github.com/lukaszlach
* https://github.com/lukaszlach/clip/tree/master/clips/expose

# expose plugin とは
簡単にいうと手元で動かしているコンテナ（HTTPサービス）を外部公開するため、パブリックなHTTPエンドポイントを払い出す。**ngrokクラウドサービス**を介してプロキシするような仕組みをとっている。ngrokを導入する方法はネット上にすでにあるし、それでも簡単なんだけど、最近はきっとコンテナ使って開発する人も多いだろうからそん時に便利に使えるものとしてこのプラグインが活用できる。

* https://ngrok.com/

![image.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75458/02421155-7759-a894-51ef-94ebe371eb75.png)


既存のオンプレ、Dockerホストで試してみる。

* Docker の 19.03へのアップデート
* Clip のインストールとセットアップ
* expose plugin のインストール

# Update Docker
19.03へアップデート割愛
#Clipインストール＆セットアップ

ここでは、docker コマンドが実行できる一般ユーザにインストール＆セットアップする。

```shell-session
$ mkdir -p ~/.docker/cli-plugins

$ curl -sf https://raw.githubusercontent.com/lukaszlach/clip/master/docker-clip -o ~/.docker/cli-plugins/docker-clip

$ chmod +x ~/.docker/cli-plugins/docker-clip

$ ls -ltr ~/.docker/cli-plugins

$ docker info |grep clip
  clip: Docker Client Plugins Manager (Łukasz Lach, v19.06.0)

$ docker clip --help

Usage: docker clip COMMAND

Commands:
  add       Install a new plugin by an image name
  build     Build a new plugin
  ls        List installed plugins
  push      Push local plugin to a Docker registry
  rm        Remove an installed plugin
  search    Search plugins from the remote catalog
  update    Reinstall a plugin to its latest version
```

# expose plugin を使う

## インストール

```shell-session
docker clip add lukaszlach/clips:expose
Installing client plugin from lukaszlach/clips:expose
expose: Pulling from lukaszlach/clips
dfe3f328527c: Pull complete                                                                                                         Digest: sha256:ab4eb409ef77cdbec1769d5b2b3e6af8741cb9988d05456394b5f25558b7c83e
Status: Downloaded newer image for lukaszlach/clips:expose
docker.io/lukaszlach/clips:expose
tar: manifest.json: 恐らく古いタイムスタンプ 1970-01-01 09:00:00
tar: repositories: 恐らく古いタイムスタンプ 1970-01-01 09:00:00
Successfully installed lukaszlach/clips:expose client plugin
New client command available: 'docker expose'
```

## テスト


ここでは適当にnginxのWebサービスを立ち上げる、この時、ポート公開をせずに動かす。


```shell-session
$ docker run --name nginx -d nginx
```

```shell-session
$ docker expose nginx 80
Error: No such network: clip-expose-network
Creating network
Error: No such container: clip-expose
Starting proxy for nginx:80
Unable to find image 'lukaszlach/ngrok:latest' locally
latest: Pulling from lukaszlach/ngrok
8e402f1a9c57: Pulling fs layer
fe0b84b4b7fe: Pulling fs layer
438fed729a8a: Pulling fs layer
7f5e7bf8b582: Pulling fs layer
b625a16fdacc: Pulling fs layer
7f5e7bf8b582: Waiting
b625a16fdacc: Waiting
fe0b84b4b7fe: Verifying Checksum
fe0b84b4b7fe: Download complete
8e402f1a9c57: Download complete
8e402f1a9c57: Pull complete
fe0b84b4b7fe: Pull complete
7f5e7bf8b582: Verifying Checksum
7f5e7bf8b582: Download complete
b625a16fdacc: Verifying Checksum
b625a16fdacc: Download complete
438fed729a8a: Verifying Checksum
438fed729a8a: Download complete
438fed729a8a: Pull complete
7f5e7bf8b582: Pull complete
b625a16fdacc: Pull complete
Digest: sha256:4dfe86dc145edf6b4b2b8d92fabf43f931a7c9192d76bcd53657abb34e5b4183
Status: Downloaded newer image for lukaszlach/ngrok:latest
Proxy is running, fetching public address details
http://5c7b4d08.ngrok.io
https://5c7b4d08.ngrok.io
Successfully exposed nginx:80

$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
640c1230bd65        lukaszlach/ngrok    "ngrok http --log /d…"   About a minute ago   Up About a minute   4040/tcp            clip-expose
b4c03ce4e87c        nginx               "nginx -g 'daemon of…"   2 minutes ago        Up About a minute   80/tcp              nginx
```

* clip-expose-network なければ作ってくれる
* clip-expose コンテナが作られる
* clip-expose には ngrok client が入っていてこいつがプロキシする
* lukaszlach/ngrok がpullされてexpose用コンテナが起動する
上記例でいうと「 http://5c7b4d08.ngrok.io or https://5c7b4d08.ngrok.io 」にアクセスするとnginxのトップページが表示される。

もう、いらないよ、ということであれば下記のコマンドで停止できる。
コマンドというかngrokとの仲介している「clip-expose」コンテナを停止するというだけ。

```shell-session
$ docker stop clip-expose

$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
b4c03ce4e87c        nginx               "nginx -g 'daemon of…"   4 minutes ago       Up 4 minutes        80/tcp              nginx
```

# 実用

自分で提供している、HTTPサービスにも同じようにやってみた。
＝＞結論、まんま公開可能

```shell-session
$ docker pull <private image>
$ docker run -d --name venn <private image>
$ docker expose venn 80
```

当たり前だが、HTTPサービスを提供しているコンテナは80をLISTENしていないとだめ。


# 感想

* 手元のサービスがすぐに公開でき、停止もできるので相当に簡単
* https がすぐに払い出せるのもよい（これまでhttpsで独自に作りこんだ苦労はなんだったんだ・・・まぁそれは常時提供する場合にはしなきゃなんないんだけど、今のところの使い方だとこれで十分）
* 最大コネクション数に制限があるため、一時的なサイト利用には重宝するが、いわゆるサービスのプロダクション利用にはちょっと不向きか