やってやった
もしかしたら知っている方もいるかもしれないSchemaSpyですが、↓長らく更新が停止しており、皆静かに離れていきました。
SchemaSpy
この状況をに絶望した?人達が集まり、有志による開発がGithubで始まっていました。
github.com
以前は非常に簡素なデザインのDB定義書で、「ちょっとかっこ悪い」「(見た目が)イケてない」と思われたと思いますが、新たにデザインも刷新され、twitter bootstrapによって生まれ変わりました。
折角なのでSchemaSpyを再び使ってみようとしましたが、Dockerに慣れてきた私達には、graphviz, javaをインストールしたり、JDBCドライバをダウンロードする事すら億劫です。
SchemaSpyによって生成したDB設計書をローカルに保存したくないので、サーバに定義書を配置して定義書の閲覧はサーバに配置されたものをブラウザで確認したいのです。apacheやnginxで確認用のwebサーバを立てるなんて絶対嫌ですね。
という事で、Dockerで一通りの環境を揃えてみました。
システム要件
- Docker v1.13以上
- docker-compose
技術要素
- SchemaSpy v6.0
- MySQL-server(こちらでは用意しないので、各自用意して下さい)
- Dcoker v17
- docker-compose v1.14
- alpine linux v3.6(nginxとschemaspyでDB定義書を共有するためのvolume container)
- alpine linuxベースのnginx v1.13.1
- alpine linuxベースのopenjdk v1.8
常駐するのはalpineベースの軽量なnginxのみで、schemaspyコンテナは実行する時のみしか現れないようにしたので、マシンリソースにも優しいと思います。
環境構築手順
例によって事前にgithubにpush済みなのです。
今回使った(作った)イメージのサイズですが、それぞれ以下のようになっています。
dtree:~ tree$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE treetips/schemaspy-mysql latest 54c553615d38 20 hours ago 208MB alpine 3.6 7328f6f8b418 2 days ago 3.97MB nginx 1.13.1-alpine 33aa78cbda15 10 days ago 15.5MB openjdk 8u121-jdk-alpine 630b87931295 7 weeks ago 101MB
treetips/schemaspy-mysqlはopenjdk:8u121-jdk-alpineのイメージをベースにして208MByteとなりました。
このopenjdkはalpine linuxベースなので、恐らくかなり小さいサイズだと思うのですが、それでもまだ大きいですね。208MBのうち101MBがopenjdkで占有しているのが泣けてきますね。
docker環境を用意する
docker for mac, docker for windows でさっくり環境構築をして下さい。必須要件はこれだけです。
git cloneする
git clone https://github.com/treetips/schemaspy-mysql.git
schemaspy.propertiesをいじる
schemaspy.propertiesにデータベースの接続情報を書いて下さい。
cd schemaspy-mysql
vi schemaspy.properties
コンテナを起動する
お馴染みの起動です。
docker-compose up -d
schemaspyのコンテナ起動時にDB定義書の自動生成をします。生成が完了すると、schemaspyコンテナはそっと消えます。
nginxコンテナだけデーモン起動します。
ブラウザでDB定義書を見てみよう
さて、どうでしょうか。見えたでしょうか。
自動生成が成功すれば、以下のような定義書をブラウザから確認できたと思います。
テーブル一覧
テーブル詳細
関連図
中々いい感じです。ただしColumnsタブを開く際は注意がいるかもしれません。全テーブルの全カラムが表示されるので、100テーブルとかあると・・・
DB定義書を更新する
再度SchemaSpyを実行し、DB定義書を生成します。
停止中のschemaspyを叩き起こすのですが、--rmオプションを付けるので、実行が完了するとまた静かに眠りに付き、リソースを消費し続ける事はありません。
docker-compose run --rm schemaspy
本当はcron用コンテナでも用意してそこからSchemaSpyコンテナを叩こうと思ったのですが、再実行したいタイミングは人によって違うと思ったので、やめておきました。場合によってはCIサーバでDBマイグレーションが実行されたタイミングでピンポイントで実行したいかもしれませんし。
私はまだまだdockerを始めたばかりで全然ベストプラクティスが解ってないのですが、コンテナをバッチ的に起動するって、どうやるのがいいのでしょうね。
一番簡単なのは今回のようにホスト側のcrontabで叩いてしまえばいいのですが、ホスト側のcron設定を汚すのも微妙に嫌ですね。Jenkins等のCIでスケジューリングして叩くのも楽ではありますが、ちょっと格好悪い気もしています。
DBマイグレーション実行後のみ叩きたいケースや、手動で再生成したいケースを考えると、やはりホスト側から叩くのが良い気がしていますが、どうするのがよいのやら。digdagとかairflow的なワークフローコンテナ用意するとか?
実装するうえでハマった点
AWTFontDefaultChar: symbol not found
java.lang.UnsatisfiedLinkError: /usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/libfontmanager.so: Error relocating /usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/libfontmanager.so: AWTFontDefaultChar: symbol not found
このエラーはバグで、openjdkのバージョンによって起きるようです。最新バージョンで試してもエラーが起きたので、openjdk:8u121-jdk-alpine を使いました。
FontConfigurationのNullPointerException
schemaspy_core | java.lang.NullPointerException schemaspy_core | at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264) schemaspy_core | at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219) schemaspy_core | at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
これはAlpine linuxで起きがちなエラーで、単にシステムフォントがインストールされていないだけです。
ttf-dejavu等を適当にインストールしちゃって下さい。
wget: can't execute 'ssl_helper': No such file or directory
Alpine linuxでwgetをインストールしてhttpsのURLを指定すると、以下のエラーが起きました。
wget: can't execute 'ssl_helper': No such file or directory wget: error getting response: Connection reset by peer
ca-certificatesを使う方法もあるようですが、私は面倒なのでlibresslをインストールして解決しました。(ダウンロード後は不要なのでdelします)
schemaspy.propertiesのschemaspy.portが反映されない
これは単純にschemaspyのバグっぽいです。何指定しても無視されます。コマンドラインパラメータでportを指定しても同様の結果になりました。
なので、現状は残念ながら3306固定だと思って下さい。(MySQL以外だと違うかもしれませんね)
雑感
最近開発支援のツール等をdocker-composeを使ってサクッと構築しています。
実装がクソですが、一応紹介してみます。
静的リソースビューワー
github.com
これは、gitにpushされたファイルを、git環境無しでブラウザから閲覧できるようにする支援を行うものです。
と言っても単にnginxコンテナを起動してhtdocsのボリュームをホストと同期し、CIで定期的にhtdocsにファイルをpullすると、デザイナや営業がSourceTree等をインストールしなくてもgitのファイル群を確認できるよ、というクソツールです。
SeleniumGrid + nightwatchのE2Eテスト支援
github.com
ほぼサンプルプロジェクトですが、Dockerコンテナ上にSeleniumGridを構築し、ChromeとFirefoxに対してNightwatchでE2Eテストするためのものです。ローカル環境で実行する場合はGrid起動せず、自分のPCにインストールされたブラウザを直接起動するnpmスクリプトも用意しています。
複数のMySQL・MariaDBデータベースを一括起動
github.com
業務で使うデータベースがほとんどMySQLで、案件毎にバージョンが異なるのがウザかったので、いっそMySQLもMariaDBもありったけ起動してやれ!的なノリで作りました。docker-compose up -dすると、MySQL5.5〜5.7、MariaDB 10.0〜10.3を全部一気に起動するという、細かい事は一切気にしない男らしいコンテナです。
ちなみに前述のスクリーンショットは、この男らしいコンテナにテストテーブルを作って自動生成したものをキャプチャしたものなのです。
テスター向けのphpMyAdmin
これはDockerfileが不要なのでgithubにもdocker-hubにもアップしてませんが、以下のようにdocker-compose.ymlを保存して実行するだけで、WEB版のphpMyAdminが起動できます。
version: '3' services: phpmyadmin: image: phpmyadmin/phpmyadmin:latest container_name: phpmyadmin environment: - LANG=ja_JP.UTF-8 - TZ=Asia/Tokyo - PMA_HOST=127.0.0.1 ports: - "8080:80"
強い権限を持つユーザでphpMyAdminにログインされると、テーブルの削除やカラム定義の変更等が行えてしまうので、select・insert・update・deleteのみが行える専用ユーザを用意すると、テスターが自分でデータをいじってテストする事ができて便利です。
こんな感じで最近dockerで簡単に用意できる便利ツール的なものを導入していってます。
↑では挙げてませんが、アプリケーション内の画像を、ビルド時に画像変換(圧縮)するものも作ってたりします。parallelコマンドとmogrifyコマンドで並列実行し、高速に一括で画像変換するものです。業務ではそれを使っているのですが、githubで公開するにはクオリティが低すぎるので、公開していません。
ImageMagickコンテナを作っていて思ったのですが、コンテナ内で変換した画像ファイルのowner・groupの権限設定って目茶苦茶面倒臭いですね。ホストとコンテナでユーザIDとグループIDを合わせたユーザで変換しないと駄目なんですよね。何も考えずにコンテナ内で変換してもroot:rootになるし、かといってuid・gidを揃えないとホスト側からは存在しないuid・gidのowner・groupになってしまうし。
こんな感じで今後も簡単に試せて簡単に捨てる事ができるdocker環境を増やして公開していきます!