開発環境構築について ~ Windows 10 Home + Dockerでmysqlを動かす ~

  • はじめに
    ローカル環境で開発作業をする際、以下のような様々な課題を経験することがあります。
    一例として、
    ・開発環境構築手順が多く、煩雑で環境を整えるのに1日費やす
    ・各自のマシンで若干設定が異なっていることによって、環境依存が生じる
    ・DBが共有化されている(共通のサーバーに有る)ので、データを容易に弄れない(データの洗い替えができないなど)
    etc
    があります。
    そこで、今回は各自のローカル環境構築の手間を減らすことを目的とした、
    Windows Homeでの開発環境の整備について記します。
    ※Windows ProとMacはDocker-toolboxを使わず、Dockerをインストールしてください。
    今回の内容で コマンドだけで、ローカル環境にAmazon Linuxを立ち上げ、その環境でアプリを動かすことができました。また、コンテナ上にMySQL(DB)を用意したことで、自分専用のDBが作れました。

構成内容

  • Windows 10 64bit Home Edition
  • Docker-Toolbox (インストーラver 18.03.0-ce)※基本的にlatestで良いと思います。
    Windows HomeではHyper-vが使えないので、Hyper-Vの代わりにOracle Virtual Boxを利用するDocker Toolboxを使います。
  • Java:java-11-amazon-corretto
  • amalizonlinux:2
  • MySQL:8.0.18

Oracle Virtual Box + Docker Toolboxをインストールする

  1. ダウンロード&インストール
    Docker Toolboxをダウンロード
    基本デフォルトで好きな場所にインストールしてください。
    デスクトップにアイコンは作っておいたほうが後々楽になります。
  2. 起動
    デスクトップに作成されたDocker Quickstart Terminalを起動させる。
    ここに起動後の画像を貼る。
    起動するとDockerでおなじみのクジラが出てくる。
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/

docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com


Start interactive shell

上記のメッセージが出ると思うので、IPをどこかに記録しておきます。(後で確認することも可能。)

合わせてDockerで使う必要なコマンドが最低限インストールされています。
docker ps
docker-compose
…etc

今回の構成

directory
| docker-compose.yml
|─Dokcer
|─java
│ Dockerfile(webアプリを動かすサーバー情報を記載)

└─mysql
│ Dockerfile(DBの情報を記載)

├─conf.d
│ my.cnf(mysqlのconf内容を記載)

└─initdb.d
1__init.sql(初期データ等を投入するためのSQL)
バージョン情報
java:java-11-amazon-corretto
amazonlinux:2
mysql:8.0.18

dockerでamazonlinuxを動かす準備

サーバーの構成を記載した、サンプルの設計書を記載します。

FROM amazonlinux:2

#タイムゾーンの設定
RUN /bin/cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# x86_64 args
ARG rpm_x64=java-11-amazon-corretto-devel-11.0.5.10-1.x86_64.rpm
ARG path_x64=https://d3pxv6yz143wms.cloudfront.net/11.0.5.10.1
ARG key_x64=13817E35D6AA26BB2D85267712EABAC5209DDBC0

# aarch64 args
ARG rpm_aarch64=java-11-amazon-corretto-devel-11.0.5.10-1.aarch64.rpm
ARG path_aarch64=https://d3pxv6yz143wms.cloudfront.net/11.0.5.10.1
ARG key_aarch64=13817E35D6AA26BB2D85267712EABAC5209DDBC0

# In addition to installing the RPM, we also install
# fontconfig. The folks who manage the docker hub's
# official image library have found that font management
# is a common usecase, and painpoint, and have
# recommended that Java images include font support.
#
# See:
#  https://github.com/docker-library/official-images/blob/master/test/tests/java-uimanager-font/container.java
RUN set -eux; \
    case "$(uname -p)" in \
        x86_64) rpm=$rpm_x64; path=$path_x64; key=$key_x64 ;; \
        aarch64) rpm=$rpm_aarch64; path=$path_aarch64; key=$key_aarch64 ;; \
        *) echo >&2 "Unsupported architecture $(uname -p)."; exit 1 ;; \
    esac; \
    \
    curl -O $path/$rpm \
    && export GNUPGHOME="$(mktemp -d)" \
    && gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys $key \
    && gpg --armor --export $key > corretto.asc \
    && rpm --import corretto.asc \
    && rpm -K $rpm \
    && rpm -i $rpm \
    && rm -r $GNUPGHOME corretto.asc $rpm \
    && yum install -y fontconfig \
    && yum clean all

ENV JAVA_HOME=/usr/lib/jvm/java-11-amazon-corretto

# recommended by spring boot
VOLUME /tmp

# create directory for application
RUN mkdir /app
WORKDIR /app

COPY ./build/libs/hogehoge.war hogehoge.war

# EXPOSE は開けるポートを指定する.
EXPOSE 8180

# set entrypoint to execute spring boot application
ENTRYPOINT ["sh","-c","java -Dserver.port=8180 -Dspring.profiles.active=local -jar hogehoge.war"]

今回はDockerfileの中身はdockerhubをもとにしています。
仮想AWS EC2とするためAmazon Linuxを使います。
最後のENTRYPOINTのみ各自が動かす環境に合わせてください。  
※warファイルでの実行を想定したものになります。

DockerでMySQLを動かす準備

DBのサンプル設計書になります。

FROM mysql:8.0.18

#MySQL設定ファイルをイメージ内にコピー
ADD ./conf.d/my.cnf /etc/mysql/conf.d/my.cnf
COPY ./initdb.d/* /docker-entrypoint-initdb.d/

#docker runに実行される
CMD ["mysqld"]

今回は最小限にしています。
※Amazon Linuxはdockerhubからコピーしたものですが、MySQLは自前です。
こういった形で記載することもできます。
MySQLのバージョンは各自が利用している環境のバージョンに合わせてください。latestにて最新を取得することも可能です。

Dockerを動かす準備

上記のAmazon LinuxとMySQLを動かすためのファイル(docker-copose.yml)を用意します。

version: '3.3'
services:
    mysql:
        build: ./docker/mysql
        environment:
            MYSQL_DATABASE: dbName
            MYSQL_USER: user
            MYSQL_PASSWORD: password
            MYSQL_ROOT_PASSWORD: rootpassword
        ports:
            - "3314:3306" #3314はhost側のポート、3306はコンテナ側のポート
    app:
        build:
            context: ./
            dockerfile: ./docker/java/dockerfile
        depends_on:
           - mysql
        ports:
            - "8090:8180" #8090はhost側のポート、8180はコンテナ側のポート
        links:
            - mysql

実際に動かす

  1. docker-compose.ymlが配置してあるパスに移動します。
    例:”C:workspase”
  2. docker-compose.exe build
    を実行する。Dockerfileに記載された内容に問題なければbuildされます。
  3. buildが正常に完了した場合、
    docker-compose.exe up -d
    を実行します。
    ※-dオプションを付けることでバックグランド実行になります。
  4. 実行されていることを確認する。
    docker-compose.exe ps
    を実行すると以下のような状態になり、stateがupになっていればOKです。
Name                       Command               State                 Ports
---------------------------------------------------------------------------------------------------
hogehoge_app_1     sh -c java -Dserver.port=8 ...   Up      0.0.0.0:8090->8180/tcp
hogehoge_mysql_1   docker-entrypoint.sh mysqld      Up      0.0.0.0:3314->3306/tcp, 33060/tcp
  1. コンテナを止めたい場合
    docker-compose stop
    を実行してください。
    ※upの反対でdownコマンドも用意されています。
    ですが、これはコンテナを停止し、そのコンテナとネットワークを削除します。なので、コンテナのDBやアプリに改変を加えていた場合破棄されます。

まとめ

今までのローカル環境構築では、各自が各PJの手順に沿ってDB接続や、アプリの設定等を行っていたと思います。この時点でMacとWindows用で2種類存在することもあるかもしれません。
ですが、用意したDockerfileを配布することで配布された側も配布した側と同じ環境がすぐに作成することができます。 (OSを意識することが少なくなります)
Dockerfileやdocker-compose.ymlもバージョン管理していくことをおすすめします。

ローカル環境にAmazon Linuxを立ち上げ、その環境でアプリが動く用になりました。また、コンテナ上にMySQL(DB)を用意したことで、自分専用のDBが作られました。
これでデータを自由に弄れるようになりますし、何回でも同じデータで復元できます。単体テスト等でデータを作り直すのも容易になるはずです。
  
今後は、nginxを追加しかつSonarQubeによる静的解析等を追加していく予定。

author k.kawai

DBの環境差異調査(mysql編)

システム開発において、
 ・本番
 ・検品(ステージング)
 ・開発
と環境が別れている事は通常よくあることであり、それにともないDBの環境もそれぞれ存在することとなります。

開発体制が小規模であったり、管理ルールが整っていない時などに、それぞれのDB環境に差異が発生している事が多々あります。
その差異を視覚化し、容易に把握するための方法をご紹介します。

※今回使用した環境
 ・mysql : 5.6.40
      https://dev.mysql.com/downloads/windows/installer/5.6.html
 ・ローカル環境:windows 10
 ・比較ツール:WinMerge 2.14.0
        https://winmerge.org/downloads/?lang=ja

1.差分抽出SQL の用意


SELECT '### COLUMN情報 #########################' AS '';
SELECT TABLE_NAME
     , COLUMN_NAME
--   , ORDINAL_POSITION
     , COLUMN_TYPE
     , COLUMN_DEFAULT
     , IS_NULLABLE
     , COLUMN_KEY
     , IFNULL( COLLATION_NAME , '')      COLLATION_NAME
     , IFNULL( CHARACTER_SET_NAME , '')  CHARACTER_SET_NAME
     , COLUMN_COMMENT 
  FROM INFORMATION_SCHEMA.COLUMNS
 WHERE TABLE_SCHEMA = @DB_DATABASE
 ORDER BY TABLE_NAME , COLUMN_NAME
;

SELECT '### INDEX情報 ##########################' AS '';
SELECT TABLE_NAME
     , INDEX_NAME
     , SEQ_IN_INDEX
     , COLUMN_NAME
  FROM INFORMATION_SCHEMA.STATISTICS
 WHERE TABLE_SCHEMA = @DB_DATABASE
 ORDER BY TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX 
;

mysql では、DBの情報を INFORMATION_SCHEMA 内に保持しており、その情報を出力しています。
※上記例では、カラムの順番を考慮せず、カラム名順で評価しています。

2.差分抽出SQL の実行

上記 SQL をファイルに保存して、コマンドで実行します。
※ここでは、「db-columns.sql」と命名します。

mysql -e "set @DB_DATABASE='DB名'; source db-columns.sql ;" > 環境.txt

※接続情報等は、省略させて頂いています。

こちらの実行した結果は以下の通りとなります。
※ mysql のバージョンに関わらず、全てのバージョンで稼働すると思います。


### COLUMN情報 #########################
TABLE_NAME	COLUMN_NAME	COLUMN_TYPE	COLUMN_DEFAULT	IS_NULLABLE	COLUMN_KEY	COLLATION_NAME	CHARACTER_SET_NAME	COLUMN_COMMENT
hoge	birthday	date	NULL	YES				
hoge	key	int(11)	NULL	NO	PRI			
hoge	name	varchar(50)	NULL	YES	MUL	utf8_general_ci	utf8	
hoge	sex	char(1)	0	YES		utf8_general_ci	utf8	

### INDEX情報 ##########################
TABLE_NAME	INDEX_NAME	SEQ_IN_INDEX	COLUMN_NAME
hoge	hoge_i1	1	name
hoge	hoge_i1	2	birthday
hoge	PRIMARY	1	key

3.SQL実行結果の比較

上記、環境毎に出力し、その結果を winmerge 等で比較する事が出来ます。
例えば、ローカルの環境と比較。

別のタブで画像を開くと、大きな画像で参照できます。

上記は、以下の テーブルを比較した結果なのですが、

-- 左のDDL
CREATE TABLE `hoge` (
	`key` INT(11) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(50) NULL DEFAULT NULL,
	`sex` CHAR(1) NULL DEFAULT '0',
	`birthday` DATE NULL DEFAULT NULL,
	PRIMARY KEY (`key`),
	INDEX `hoge_i1` (`name`, `birthday`)
)

-- 右のDDL
CREATE TABLE `hoge` (
	`key` INT(11) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(50) NULL DEFAULT NULL,
	`sex` VARCHAR(1) NULL DEFAULT '0',
	`birthday` TIMESTAMP NULL DEFAULT NULL,
	PRIMARY KEY (`key`),
	INDEX `hoge_i1` (`name`)
)

WinMarge 上で、差分行が色分けされているのが判るかと思います。
・DATE型 と TIMESTAMP 型 の差異
・CHAR型 と VARCHAR型 の差異
・INDEX の差異

※Oracle ですと、「USER_TAB_COLUMNS」・「USER_IND_COLUMNS」テーブルを使用すると、同じ情報が取得できます。

author k.tomita