LoginSignup
14
17

More than 3 years have passed since last update.

docker-composeでAPPコンテナがDBコンテナの起動完了を待ってくれない問題を手軽に解決する

Last updated at Posted at 2019-10-15

概要

先日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コンテナが起動した瞬間にアプリケーションコンテナが起動してしまいます.
スクリーンショット 2019-10-15 23.12.48.png

アプリケーションコンテナはDBコンテナに依存しているため, DBコンテナの起動が完了していない状態でアプリケーションコンテナが起動してしまうと以下のようにエラーが発生してしまいます.
スクリーンショット 2019-10-15 23.17.20.png

この状況を解決するためには,以下のようにシェルを書いて解決する場合が多いです.
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コンテナの起動完了を待っている状態になります.

スクリーンショット 2019-10-15 23.41.40.png

そして無事にDBコンテナの起動が完了してからアプリケーションコンテナの起動が始まりました.
先ほどはエラーでこけてしまいましたが,今回はエラーなくアプリケーションの実行が完了しました.
スクリーンショット 2019-10-15 23.40.59.png

まとめ

今回は docker-compose-wait の紹介でした.
自分自身,このライブラリを使い倒した訳ではないので基本的な使い方のみの紹介になってしまいました.
詳細はリポジトリのREADMEで確認をお願いします.
https://github.com/ufoscout/docker-compose-wait

他記事にて誤字脱字や誤った情報など記載していたらコメントで指摘していただけると幸いです!

14
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
17