IntelliJのDocker pluginを使ってみます


みなさまこんにちは。 
[JetBrains Advent Calendar 2017](https://qiita.com/advent-calendar/2017/jetbrains) の 12/19分での投稿となります。

（実は、[Docker Advent Calendar](https://qiita.com/advent-calendar/2017/docker)に参加表明していたのですが、諸事情で投稿を逃してしまいました。参加希望だった方には、本当に申し訳ございません…）

あとからの投稿で、高度な内容ではないのですが、この機会に最近使っている[IntelliJのDocker plugin](https://plugins.jetbrains.com/plugin/7724-docker-integration)についてご紹介いたします。
画像多めですので、「こんな感じで使えるんだ」という雰囲気を掴んでいただけたら幸いです。
また、Docker for Mac及び、AzureのACS（コンテナサービス）に連携した例を取り上げています。


## はじめに

当方の環境は以下の通りです。

- MacOS / Docker for Macを通常利用
- コマンドラインからの操作以外に、GUIのKitematicも良く利用

また、Dockerを使っている理由ですが、これも以下の通りです。

- 個人でRedmineのプラグインを書いており、その動作チェックにもDockerを使っている
 - RedmineはサポートするDBが色々あるので、SQLite3だけでなく、必要に応じてMySQLやPostgreSQL, SQL Serverでも動作確認がいる
 - DBの切り替えやDBの稼働が面倒なので、[docker-composeを使い出した](https://qiita.com/akiko-pusu/items/c2d26672923b9d616536) 

## Docker化に関して

現職の業務でも、ローカル開発環境ではDocker化が進んでいます。

一部の静的コンテンツが中心のサーバについても、ECSを使っているような状況です。Docker化に関しては、職場の優秀なエンジニアさんたちがぐいぐい引っ張っていってくれています。
私はあとから追いかける形ではありますが、主にコードレビューを通して動作確認をすることが多いので、幸いにも学習の機会をいただけている感じです。
（ありがたいことです！）

## IntelliJのDocker plugin

さて、本題です。
私は通常エディタとしてはIntelliJ IDEAを使っています。([とても好きなので2016年も書きました！](https://qiita.com/akiko-pusu/items/1caa46bb1fd2f0c60916))

作業中のソースコードの中にDockerfile, docker-compose.yml が含まれているのですが、こちらについては編集はIntelliJで行うものの、コンテナの起動はターミナルから / 起動確認は[Kitematic](https://qiita.com/akiko-pusu/items/d07751a6bf0ce6df44ce)で、といった方法を取っていました。

ただ、ファイル自体はIntelliJからもDocker用のファイルと認識されている...。
何気なく右クリックすると、どうやらこのDockerfileもIntelliJから「ビルド」できる模様...。


![build-setting-for-dockerfile.png](https://qiita-image-store.s3.amazonaws.com/0/27976/728abe34-185b-cd18-f67a-0030446eacc8.png "build-setting-for-dockerfile.png")

ビルドをするDockerのサーバは、Preference -> Build, Execution, Deployment から "Docker" の項目を選びます。
こちらで、まずはDocker for Macを選択します。
（注：Docker for Macのサービスを起動させておくこと）

![preference-for-docker.png](https://qiita-image-store.s3.amazonaws.com/0/27976/1f477417-ba4d-d69e-7423-7f424a11922f.png "preference-for-docker.png")

これで基本の設定は完了です。
設定が適用されると、"Connection successful" の文字列が表示されます。


## Docker for Macに接続！

設定が終わったので、IntelliJのTool WindowからDockerを選びます。
画面左下側に、Docker用のエリアが表示されます。
上記の通り、Dockerのサーバを登録していれば、ここに登録したサーバの名前が表示されますので、「緑色の三角(Connect)」ボタンを押すと、Dockerのサーバ側と接続が開始されます。

イメージやコンテナがすでに作成されていれば、docker images, docker ps -a の結果と同じ内容が、グラフィカルに表示されます。

![intellij-and-kitematic.png](https://qiita-image-store.s3.amazonaws.com/0/27976/d7834c9a-7fdf-a3da-df1d-a61047138205.png "intellij-and-kitematic.png")

Dockerのコンテナを表示するときは、Kitematicを使っていたのですが、わざわざKitematicを起動しなくても、ほぼ同じ情報がIntelliJから参照できることがわかります。


#### コンテナの起動 / 停止 / 削除

IntelliJが一旦Dockerのサーバに接続すると、コンテナを選んで右クリックから起動や停止、削除、さらにイメージの削除も実行できるようになります。

うっかりして、ものすごい数のコンテナやイメージが溜まっていた...という場合も、お掃除しやすいですね！

#### コンテナの状態もチェックできます！

私が「このプラグインが便利！」と思った点は、以下の通りです。

- コンテナとイメージの双方がGUIで確認できる
- コンテナのログや環境変数、ボリューム、ポートといったものも確認できる
- 環境変数やポート、ボリュームの調整も可能
- Dockerfile, docker-compose.yml どちらも「ビルド」という形でイメージ作成やコンテナ起動ができる

特に、Kitematicと同様に起動したコンテナのポートを追加で解放したいなという時に、この画面から設定が可能です。
Dockerで用意したDBに対して、Mac側からアクセスして中身を確認するような場合に使っています。


![operate-docker-container.png](https://qiita-image-store.s3.amazonaws.com/0/27976/fea23e0a-fb7b-fa0f-7523-fa2e542896d9.png "operate-docker-container.png")

さらに、コンテナへのdocker run, docker execも右クリックで実行可能です。

![docker-exec-bash.png](https://qiita-image-store.s3.amazonaws.com/0/27976/4d66c159-a2b1-5180-f4e8-1dca5a532327.png "docker-exec-bash.png")

思ったとおりにコンテナが動いてくれないな...という場合に、exec bash でコンテナの中に入ったりするのですが、これもGUIから利用が可能です。


## Azure Container Serviceにも接続！

さて、せっかくなのでMacのLocalのDockerだけでなく、他のサービスにも接続してみたい。
Azureには全く明るくないのですが、今回は[Azure Container Service](https://azure.microsoft.com/ja-jp/services/container-service/)を使ってみることにしました。

### まずは Azure Container Serviceを作成

Azure Container Service(ACS)では、Kubernetes、DC/OS、または Docker Swarm が利用できますが、ひとまずSwarmでの作成をしました。（Kubernetesは専用のCLIを入れる必要があったので見送っています。勉強せねば！）


![create-swarm-cluster-on-azure.png](https://qiita-image-store.s3.amazonaws.com/0/27976/c93d7e15-92dc-0a55-78d4-06e7fe737ed2.png "create-swarm-cluster-on-azure.png")


あまり細かいことは考えず、クラスターのタイプはDocker swarmを指定。
接続用のアカウントとsshの公開鍵を登録して作成すると、下記のように色々とリソースが追加されます。

![azure-all-resources.png](https://qiita-image-store.s3.amazonaws.com/0/27976/b5bcded5-a3c7-c0a7-e510-415fde496e22.png "azure-all-resources.png")


### Azure Tooklit for IntelliJ でも確認

さて、本題はDockerの操作なのですが、Azureには [Azure Tooklit for IntelliJ](https://docs.microsoft.com/ja-jp/java/azure/intellij/azure-toolkit-for-intellij) というAzureアプリケーションを管理できるツールが提供されています。

せっかくなので、この状態でどのように見えるのか、試してみました。
今回作成したACS用に、仮想マシンが1つ立ち上がっているのがわかります。
このswarm-masterという仮想マシンがDockerの管理用サーバとして動き、ここに対しAPI経由でコマンドを投げると、swarm-agentという実際にコンテナをホストするエージェントノード上でコンテナが稼働します。

![azure-toolkit.png](https://qiita-image-store.s3.amazonaws.com/0/27976/23096bef-1a06-bcc9-284d-81932aa24dab.png "azure-toolkit.png")


- 参考：[Azure Toolkit for IntelliJ](https://docs.microsoft.com/ja-jp/java/azure/intellij/azure-toolkit-for-intellij)

### IntelliJからAzure上のDocker管理用サーバに接続

swarm-masterには直接は接続できないので、sshでトンネリングして、swarm-master上の管理用のAPIに接続するという流れになります。
今回は、下記のページに従って、Azure側の仮想マシンのDocker管理用ポート: 2375 をlocalhost:2375 に転送しておきます。

- [Kubernetes、DC/OS、または Docker Swarm クラスターへのリモート接続を確立する](https://docs.microsoft.com/ja-jp/azure/container-service/dcos-swarm/container-service-connect)

```
# sshトンネリングの例
# ACSで作成時に指定したアカウント＆公開鍵を使ってsshトンネリングを張ります
#
$ ssh -fNL 2375:localhost:2375 -p 2200 username@xxxxxmgmt.eastasia.cloudapp.azure.com
```

ポートを localhost:2375 に転送する前提で、IntelliJ側にDocker管理用サーバとしてAzure上のサーバを登録します。

![connect-acs.png](https://qiita-image-store.s3.amazonaws.com/0/27976/0cb4c048-f94f-bf7e-9daa-82a3b4107c4a.png "connect-acs.png")

トンネリングが有効な状態で設定を適用すると、やはり "Connection successful" の文字列が表示されます。

### Azure上のDockerに向けてdocker build

いったん接続してしまえば、あとは処理は同じになります。
ローカルで実施したdocke-compose.ymlのビルドの設定を調整し、Azure側に向けると、デプロイ、ビルドの処理が走ります。

![build-on-azure.png](https://qiita-image-store.s3.amazonaws.com/0/27976/1ec39ff5-f785-b34f-09b9-0bbd6deb6e01.png "build-on-azure.png")

### Azure上のRedmineのコンテナにアクセス

上記の処理で、Redmineのコンテナが起動しました。
ただ、このままではRedmineの画面にはアクセスできないので、Azure側のロードバランサを調整してみます。
このあたりはIntelliJからでは操作できないので、Azureの管理画面から実施します。

Docker swarmを使っているので、swarm-agentという名前で実際にコンテナを動かすノードが稼働しています。
こちらにもロードバランサ、接続用のパブリックIPが設定されますが、デフォルトはport: 80, 443, 8080のみなので、一時的に3000番を追加。

この状態で、指定されたパブリックIP:3000にアクセスしてみます。

![access-redmine-on-acs.png](https://qiita-image-store.s3.amazonaws.com/0/27976/dc7b148d-15e8-3ab9-de96-a950a6224177.png "access-redmine-on-acs.png")

ずっと向こうの世界ではありますが、DockerのAPIを経由して、Azure上のコンテナのログが取得できています。

同様に、exec bashでコンテナの中に入ることができます。

細かい点は課金が心配なのでこの程度で留めていますが、とにかくAPIに接続できればローカルでもクラウドでも変わらないのが分かりました。

## まとめ

以上、IntelliJのDockerプラグインを使った例を紹介させていただきました。

Dockerコマンドの利用は、実際は単純なdocker-compose up やdocker runではなく、コマンドラインでいろいろオプションを指定するため、もしかしたらターミナル利用のほうが良いかもしれません。
それでも、コンテナの稼働状況やログは、IntelliJを通して1箇所でチェックできるのは、なかなか便利だな、と思っています。

だいぶ勉強不足で言葉が曖昧だったり、間違いもあるかと思いますが、もしまだ使っていないようでしたら、お試しいただけたら幸いです。