Edited at

Dockerizeを使って他のコンテナの起動を待つ

More than 1 year has passed since last update.


はじめに

この記事は「学生 Advent Calendar 2017」7日目(大遅刻)の記事です。

docker-composeのlinksdepends_onを使えば、コンテナの起動順を制御することはできます。しかし、他のコンテナの起動を待つことはできません。

例えばデータベースを利用するアプリのコンテナとデータベースのコンテナがあったときに、データベースが起動していないにもかかわらずデータベースを利用するコンテナがデータベースに接続しようとして、例外を吐いて落ちてしまうことがあります。

そこで今回はDockerizeを用いて、他のコンテナの起動を待つことができるように設計する方法を紹介します。


Dockerfile側の準備

Dockerizeはコンテナ内に導入するツールです。従って、Dockerfileにdockerize導入コマンドを追記していきます。Ubuntu(Alpine以外?)用とAlpine用にそれぞれ別のバイナリが用意されているので、導入時には注意しましょう。

バイナリをもらってくるのに必要なhttps対応のwgetを導入して、Dockerizeのバイナリを落としてきて、指定した場所に配置して、tar ballを削除するだけのコマンドです。


Ubuntuの場合

ENV DOCKERIZE_VERSION v0.6.0

RUN apt-get update && apt-get install -y wget \
&& wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz


AlpineLinuxの場合

ENV DOCKERIZE_VERSION v0.6.0

RUN apk add --no-cache openssl \
&& wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz


docker-compose側の準備

続いてdocker-compose側で待つ対象を指定します。今回はentrypointを利用して待つ動作を挟み込みましょう。今回はタイムアウト時間を60秒に設定し、tcp://mysql:3306に応答があるまで待つようにしています。

ただ、このままだと応答があった時点でコンテナが終了してしまうので、commandに起動したいアプリの起動コマンドを記入しておくことを忘れないでください。今回はPythonアプリを起動する例を挙げておきます。

version: '3'

services:
app:
build: .
ports:
- "5000:5000"
links:
- mysql
entrypoint:
- dockerize
- -timeout
- 60s
- -wait
- tcp://mysql:3306
command: python /usr/src/app/hoge/app.py

mysql:
image: mariadb:latest
environment:
MYSQL_ROOT_PASSWORD: 'root_pass'
MYSQL_DATABASE: 'hoge'
MYSQL_USER: 'hoge'
MYSQL_PASSWORD: 'hoge_pass'
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci


おわりに

既存のDockerfileとdocker-compose.ymlに少し記述を追加するだけで、コンテナの起動を待つように設定することができました。いろいろな箇所で役立つはずですので、ぜひお試しください。