概要
先日Dockerに初めて触れた際, DBコンテナより先にアプリケーションコンテナが立ち上がってしまう問題が起きました.
Dockerfileで depends_on
を指定すると起動順序の制御はできたのですが,コンテナの起動完了までは待ってくれないためアプリケーションコンテナでエラーが発生してしまうというものです.
調べてみると, シェルを書いて解決している記事が多かったのですが, より手軽に解決できるライブラリを発見しました.
使用技術
- spring boot (Java)
- MySQL
- Docker
docker-compose-wait
本記事で紹介するのは docker-compose-wait
というライブラリです.
https://github.com/ufoscout/docker-compose-wait
とりあえず試したい方.今回作成したサンプルリポジトリです.
https://github.com/YutaSeki36/spring-boot-docker-maven
1. ライブラリなしでコンテナをビルドしてみる
まずはライブラリ無しでコンテナをビルドしてみます.
以下の画像のように,DBコンテナが起動した瞬間にアプリケーションコンテナが起動してしまいます.
アプリケーションコンテナはDBコンテナに依存しているため, DBコンテナの起動が完了していない状態でアプリケーションコンテナが起動してしまうと以下のようにエラーが発生してしまいます.
この状況を解決するためには,以下のようにシェルを書いて解決する場合が多いです.
https://docs.docker.com/compose/startup-order/
しかし, docker-compose-wait
を使うとシェルをほぼ書かずに解決することができます.
docker-compose-waitを使ってみる
1. Dockerfile変更
Dockerfileを以下のようにします.
コメントがある部分でライブラリの追加を行なっています.
FROM maven:3.3.9-jdk-8-alpine AS build
COPY ./ /work
WORKDIR /work
RUN mvn clean package
FROM openjdk:8u181-jre-alpine3.8
WORKDIR /home
COPY ./run.sh /usr/local/bin/run.sh
RUN chmod +x /usr/local/bin/run.sh
# waitライブラリの追加
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.6.0/wait /wait
# ライブラリの権限変更
RUN chmod +x /wait
COPY --from=build /work/target/dtest-0.0.1-SNAPSHOT.jar /home/
CMD /wait && /usr/local/bin/run.sh
2. docker-composeを変更
Dockerfileを変更したらdocker-composeを修正します.
以下のように,waitさせたいコンテナのenvironmentに起動を待ちたいコンテナのホストを定義します.
version: '2'
services:
dbserver:
build: ./docker/mysql
image: demo-db:0.0.1
restart: always
environment:
MYSQL_DATABASE: demo_db
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: rootpassword
ports:
- "3314:3306"
volumes:
- ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d
- ./docker/mysql/conf.d:/etc/mysql/conf.d
- ./log/mysql:/var/log/mysql
app:
build: ./
image: dtest/boot:0.0.1
depends_on: # 依存関係をここで指定できるが,順序を指定できるだけで起動を待ってくれたりはしない
- dbserver
ports:
- "8080:8080"
volumes:
- .:/app
environment:
# waitするホストを指定する.
# 複数のwait_hostを指定することもできます.(MySQLだけでなくRedisの起動を待ちたい時なども便利です.)
WAIT_HOSTS: dbserver:3306
volumes:
mysql-db:
driver: local
ビルド
以上のファイル修正を行なってから docker-compose up --build
を実行してみましょう.
先ほどはDBコンテナが起動してからすぐにアプリケーションコンテナが起動してしまいましたが,今度はアプリケーションコンテナがDBコンテナの起動完了を待っている状態になります.
そして無事にDBコンテナの起動が完了してからアプリケーションコンテナの起動が始まりました.
先ほどはエラーでこけてしまいましたが,今回はエラーなくアプリケーションの実行が完了しました.
まとめ
今回は docker-compose-wait
の紹介でした.
自分自身,このライブラリを使い倒した訳ではないので基本的な使い方のみの紹介になってしまいました.
詳細はリポジトリのREADMEで確認をお願いします.
https://github.com/ufoscout/docker-compose-wait
他記事にて誤字脱字や誤った情報など記載していたらコメントで指摘していただけると幸いです!