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

More than 1 year has passed since last update.


はじめに

docker-composeで複数のコンテナを管理するとき、Webアプリと一緒にDBも使うと思います。

大抵はWebアプリ側にdepends_onでDBのコンテナを指定して起動順序を制御しますが、あくまで起動順序だけなのでDBの起動完了前にWebアプリがDBにアクセスしてしまい起動失敗する事があります。

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


GitBucket + MySQLの場合

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

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


files

docker-compose.yml

+ gitbucket/
+ Dockerfile
+ wait.sh

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


gitbucket/wait.sh

#!/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をインストールしています。


gitbucket/Dockerfile

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を起動します。


docker-compose.yml

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アプリを起動できるようになります。


参考