ASP.NET MVC アプリケーションは microsoft/aspnet イメージを使うことで簡単に Windows Containers で動作しましたが、実際のアプリケーションには大抵 DB がセットなので、DB を含めた形でアプリケーションを Docker で動かしてみました。
SQL Server 2016 も Docker Hub でイメージが公開されているので、これを使っていきます。
アプリケーションと DB のコンテナ両方を立ち上げる必要があるので、管理には Docker Compose を使います。依存関係を定義できるので、管理が非常に簡単になります。
Docker Compose の新しいフォーマットで書いてみたところ、コンテナの起動時にエラーになってしまいましたが、以下のサンプルに含まれる定義を参考にして解消できました。
networks の設定を追加しておかないと、現在の Windows Containers では問題になるようです。これもまた WinNAT の制約っぽいです。
作成した docker-compose.yml は以下になります。web と db の 2 つを定義してあります。
version: '2' services: web: build: ./app depends_on: - "db" ports: - "8080:80" db: image: microsoft/mssql-server-windows-express ports: - "1433:1433" volumes: - "C:/temp/:C:/temp/" environment: - sa_password=P@ssw0rd - ACCEPT_EULA=Y - attach_dbs="[{'dbName':'SampleDB','dbFiles':['C:\\temp\\AdventureWorksLT2012_Data.mdf']}]" networks: default: external: name: nat
web は Dockerfile に基づいてイメージを作成するようにしてあります。DB は attach_dbs でアタッチしたい DB ファイルを指定しておき、コンテナ起動後に SampleDB という名前で使えるようにしてあります。
この docker-compose.yml があるディレクトリで docker-compose up -d を実行すると、ビルドが行われた後にコンテナが依存関係に従って起動されます。
用意した ASP.NET アプリケーションは DB の内容を一覧表示するだけの、とても単純なものです。
毎回 IP アドレスを docker inspect で取得するのが面倒になったので、別マシンから確認してみました。
上の例ではプリコンパイル済みの ASP.NET アプリケーションを使いましたが、Dockerfile を工夫してプロジェクトフォルダをマウントし、サイトの物理パスを書き換えると開発しながら実行することもできます。
FROM microsoft/aspnet:4.6.2 RUN %windir%\system32\inetsrv\appcmd set vdir "Default Web Site/" -physicalPath:"C:\app"
appcmd を使って Default Web Site の物理パスを C:\app に変更しています。
このままだと IIS に設定したパスにはディレクトリすら存在しないので、docker-compose.yml 側で ASP.NET プロジェクトのディレクトリをマウントするように設定を追加します。
services: web: build: . depends_on: - "db" ports: - "8080:80" volumes: - "C:/app/WebApplication2/:C:/app/"
これでコンテナを起動すると ASP.NET プロジェクトのパスをサイトのルートとして IIS が起動するので、ビューを変更してリロードすると再コンパイルが行われて画面に反映されるようになります。
過去プロジェクトの環境を維持するのが面倒でしたが、Docker Compose を使えば DB のファイルを保持しておくだけで、簡単に維持が出来そうです。