Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /home/kpkyvkzp/public_html/unskilled.site/wp-content/plugins/all-in-one-seo-pack/modules/aioseop_opengraph.php on line 825
[使い方基本版]DockerComposeでコンテナ立ち上げ・連携を楽にする | Unskilled?
2017/01/11 19:30:35

[使い方基本版]DockerComposeでコンテナ立ち上げ・連携を楽にする


Warning: Attempt to read property "post_excerpt" on null in /home/kpkyvkzp/public_html/unskilled.site/wp-content/themes/unskilled2/content-header-eyecatch.php on line 5
目次(クリックするとジャンプします)
  • 1:今日も今日もでコンテナ立ち上げ
  • 2:DockerComposeを使う
  • 2.1:DockerComposeインストール
  • 2.2:ymlってなんだ?
  • 2.3:記述に関してのversionの存在
  • 2.4:サービスの名前を指定
  • 2.5:imageを指定する
  • 2.6:ymlの最小構成とサービスの起動
  • 2.6.1:docker-compose run
  • 2.6.2:docker-compose up
  • 2.7:docker-compose 「up」 「run」の違い
  • 2.7.1:upはサービス全体立ち上げ
  • 2.7.2:runコマンドはone-off
  • 2.8:コンテナ名を指定する
  • 2.9:dockerfileをビルドしてコンテナを立ち上げる
  • 2.10:dockerfileをビルド
  • 2.11:イメージ名を付けてビルド
  • 2.11.1:dockerfileのファイル名指定
  • 2.11.2:コンテキスト指定
  • 2.11.3:GitHubなどからの取得
  • 2.12:さまざまなオプション
  • 2.13:具体例
  • 2.13.1:ポートの開放およびバインド
  • 2.13.2:コマンドの実行
  • 2.14:コンテナの連携
  • 2.14.1:サービス名とコンテナ名に注意
  • 3:補足・ハマったポイント
  • 3.1:depends_onについて
  • 4:まとめ

今日も今日もでコンテナ立ち上げ

いままでコマンドラインでせっせとdocker runでコンテナ立ち上げていた人。はいそれは私です。

単純なコンテナならコマンドラインでもいいのですが、ちょっと複雑なオプションだったり、コンテナ同士の連携をやろうとすると手打ちでコマンド打っていくのとてもつらいです…。

シェルスクリプトでコンテナ立ち上げとかやっていたのですが、専用のツール使ったほうがいいかと思いDockerComposeを使い始めた次第です。

なかなか使い方がわからなくて勉強していましたので、せっかくだから記事にまとめてみるべと思いました。

ちょっと長い記事ですが、基本的なことは抑えられたかなと思います。

DockerComposeを使う

Dockerツール群の一つであるDockerComposeを使うと、コンテナ立ち上げ設定をファイル化(yml形式)して管理することが可能になります。

自前のシェルスクリプトでも同じようなことはできますが、手軽さが段違いです。

DockerComposeはPythonで書かれています。

DockerComposeに関しての情報は以下がおすすめです。公式ドキュメントの日本語訳です。

Docker Compose(日本語)
http://docs.docker.jp/compose/toc.html

DockerComposeインストール

導入方法は公式のページで解説されています。

Install Docker Compose(英語)
https://docs.docker.com/compose/install/

日本語訳もあります。参照してください。

Docker Compose のインストール(日本語)
http://docs.docker.jp/compose/install.html

いくつかのディストリビューションではパッケージがあるかと思いますので検索してみてください。

Arch Linuxにはパッケージありました。

DockerComposeはPythonアプリなのでpipからインストールすることも可能です。

ymlってなんだ?

@MINOはRails on Rubyをほとんど触ったことがないのであまりyml形式のファイルに慣れていません。

と思っていたのですが、そういやtmuxのtmuxinaterがRuby製で設定ファイルがyml形式だったことを忘れていました。

ymlは

データ構造を記述するフォーマット

の一つということで、jsonみたいなものの仲間と考えて良さそうですね。

というかymlはjsonのスーパーセット(上位互換みたいな感じ)だそうで、json形式でもymlとして認識してくれるらしいです。

ただjsonみたく波括弧をたくさん書かなくてよく、キーとインデントで構造を作っていくので記述するのが結構楽でいいですね。

キー:値
 キー:値
   キー:
    - 値
    - 値
 キー:値
 キー:値

DockerComposeではこのyml形式ファイルを使って、コンテナ起動に関してを記述していきます。

DockerComposeで使うファイルは

docker-compose.yml

というファイル名にします。任意のファイル名でも使えますが、このファイル名だとファイル指定を行わなくても自動的に認識してくれますので楽ですよ。

保存場所は任意の場所でも構いませんが、後々Dockerfile指定などのコンテキストのために、プロジェクトの作業ディレクトリのルートに置くのが普通のようです。

記述に関してのversionの存在

DockerComposeではymlの記述に関してversion12が存在しています。

が、すでにversion1は廃止が決定していますので、今後使えなくなります。

ですので新しくymlを記述する場合はversion2のほうが無難です。またversion2の方がより柔軟に記述できるようになっています。

version2を指定する方法は以下です。

version: '2'

この行が無い場合、composeはymlをversion1と判断します。

さらにversion2ではデータ構造のトップレベルとしてservicesという構造(キー)が必要になります。

version2として記述するには最低限以下の2行が必要ということになります。

version: '2'
services:

サービスの名前を指定

services構造直下に各コンテナに関しての記述を行っていくのですが、次の構造(キー)として各サービス名があります。

コンテナ一つでサービス担っている場合もありますが、複数のコンテナで一つのサービスを提供している場合もあります。

その場合立ち上げるコンテナごとに記述内容が異なるはずですので、区分して記述するために構造を分割します。

例えば、webサイトを表示させるコンテナを記述する場合、「web」などという名前で構造を作ります。もちろん任意の名前でokです。

注意点としてはこの名前がコンテナの名前になるわけではありません。

コンテナ名の指定は別途指定の方法があります。

サービス名を指定すると以下の様になります。今回はbusyboxでテストするのでshellという名前にしました。

version: '2'
services:
    shell:

imageを指定する

次にコンテナを生成するためのイメージに関して記述します。

以下の様に単にimageを指定すると、すでに存在するimageを探してくれます。docker runの時と同じ様にまずローカルのimageから検索して、なければDockerHubからの取得を試みてくれます。

たとえばbusyboxを立ち上げたい場合は以下の様になります。

version: '2'
services:
    shell:
        image: busybox

2つのサービスを記述する場合の構造は以下のような感じになります。(意味のない組み合わせですが…)

version: '2'
services:
    shell:
        image: busybox
  os:
        image: debian

ymlの最小構成とサービスの起動

おそらく先程のimageを指定しただけのymlファイルが最小構成になると思います。この状態でもdocker-compose runコマンドでコンテナを立ち上げることが可能です。

docker-compose run

docker-compose runではymlに記述したサービス名を指定し、一つのサービス(コンテナ)を起動させることができます。

例えば先程のdocker-compose.ymlが/home/workdirにある場合、以下のようにしてコンテナを起動することができます。

shellサービス(busyboxコンテナ)を起動させてみます。

$cd /home/workdir
$ docker-compose run shell
# / ←busyboxのシェルが起動した

docker-compose up

またdocker-compose upというコマンドもあります。こちらはymlに記述したすべてのサービスを起動させます。

$ docker-compose up 
Starting vimdocker_os_1
Starting vimdocker_shell_1
Attaching to vimdocker_shell_1, vimdocker_os_1
vimdocker_shell_1 exited with code 0
vimdocker_os_1 exited with code 0

しかし先のymlではdocker-compose upで起動しようとするとすぐに終了してしまいました。

これはdocker runでシェル起動するコンテナを作る場合、標準入力のバインド(iオプション)と仮想端末(tオプション)の指定をしない場合、シェルが起動しないままコンテナがすぐに終了してしまう挙動と同じことです。

コンテナでは何か継続的に動くプロセスがないと終了してしまうのは、docker runでコンテナを起動する時と変わりません。

docker-compose 「up」 「run」の違い

upとrunはどちらもコンテナを立ち上げるためのコマンドです。

upはサービス全体立ち上げ

upはdocker-compose.ymlに記述された内容をもとに、すべてのコンテナを設定通りビルド、起動、アタッチさせます。

複数コンテナで形成されるサービスを立ち上げるのが本来のupの使い方です。

またupで起動されたコンテナの出力は統合されることになります。

そのため以下のようdocker-compose.ymlでtty(docker run -tオプションに相当)、stdin_open(docker run -iオプションに相当)を記述しても、ttyはインタラクティブにはなりません。

version: '2'
services:
    shell:
        image: busybox
        stdin: true
        tty: true

runコマンドはone-off

一方runはdocker-compose.ymlに記述したコンテナを臨時にビルド、起動させます。

通常では一つのコンテナを立ち上げるために使われますので、docker-compose.ymlに記述したサービス名をもってrunするコンテナを指定します。

docker-compose runではデフォルトでdocker runのiオプション、tオプションが有効な状態で実行したのと同じ意味を持ちます。

そのためstdin(iオプション)、tty(tオプション)を記述しなくてもコンテナのシェルが(シェルが起動する設定であれば)表示されます。

$ docker-compoce run shell
# /  ←busyboxのシェルが起動した

コンテナ名を指定する

docker-compose upにて起動したコンテナをdocker psで確認してみます。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS       NAMES
a75d8da9e18f        busybox             "sh"                10 minutes ago      Exited (0) 10 minutes ago      workdir_shell_1

コンテナ名が自動で付いているのがわかるかと思います。

docker runの場合、コンテナ名を指定しないとランダムな単語の組み合わせでコンテナ名が付けれれますが、なにやらランダム単語というわけではなさそうです。

確認したところ、docker-compose upでのコンテナ名は「docker-compose.ymlが置かれているディレクトリ名」+「サービス名」+「数字」がデフォルトになっているようです。

workdir_shell_1

docker-compose runにて起動したコンテナはコンテナ名にrunが追加され、「docker-compose.ymlが置かれているディレクトリ名」+「サービス名」+「run」+「数字」となります。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS       NAMES
c776964a6283        busybox             "sh"                10 minutes ago      Exited (0) 10 minutes ago      workdir_shell_run_1
workdir_web_run_1

場合によってはコンテナに任意の名前を付けたい場合があるかと思います。

その場合はcontainer_nameキーにて指定します。

これはdocker runの–nameオプションに相当します。

以下ではfreeboxというコンテナ名を付けた例です。

version: '2'
services:
    shell:
        image: busybox
        container_name: freebox

docker psで確認してみるとコンテナ名が指定したものになっています。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS       NAMES
ecfde54af4aa        busybox             "sh"                10 minutes ago      Exited (0) 10 minutes ago      freebox

dockerfileをビルドしてコンテナを立ち上げる

DockerComposeでは任意のdockerfileをビルドする設定も記述できます。

以下の様なdockerfileを作ってみました(意味なさすぎですが)。

//dockerfile
FROM busybox
RUN echo "busy!!"

このdockerfileで色々テストしてみます。

dockerfileをビルド

例えばディレクトリの中が以下のような場合

/home/workdir
    dockerfile 
    dokcer-compose.yml

以下のようにしてビルド指定が行えます。

version: '2'
services:
    shell:
        build: .

build: .のドットはカレントディレクトリを意味することになります。

デフォルトで「Dockerfile(またはdockerfile)」というファイル名のDockerfileを探してくれますので、/home/workdir直下にあるdockerfileがビルドされコンテナが起動することになります。

docker-compose upを実行してみます。

$ docker-compose up
Building shell
Step 1 : FROM busybox
 ---> 1efc1d465fd6
Step 2 : RUN echo "busy!!"
 ---> Running in aa577f059517
busy!!
 ---> 5ec12e87cb89
Removing intermediate container aa577f059517
Successfully built 5ec12e87cb89
WARNING: Image for service shell was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating vimdocker_shell_1
Attaching to vimdocker_shell_1
vimdocker_shell_1 exited with code 0

ビルドとコンテナの起動(プロセスが無いので終了してしまってはいますが)は成功したようですが、なにやらWARNINGメッセージがでています。

これはimageが存在していなかったため、「なかったからビルドしたお」という警告です。

ビルドを伴う場合には以下のように明示的に–buildオプションを付けて実行します。(以下の実行は一旦image及びコンテナを削除して何もない状態にしてから実行しています)

$ docker-compose up --build 
Building shell
Step 1 : FROM busybox
 ---> 1efc1d465fd6
Step 2 : RUN echo "busy!!"
 ---> Running in 0c489b927f30
busy!!
 ---> 0e489c3e3617
Removing intermediate container 0c489b927f30
Successfully built 0e489c3e3617
Creating vimdocker_shell_1
Attaching to vimdocker_shell_1
vimdocker_shell_1 exited with code 0

今度はWARNINGメッセージはでなくなりました。

またビルドのみを行う場合は以下のようにdocker-compose buildコマンドが使えます。

$ docker-compose build 
Building shell
Step 1 : FROM busybox
 ---> 1efc1d465fd6
Step 2 : RUN echo "busy!!"
 ---> Running in 164c23f6fb54
busy!!
 ---> f5f40b09c0da
Removing intermediate container 164c23f6fb54
Successfully built f5f40b09c0da

ビルドのみが実行されています。

イメージ名を付けてビルド

docker-compose upのビルドではデフォルトでimage名が「docker-compose.ymlが置かれているディレクトリ名」+「サービス名」となります。

$docker images

REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
workdir_shell              latest              b105f5750fb8        2 days ago          1.095 MB

imageに任意の名前をつけるには以下のようにimageキーを記述します。buildキーが存在する場合には、このimageキーはイメージ名付与として働きます。

version: '2'
services:
    shell:
        build: .
    image: busybox-test

docker-compose upを実行して確認すると指定した名前になっているのが確認できます。

$docker images

REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
busybox-test              latest              b105f5750fb8        2 days ago          1.095 MB

dockerfileのファイル名指定

もし何かの理由で「dockerfile」から任意の名前に変えていた場合(複数のdockerfileが同じ階層に存在するなど)はファイル名を指定してビルドすることもできます。

例えば以下のような構成の場合、

/home/workdir
    dockerfile
    testdockerfile
    dokcer-compose.yml

以下のようにしてdockerfileを指定してビルドできます。

version: '2'
services:
    shell:
        build: .
            dockerfile: testdockerfile
        image: busybox-test

コンテキスト指定

またディレクトリのコンテキストを指定することも可能です。絶対指定も行えますが、可搬性を考えると相対指定の方が良いかと思います。

例えば以下のような構成の場合、

/home/workdir
  buildfiles/
        dockerfile
        testdockerfile
    dokcer-compose.yml

以下のようにしてコンテキストを指定することができます。

version: '2'
services:
    shell:
        build:    
        context: ./buildfiles
            dockerfile: testdockerfile
        image: busybox-test

以下でも同じ意味になりますが、contextではGitHubなどのURLの指定も行えるため、contextを使ったほうがより柔軟な記述が可能です。

version: '2'
services:
    shell:
        build: ./buildfiles
            dockerfile: testdockerfile
        image: busybox-test

GitHubなどからの取得

contextにはGitHub等のURLも指定可能です。

以下はGitHubにあるdocker/composeリポジトリを指定してimageをビルドすることになります。

version: '2'
services:
    test:
        build:    
        context: https://github.com/docker/compose.git
        image: compose-test

ただし、リポジトリのルートディレクトリ直下にDockerfileが存在していないと、composeはDockerfileを探すことができません。

Dockerfileがリポジトリのルートディレクトリ直下にないリポジトリの場合は以下のようにエラーが出て(–vervoseオプション使用時)終了してしまいます。

ERROR: compose.cli.errors.log_api_error: Cannot locate specified Dockerfile: Dockerfile

※リポジトリのルートディレクトリ直下にDockerfileが無い場合、リポジトリのTree構造(Dockerfileの場所)をどのようにyml内で指定するのかは調査不足で判明していません。

さまざまなオプション

docker runで指定するオプションとdocker-compose.ymlで指定するコマンドの対応は以下です。

※runで使用できるオプションすべてを利用できるかどうかが不明な場合もありました。ソースコードを確認しつつ表を作りましたが調査が不十分で間違っている場合がありますのでご注意ください。

キー 相当するdocker runオプション 機能
cap_add –cap-add Linuxケーパビリティの追加
cap_drop –cap-drop Linuxケーパビリティの削除
command runコマンド末尾のコマンド指定に相当 コマンドの指定
cpu_shares -c –cpu-shares cpu共有ウエイトの設定
cpuset –cpuset-cpus cpuコアの割当
devices −−devices 特権が無いコンテナ内でもデバイスの実行を許可
dns –dns DNSの設定
dns_search –dns-search DNSの検索ドメイン
domainname –hostnameに相当 ドメイン名の設定
entrypoint –entrypoint entrypointの設定
env_file -eに相当? 環境変数のファイル指定
environment -e 環境変数のバインド
expose -P –expose 露出ポートの指定
extra_hosts –add-host /ext/hostsへのホスト名の書き込み
hostname –hostname ホスト名の設定
image runコマンド末尾のイメージ指定に相当 イメージ指定
ipc –ipc IPC名前空間設定
labels –label ラベル
links –link コンテナのリンク設定
log_driver –log_driverに相当? ログサービスを指定
logging –log-driverに相当? ログのON/OFF
mac_address –mac-address MACアドレスの設定
mem_limit –memory メモリ設定
memswap_limit –memory-swap メモリスワップの設定
name_container –name コンテナ名
network_mode –net ネットワークモードの設定
pid –pid pidの設定
ports -p ポートのバインド
privileged –privileged コンテナに拡張権限を与える
read_only -vオプションでのroに相当? 読み込み専用
restart –restart コンテナの再起動ポリシー
stdin_open −i 標準入力
tmpfs –tmpfs 一時ファイルシステムの設定
tty −t 端末の付与
user -u ユーザ指定
volume -v ボリュームの指定
volume_driver -vに相当? ボリュームドライバの指定
volumes_from –volumes_from ボリュームコンテナのバインド
working_dir -w 作業ディレクトリの指定
? –blkio-weight ブロック I/O ウエイト設定
? –cgroup-parent cgroup設定
? –cpu-period CPU CFSのピリオドの上限
? –cpu-quota CPU CFSのクォータ設定
? –cpuset-mems 実行するメモリノードの割り当て
? –group-add グループの追加
? –health-interval チェックを実行する間隔
? –health-retries 障害を報告するまでに必要な連続失敗回数
? –health-timeout チェックを実行できる最長時間
? –kernel-memory カーネルメモリの設定
? –lxc-conf カスタムlxc オプションの追加
? –memory-reservation メモリのソフトリミット
? –memory-swappiness メモリのスワップ度合いの調整
? –no-healthcheck コンテナ固有のヘルスチェックを無効化
? –oom-kill-disable oomkillerのon/off
? –rm コンテナの削除
? –security-opt セキュリティ設定
? –uts UTS名前空間モード設定

具体例

いくつか基本的な例を挙げていきたいと思います。

ポートの開放およびバインド

以下の様なdocker runコマンドをcomposeで再現してみます。

$ docker run -it -p 10022:22 busybox

ymlファイルは以下のようになります。

version: '2'
services:
    test:
        image: busybox
        ports:
            - "10022:22"
        tty: true
        stdin_open: true

upしてみます。(ttyと標準入力をtrueにしていますが、前述したとおりインタラクティブにはならず、待機状態になります)

$ docker-compose up
Recreating workdir_shell_1
Attaching to workdir_test_1

PORTSに開放しバインドしたポートが確認できます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                   NAMES
a53b48665e45        busybox             "sh"                10 seconds ago      Up 8 seconds        0.0.0.0:10022->22/tcp   workdir_test_1

コマンドの実行

以下の様なdocker runコマンドをcomposeで再現してみます。

$ docker run -it busybox sleep 100

ymlファイルは以下のようになります。

version: '2'
services:
    test:
        image: busybox
        command: sleep 100
        tty: true
        stdin_open: true

upしてみます。(ttyと標準入力をtrueにしていますが、前述したとおりインタラクティブにはならず、待機状態になります)

$ docker-compose up
Recreating workdir_shell_1
Attaching to workdir_test_1

COMMANDがもともとbusyboxのDockerfileに指定されているshからsleep 100に上書きされました。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3c1475d4e54f        busybox             "sleep 100"         11 seconds ago      Up 7 seconds                            workdir_test_1

コンテナの連携

DockerComposeの真価が発揮できるのがコンテナの連携です。複数のコンテナの設定を記述することができます。

以下の様なdocker runコマンドをymlに記述していきたいと思います。

以下は公式のMySQL、WordPressイメージを使ってWordPress環境を立ち上げるコマンドです。テーマファイルを分離できるよう、ボリュームコンテナを作成してバインドしています。

WordPressはデータベースが必要になるため、コマンドラインからrunする場合は、先にデータベースコンテナを作っておく必要があります。

$ docker create --name themesdate -v /your/dir:/var/www/html/wp-content/themes/ busybox 

$ docker run --name wpdb --restart=always  -e MYSQL_ROOT_PASSWORD=pass -e MYSQL_DATABASE=db mysql:latest

$ docker run --name wps -p 8000:80 --link db:mysql --volumes-from themesdate --restart=always  -e WORDPRESS_DB_HOST=$WPDB_PORT_3306_TCP_ADDR -e WORDPRESS_DB_PASSWORD=$WPDB_MYSQL_ROOT_PASSWORD wordpress

ymlに記述すると以下のようになります。

version: '2'
services:

  volume:
    image: busybox
    container_name: themesdata
    volumes:
      - "/your/dir:/var/www/html/wp-content/themes/"

  datebase:
    image: mysql:5.7
    container_name: db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: pass
      MYSQL_DATABASE: db

  wordpress:
    depends_on:
      - datebase
    image: wordpress:latest
    container_name: wp
    volumes_from:
          - volume
    links:
      - database
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: database:3306
      WORDPRESS_DB_PASSWORD: pass

この例では

  • ボリュームのバインド volumes:
  • ボリュームコンテナのバインド volumes-from:
  • ポートの開放とバインド ports:
  • link設定 links:
  • コンテナ名 container_name:
  • 環境変数の指定 environment:
  • 依存関係の指定 depends_on:
  • 再起動ポリシーの設定 restart:

が実現できています。

サービス名とコンテナ名に注意

ボリュームコンテナのバインドやlink設定、依存関係の設定の場合、指定するのは「サービス名」です。コンテナ名ではありません。

以下は誤りになります。

volumes_from:
          - themesdata

しかしvolumes_fromではコンテナ名を指定したい場合、以下の様にすることができます。

volumes_from:
          - container:themesdata

今回はコンテナ名も記述しましたが、意外と混乱してしまうので、サービス名とコンテナ名はちゃんと見分けられるように付けたほうがいいでしょう。

docker-compose upすると大量にログが出力されます。今回は3つのコンテナが連携することになりますが、それぞれの出力は一つにまとまります。

どのコンテナのログかは行の最初にコンテナ名が付きますので識別できます

以下は出力の抜粋です。

$ docker-compose up

~~~~
~~~~
~~~~
wpdb         | 2017-01-11T06:05:28.227391Z 0 [Note] Event Scheduler: Loaded 0 events
wpdb         | 2017-01-11T06:05:28.227470Z 0 [Note] Executing 'SELECT * FROM INFORMATION_SCHEMA.TABLES;' to get a list of tables using the deprecated partition engine. You may use the startup option '--disable-partition-engine-check' to skip this check. 
wpdb         | 2017-01-11T06:05:28.227476Z 0 [Note] Beginning of list of non-natively partitioned tables
wpdb         | 2017-01-11T06:05:28.233052Z 0 [Note] End of list of non-natively partitioned tables
wpdb         | 2017-01-11T06:05:28.233156Z 0 [Note] mysqld: ready for connections.
wpdb         | Version: '5.7.17'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
wp           | Complete! WordPress has been successfully copied to /var/www/html
wp           | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.19.0.2. Set the 'ServerName' directive globally to suppress this message
wp           | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.19.0.2. Set the 'ServerName' directive globally to suppress this message
wp           | [Wed Jan 11 06:05:30.960373 2017] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.10 (Debian) PHP/5.6.29 configured -- resuming normal operations
wp           | [Wed Jan 11 06:05:30.960393 2017] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

読んでいくと最後にapache2 -D FOREGROUNDが実行されWordPress環境が構築されたことがわかります。

補足・ハマったポイント

depends_onについて

依存関係を記述するdepends_onですが、コンテナ作成開始までは待ってくれるのですが、コンテナ内部の準備が整うのを待ってくれるわけではありません。

例えば先ほどのWordPress環境で説明すると、WordPressコンテナはMySQLコンテナが作られるまでは作られません。

しかしMySQLコンテナが作られて、内部でデータベースやユーザ関係の処理が行われデータベースとして使える状態になるまでは待ちません。

ですので場合によってはMySQLコンテナの準備が間に合わず、WordPressコンテナがMySQLコンテナにアクセスしようとしても不能になる可能性もあります。

幸い公式のWordPressイメージでは接続試行を複数回(たしか20回)おこなってくれますので、そのうちにMySQLコンテナの準備が整えば接続できるようになります。

このように、コンテナを連携させる時は、「コンテナの準備の時間」が重要になってくる場合があります。

ほとんどの場合で試行回数などで対応できるかと思いますが、この辺は自作のDockerfileの場合、いろいろ弄くる必要のある箇所かもしれません。

まとめ

随分長い記事になってしまいましたが、どうにかDockerComposeの基本的なことはお伝えできたのではと思います。

それにしてもコマンドラインで長いrunコマンドを泣く泣く打っていたことを考えるととてもラクですね。

これでdockerfileで環境を管理し、立ち上げをdocker-compose.ymlで管理するという可搬性の高い状態になりますね。

本当に便利になったものです。