DockerForWindowsで開発用SQLServerを利用する
はじめに
.NETアプリケーションを作るのにSQLServerを利用しようと思ったが、
クライアント環境を汚さないように、勉強も兼ねてDockerで稼働させることにした。
今回はSQLServer Developer 2017を稼働させる。
Docker体験も兼ねてるので、Docker知ってる人なら当たり前・・という内容も含まれているので注意。
なお、このページの内容は下記ページに基づいています。
https://hub.docker.com/r/microsoft/mssql-server-windows-express/
環境
- Windows10 Professional
- SQL Server Management Studio 17.3(クライアント環境を汚さないようにと思うが、やはりSSMSは欲しい)
- Docker CommunityEdition 17.09.1-ce-win42 (14687)
DockerForWindowsの導入
本題ではないが簡単に記載。Windows10の場合、Professional以上のエディションが必要。
- Windowsの機能の有効化より、「Hyper-V」、「コンテナー」をインストール
- Docker for windowsをインストールする。(https://docs.docker.com/docker-for-windows/install/)
- DockerをWindowsContainerモードにしておく(タスクトレイを右クリックしてSwitch to Windows containers...)
- PowerShellタブ補完のインストール(任意)
- PowerShellで>Install-Module posh-dockerする
- "Import-Module posh-docker"をprofile.ps1に追加する。
imageの取得
サイズも大きいので、一旦imageを取得しておく。サイズは11.6GBとなかなか大きい。
expressの場合はmicrosoft/mssql-server-windows-expressをpullする。
docker pull microsoft/mssql-server-windows-developer
コンテナの起動
環境変数として下記を指定する。
ACCEPT_EULA・・・利用許諾契約に同意するかどうか。Yで指定。
sa_password・・・管理ユーザー(saユーザー)のパスワードを指定。複雑性の要件あり。
attach_dbs (任意)・・・dbName(DB名)、dbFiles(mdf,ldfファイル)を指定。
docker run -d -p 1433:1433 -e sa_password=P@ssw0rd -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer
オプションの意味は下記。
d・・・デタッチドモード。ルートプロセスが終了したらコンテナも終了する。
p・・・[ホスト側ポート]:[コンテナ側ポート]でポートフォワードする。
e・・・[変数名]=[値]で環境変数を指定。
SQLServerインスタンスは通常1433ポートを利用する。
この段階で、localhost:1433にsaユーザーで接続可能となる。
コンテナの停止・終了
コンテナの停止は、docker stop。(32fad42ed443は"docker ps -a"で確認可能なコンテナID)
数分かかかる。
docker stop 32fad42ed443
コンテナの再開は、
docker start 32fad42ed443
停止、再開であればデータは保持される。
コンテナの削除は停止後に、
docker rm 32fad42ed443
コンテナ内のデータが消えるため、データを永続化したい場合は注意。
データの永続化
システムDBなどは、コンテナ側の下記フォルダに保存される。
C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA
新しいDBを作成する場合もコンテナ内のフォルダパスを指定する。
ただしこのままでは、上記の通りコンテナ削除時にデータが消えてしまう。
永続化するには、ホスト側のフォルダをvオプションでコンテナにマウントする。
下記のようにすると、ホスト側のc:/Users/hoge/work/docker-mssql/dataをコンテナ側のC:/DATAにマウントする。C:\Data以下にmdf,ldfファイルを作成することでコンテナを削除してもデータが消えなくなる。
(Windowsのボリューム指定方法はぐぐると色々書き方があったが、私の環境では下記の書き方で通った。)
docker run -d -p 1433:1433 -e sa_password=P@ssw0rd -e ACCEPT_EULA=Y -v "c:/Users/hoge/work/docker-mssql/data:C:/DATA" microsoft/mssql-server-windows-developer
作成したmdf,ldfファイルを読み込んだ状態でコンテナを起動するには、下記のようにattach_dbs環境変数を指定する。
docker run -d -p 1433:1433 -e sa_password=P@ssw0rd -e ACCEPT_EULA=Y -e attach_dbs="[{'dbname':'testDB','dbFiles':['C:\\DATA\\testdb.mdf','C:\\DATA\\testdb_log.ldf']}]" -v "c:/Users/hoge/work/docker-mssql/data:C:/DATA" microsoft/mssql-server-windows-developer
デフォルトのC:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATAにマウントできたらいいなぁと思ったが、思ったようにマウントできず断念。半角スペースの前を\でエスケープしたらコンテナ起動はできたが、何か違う場所をマウントしてしまっているのか、DB作成してもファイルができなかった。
もともとシステムDBのファイルなどあるので、だめなのかも??よくわからず。
PowerShellでフォルダ比較を行う
PowerShellの中でフォルダの中身を再帰的に比較したいことがあったため、調べた結果をメモ。
diffコマンドがあればこんな苦労はないのだが、PowerShellやWindows標準のコマンドだとかゆいところに手が届かない感じ。
GUIならWinMergeがあるが、今回はPowerShellスクリプトから利用したい。
ググると、下記情報が出てくる。
stackoverflow.com
コードとしては下記の通り。
$d1 = get-childitem -path $dir1 -recurse $d2 = get-childitem -path $dir2 -recurse compare-object $d1 $d2
Get-ChildItemで比較する2フォルダを取得して、そのままCompare-Objectに渡している。
このやり方を試してみると特徴は、
- ファイルの有無を比較できる
- ファイルの内容の比較はできない
- 同一ファイル名が別階層に存在していると差分なし扱いになってしまう
といったところ。
同一ファイル名の別階層を差分なし扱いにするため、今回は下記のように改変して使ってみた。
$d1 = (Get-Childitem -Path $dir1 -Recurse | % { $_.FullName.Replace(("$dir1" + "\"), "") }) $d2 = (Get-Childitem -Path $dir2 -Recurse | % { $_.FullName.Replace(("$dir2" + "\"), "") }) compare-object $d1 $d2
ファイルリストの比較はこれで問題なさそう。
本当はファイル内容の比較も行いたかったがそちらは簡単な書き方が結局見つけられず、普通にループしながらCompare-Objectをひたすら実行することに・・・。
Spring Boot触ってみる その5 ープロファイルを利用した環境ごと設定の切り替えー
Spring Boot触ってみる その4 ーSQLServerへの接続ー - endokのブログ
の続き。
DB接続設定など、実行する環境に応じて切り替えたいパラメータがある。
Springでは"Profile"という仕組みで切り替えることができる。
その1(http://endok.hatenablog.com/entry/2016/06/04/124011)で作成したサンプルプロジェクトを引き続き利用する。
続きを読むSpring Boot触ってみる その4 ーSQLServerへの接続ー
Spring Boot触ってみる その3 ーThymeleaf Layout Dialectでレイアウトを共通化ー - endokのブログ
の続き。
SpringBootでのSQLServerへの接続方法を確認する。
SpringBoot特有の設定ということはなく、Springであれば同じような設定となるだろう。
その1(http://endok.hatenablog.com/entry/2016/06/04/124011)で作成したサンプルプロジェクトを引き続き利用する。
続きを読むSpringで定義済のBean名一覧を出力する
SpringBootはSpringのBean設定を隠蔽してくれているのだが、SpringBoot側で定義しているBeanをInjectionしたいときにはどういったBeanが定義済なのかわからず困る。
定義済のBean名をすべて出力する方法を調べたのでメモ。
方法は下記の通り。
1. BeanFactoryAwareをimplementsして、BeanFactoryを取得する。
2. BeanFactoryをDefaultListableBeanFactoryにキャストして、getBeanDefinitionNamesメソッドを利用する。
Controllerで実装した場合の例はこのようになる。
@Controller public class HelloController implements BeanFactoryAware { private DefaultListableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (DefaultListableBeanFactory)beanFactory; } @RequestMapping(value = "/page1") public String page1() { for (String name : beanFactory.getBeanDefinitionNames()) { System.out.println(name); } return "page1"; } }
Spring Boot触ってみる その3 ーThymeleaf Layout Dialectでレイアウトを共通化ー
Spring Boot触ってみる その2 ーController,テンプレートエンジン(Thymeleaf)ー - endokのブログ
の続き。
Thymeleafにもincludeなどを使った共通化の仕組みはあるが、
各ページごとにincludeは書きたくない・・・。
Tilesのように共通レイアウトを定義する仕組みはないものかと調べたところ、
Thymeleaf Layout Dialect(https://github.com/ultraq/thymeleaf-layout-dialect)というものがあったため試してみる。
その1(http://endok.hatenablog.com/entry/2016/06/04/124011)で作成したサンプルプロジェクトを引き続き利用する。
続きを読むSpringBootの開発に自動リロード(ホットデプロイ)を導入する
目次
- 目次
- はじめに
- SpringLoaded
- 特徴
- 導入方法
- Spring Boot Dev Tools
- 特徴
- 導入方法
- まとめ
はじめに
SpringBootの開発の流れは、
1. コードを書く
2. [Run As]→[Spring Boot App]で起動
3. 動作確認する
4. コードを書く
5. Consoleから起動中のアプリをTerminate
6. [Run As]→[Spring Boot App]で起動
7. 3に戻る
としていたが、
いちいち修正を反映するのに停止して起動するのは煩わしい。
1つ処理を書くたびに動作確認したいタイプなので、開発効率が悪くなってしまう。
S2Containerにはホットデプロイあって楽だったなぁ・・・と思ったので同様の仕組みを調べてみた。
- JRebel(http://samuraism.com/products/zeroturnaround/jrebel)
- SpringLoaded(https://github.com/spring-projects/spring-loaded)
- SpringBootDevTools(http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html)
Springという名前が付いているし、JRebelは商用(myJRebelというフリー版もあるようだが)なので、SpringLoadedとSpringBootDevToolsを試してみる。