DEV Community

KOGA Mitsuhiro
KOGA Mitsuhiro

Posted on • Originally published at qiita.com

docker-composeでDBの起動完了を待ってからWebアプリを実行する

はじめに

docker-composeで複数のコンテナを管理するとき、ほぼWebアプリとDBを一緒に使います。
大抵はWebアプリ側にdepends_onでDBのコンテナを指定して起動順序を制御しますが、あくまで起動順序だけなのでDBの起動完了前にWebアプリがDBにアクセスしてしまい起動失敗する事があります。

せっかくdocker-composeで1つにまとめて管理しているのに便利さが半減してしまうとモヤモヤしていたら、公式ではWebアプリ側でチェックせよと解説していました。

GitBucket + MySQLの場合

上述の公式の解説ではPostgreSQLを対象にしているのですが、MySQLをよく使うので書き換えてみました。

ファイル構成はこんな感じです。

docker-compose.yml
  + gitbucket/
      + Dockerfile
      + wait.sh

今回のメインとなるwait.shは引数からDBのホスト名、ユーザ名、パスワードを受け取って生存チェック後にWebアプリを実行します。

#!/bin/sh

set -e

host="$1"
shift
user="$1"
shift
password="$1"
shift
cmd="$@"

echo "Waiting for mysql"
until mysql -h"$host" -u"$user" -p"$password" &> /dev/null
do
        >&2 echo -n "."
        sleep 1
done

>&2 echo "MySQL is up - executing command"
exec $cmd

ベースイメージはalpine版なのでapkでmysql-clientをインストールしています。

FROM java:8-jre-alpine
MAINTAINER shiena
ENV GITBUCKET_HOME /var/gitbucket
VOLUME ["${GITBUCKET_HOME}"]
EXPOSE 8080
RUN apk add --no-cache mysql-client
COPY wait.sh /wait.sh
ENV GITBUCKET_VERSION 4.7.1
ADD https://github.com/gitbucket/gitbucket/releases/download/${GITBUCKET_VERSION}/gitbucket.war /gitbucket.war

最後にdocker-compose.ymlです。
wait.shにDBの情報を渡す必要があるため、commandでGitBucketを起動します。

version: '2'
services:
  gitbucket:
    build: gitbucket
    image: gitbucket:4.7.1
    ports:
      - "8080:8080"
    volumes:
      - ./var/gitbucket:/var/gitbucket
    depends_on:
      - db
    command: sh /wait.sh db gitbucket gitbucket java -jar /gitbucket.war

  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=1
      - MYSQL_DATABASE=gitbucket
      - MYSQL_USER=gitbucket
      - MYSQL_PASSWORD=gitbucket
      - TZ=Asia/Tokyo
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci

以上、このようなスクリプトを挟む事でDBの起動完了を待ってからWebアプリを起動できるようになります。

参考

Top comments (0)