文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

復活したSchemaSpyでDB定義書を自動生成してnginxで確認するdocker環境を作ってみました

やってやった
f:id:treeapps:20170501215041p:plain

もしかしたら知っている方もいるかもしれないSchemaSpyですが、↓長らく更新が停止しており、皆静かに離れていきました。
SchemaSpy

この状況をに絶望した?人達が集まり、有志による開発がGithubで始まっていました。
github.com

以前は非常に簡素なデザインのDB定義書で、「ちょっとかっこ悪い」「(見た目が)イケてない」と思われたと思いますが、新たにデザインも刷新され、twitter bootstrapによって生まれ変わりました。

Chinook Database

折角なので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済みなのです。

github.com

今回使った(作った)イメージのサイズですが、それぞれ以下のようになっています。

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 でさっくり環境構築をして下さい。必須要件はこれだけです。

Docker For Windows | Docker

Docker For Mac | Docker

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定義書を見てみよう

http://localhost:8081/

さて、どうでしょうか。見えたでしょうか。

自動生成が成功すれば、以下のような定義書をブラウザから確認できたと思います。

テーブル一覧

f:id:treeapps:20170630222012p:plain

テーブル詳細

f:id:treeapps:20170630222033p:plain

関連図

f:id:treeapps:20170630222022p:plain

中々いい感じです。ただし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環境を増やして公開していきます!