Docker for WindowsでIISウェブサイトの開発環境を作る手順（シリーズその２）

*~更新~*
6月15日に投稿しましたが、今日一番大切なステップを書いてなかったことに気づきました。すみません。「ホストのフォルダーをコンテナにマウントする」で、`docker run`を実行する際に`-v C:\dev\mysite:C:\mysite`と指定してやる部分です。

#目的
Docker for Windowsを使ってごく初歩的なIISのウェブサイトを実行して、ホスト側のファイルをコンテナ上のウェブサイトに反映できるまでの手順を解説します。

#IISレポジトリをダウンロードする
DockerハブにあるMicrosoftの公式IISレジストリを`Docker pull`します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/a40c8a6e-d0a3-e75a-c74d-3dc0bb9aa3ad.png)

私の場合はすでにホストマシーンにイメージがありましたが、そうでない場合はダウングレードとエクストラクトにしばらく時間がかかるかもしれません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/51422d46-34f7-d8a7-cd28-e9503531b163.png)

#コンテナをスタートする
以下のコマンドでIISイメージをコンテナとして実行します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/a7e84c96-ff6c-4521-dcc1-0e15662e02bb.png)

- `-entrypoint`オプションでPowerShellを指定します。これでコンテナが実行開始したら最初にPowerShellのコンソールがスタートします。
- `-it`オプションを指定するとホストのCMDコマンドラインと、コンテナで実行するPowerShellがインターアクティブに接続されます。
- `-p`オプションでホストのポート8080とコンテナのコンピュータのポート80（これは言うまでもなくHTTPサービスのデフォルトポートですね）をつなぎます。（今回はコンテナのIPに直接アクセスするのでホストのは適当でいいです）


コンテナがスタートしたらPowerShellのコマンドラインがコンソールに表示されます。このPowerShellはコンテナで実行してるんですよね～、すごい！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/2fdebff7-7876-d39e-4248-0d3c05d231e8.png)

例えば`dir`コマンドでドライブの内容を表示してみましょう。やたらスッキリしているのが分かりますね。コンテナのドライブなので最小限のものしかありません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/3bb7c040-6cab-3c46-4426-5ef2acdb734f.png)

ちなみに、コンピュータの名前を調べてみます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/11fc03db-a7c9-6f9f-2cd2-14dda3e902c6.png)

`ED9E6FA67BF9`という名前になってました。
面白いことに、このコンピュータ名は実はコンテナのIDそのまんまだったりします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/54d817f4-d512-455b-1905-06c1d9f2b6d9.png)

#ブラウザでIISを確認する
せっかくIISのコンテナを実行したので、IIS（Webサービス）にアクセスできることを検証しましょう。
まずはコンテナのコンピュータのIPアドレスを調べます。IPアドレスは`docker inspect`コマンドで出力されるJSONデータの中にあります。とりあえずJSONデータを全部ローカルのファイルにコピーします。`docker inspect`コマンドにはコンテナIDを指定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/b129596c-27a1-da74-f35c-0fdbb1a448fd.png)

IPアドレスを見つけました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/167d4d17-e46d-ec49-e406-7dd533de4e28.png)

このIPアドレス、ネットワーク上の他のIPアドレスと同じように`ping`したりできます。こういう雰囲気が「コンテナ技術」と「仮想マシン技術」との混乱の原因のようです。「仮想化」されているのではなく「隔離」されているだけなんです。

さてブラウザで確認してみましょう。ちなみにポートはデフォルトの80なので指定する必要はないですね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/ef14c531-9184-1d74-a2f5-5993d28b4692.png)

おなじみのIISのデフォルト画面が表示されました。
このページはコンテナでは`C:\inetpub\wwwroot`にある`iisstart.htm`に対応してます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/a6ecfc78-1e20-40a5-beb4-5a116b6adfd2.png)

実験として簡単な別のテキストファイルを置いてみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/d085339a-494e-f323-f915-198458895cf2.png)

`test.txt`というファイルが出来ました。
このファイルもブラウザで確認してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/d8a1e537-e48c-5e90-245b-ba83f9da7034.png)

ちゃんとアクセスできました。こんな感じでコンテナ内のファイルシステムを自由に変えらることが確認できました。

では、いったんコンテナを止めます。PowerShellを`entrypoint`として指定したので、PowerShellを終了させることがすなわちコンテナを終了させる、ということになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/e07c253c-e3df-eb99-564d-d563cc5b07ff.png)

無事、ホストのCDMプロンプトに帰ってきました～。

#Dockerで作業用のボリュームを設定する
Dockerコンテナを利用してなんらかの作業（たとえば開発中のウェブアプリケーションのテスト）を行う場合、簡単にアプリケーションの内容を変更できる環境が必要になります。
そのためにはDockerのボリューム機能を利用します。

Dockerで簡単にボリュームを設定するやり方のうち、二つを紹介します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/f3ae63f6-031b-82cc-45d8-51214dd273b4.png)


#[方法その１] ホスト側のディレクトリをマウントする
ホストにあるフォルダーをコンテナのドライブの一部として接続します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/2ba5140e-7305-eef3-79cf-6b3651e2aefd.png)

ホスト側にはごく簡単なウェブサイトを用意します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/276c5c5e-0979-d244-189a-8a34fb1e996a.png)

次にDockerコンテナを実行する際に、ホスト側のフォルダーをコンテナ側のフォルダー（存在していなくてもよい）として指定します。`-v` オプションがその部分です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/f35d0056-ea10-4d03-1c95-b38f2399f3bc.png)


コンテナがスタートして、PowerShellコマンドが出てきたら、とりあえずコンテナ側でIISの`Default Web Site`がマップされているディレクトリを表示してみましょう。（下のPowerShellコマンドを上から順に実行してください）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/5d0b6c15-f818-f785-a717-a9fe23c690ae.png)

予想通りデフォルトの`C:\inetpub\wwwroot`にマップされてますね。おなじみのIISのページはここにありますね。
では、これを変更して、マウントしたホストのフォルダーを指し示すようにします。この操作は`WebAdministration`PowerShellモジュールに含まれる`Set-ItemProperty`を使います。この操作はDockerとは関係ありません。あくまでも単なるPowerShell操作です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/d03466b7-d221-903b-2e50-f340c7fc7aaf.png)

変更完了。ブラウザでチェックしてみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/3b2ba9a9-a47d-bf40-bd14-5178ad592f5f.png)

ちゃんとマウントされたホスト側のフォルダーにマップされました。

#ホストからウェブサイトを編集してみる
せっかくですから、ホスト側からサイトの内容をちょと変更してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/34c0b1fc-2c42-2d9b-56cc-7a4cd39eed8a.png)

こんな感じでパラグラフを加えました。
ブラウザで確認してみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/be9d5193-92a5-04d6-488a-5372fe3c5fca.png)

ちゃんと反映されてますね～。

#[方法その２]コンテナ側のディレクトリにアクセスする
次に、コンテナの方に新にボリュームを作成するようにDockerに指定し、その新規ボリュームにホストからアクセスする手順を解説します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/7c57dd1c-6216-b35f-0e45-f4ac24330ce3.png)

イメージにはもともとないボリューム（Windowsの場合はトップレベルのディレクトリと考えましょう）が無い場合でも、コンテナを実行する際に新たにボリュームを作成するように指定できます。下の`-v C:\mywebapp`オプションではコンテナ側に`C:\mywebapp`を作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/69d403f2-0024-87f0-5ca8-3b40772c210a.png)

`C:\mywebapp`が作成されたのが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/1c0f2251-120b-456a-0560-9de81f447fd7.png)

なにか適当にファイル操作をしてみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/ff09a92e-bfdb-770e-22ce-215c134b5347.png)
`test.txt`というファイルを作成してみました（単なるPowerShellの操作です。Dockerとは関係ありません）

ただ、PowerShell使ってファイルやディレクトリを操作するのは面倒くさいです。ホスト側からコンテナ内のこのボリュームの内容を操作したいですよね。やってみましょう。

#ホスト側からコンテナ内の作業用ボリュームの内容を変更する
まずはコンテナのメタデータを調べたいので、`docker inspect`を実行します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/d7bb20c4-e4b0-1421-2249-125d6df94e6c.png)

つぎにボリュームに関する設定を探します。以下のように`source`として指定されているDockerが管理しているディレクトリ情報を探し出します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/3f340bea-485f-19bf-6b53-2f446cb4b15d.png)

このディレクトリをWindowsエクスプローラーで表示してみましょう。例の`test.txt`というファイルがあるのが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/72a52614-5a99-d5a9-b7f0-888426f1cbe8.png)

ファイルに変更を加えます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/ea1a830a-3204-2d32-d15c-817517fe1118.png)

あれあれ、保存しようとするとアクセス権限に関連したエラーが出ます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/66eb94f7-956c-31af-d059-1f1cb8870e41.png)

ここでファイルのセキュリティ設定を変更し、ホストのユーザーに書き込み・変更権限を与えてます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/51faa2aa-f4cc-e7ba-d2e0-6ad68e200ba9.png)

するとエラーにならずに保存が出来ました。

<font color="Crimson"><strong>注意：私が調べた限りではホスト側からアクセス権限を変更した場合、Dockerエンジンへ何らかの影響があるのかどうか、分かりませんでした。得にDockerがボリュームを管理しているという点を考えるとこのハックが悪影響を及ぼす可能性を排除できません。自己責任でよろしく！</strong></font>

最後にコンテナ側から内容が変更されたかチェックしてみます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/56a44dc1-1f14-cd7f-2e4c-f8ef3f87bd30.png)

ホスト側からの変更が反映されているのが確認できます。

#まとめ
IISのDockerイメージを使ってごく簡単なウェブサイトの開発環境っぽいものを作ってみました。ASP.NETやらASP.NETCoreやらもだいたい同じようなパターンでDockerコンテナを利用できるでしょう。