はじめに
この記事は「学生 Advent Calendar 2017」7日目(大遅刻)の記事です。
docker-composeのlinks
やdepends_on
を使えば、コンテナの起動順を制御することはできます。しかし、他のコンテナの起動を待つことはできません。
例えばデータベースを利用するアプリのコンテナとデータベースのコンテナがあったときに、データベースが起動していないにもかかわらずデータベースを利用するコンテナがデータベースに接続しようとして、例外を吐いて落ちてしまうことがあります。
そこで今回はDockerize
を用いて、他のコンテナの起動を待つことができるように設計する方法を紹介します。
Dockerfile側の準備
Dockerizeはコンテナ内に導入するツールです。従って、Dockerfileにdockerize導入コマンドを追記していきます。Ubuntu(Alpine以外?)用とAlpine用にそれぞれ別のバイナリが用意されているので、導入時には注意しましょう。
バイナリをもらってくるのに必要なhttps対応のwgetを導入して、Dockerizeのバイナリを落としてきて、指定した場所に配置して、tar ballを削除するだけのコマンドです。
ENV DOCKERIZE_VERSION v0.6.1
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
ENV DOCKERIZE_VERSION v0.6.1
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に少し記述を追加するだけで、コンテナの起動を待つように設定することができました。いろいろな箇所で役立つはずですので、ぜひお試しください。