docker
docker-compose
winodws10

WindowsでDocker Composeを使ってマルチコンテナ環境を作ってみる

概要

Windows10にDocker環境を構築したのでいろいろ試してみた
今回はWEBサーバ/APサーバ/DBサーバなど一度に複数のコンテナが必要になるWebシステム等の構築時に使用するコンテナ構成情報一元管理ツール「Docker Compose」
「Docker Compose」のコンテナ構成情報を定義するdocker-compose.ymlの書き方とそのまとめ

Dockerとdocker-compose.ymlの関連は以下を参照

 Dockerの基本機能と全体像のイメージを整理してみる

動作環境とDocker環境構築方法は以下を参照

  • Windows 10 Pro 64bit
  • Docker for Windows

 WindowsでDocker環境を試してみる

「Docker Compose」はDocker for Windowsのインストールで同時にインストールされる

およその作業時間

1時間

使用コマンド一覧

docker run --link 接続したいコンテナ名:エイリアス名 イメージ名 実行コマンド
docker-compose up
docker-compose scale コンテナ名=数
docker-compose ps
docker-compose logs
docker-compose run コンテナ名 実行コマンド
docker-compose start
docker-compose stop
docker-compose restart
docker-compose kill
docker-compose rm

docker-compose.yml定義一覧

image イメージ名
build ファイルパス
command 実行コマンド
links/external_links コンテナ名:エイリアス名
ports/expose "ポート番号"
volumes マウントポイント
volumes_from マウント先のコンテナ名
environment 環境変数名=値
container_name コンテナ名
labels ラベル内容

YAML形式の基本的なdocker-compose.ymlの書き方

  • インデント(半角スペース)でデータ階層構造を表す
  • #はコメントになる
  • 配列を使用するときは先頭「- 」(ハイフンと半角スペース)に続き定義内容を記載する
  • インデントなしの行の先頭に定義するコンテナの種類ごとにコンテナ名を指定する

image イメージ名

ベースイメージを指定する
dockerコマンド等と同様 : に続きタグ指定も可能(タグの省略で最新イメージの指定となる)

docker-compose.yml
testserver:
 image: ubuntu

testserverが生成するコンテナ名

build ファイルパス

イメージ作成にDockerfileを使用する場合は、buildに続きDockerfileが置かれているファイルパスを指定する

docker-compose.yml
testserver:
 build: .

docker-compose.ymlファイルでは、image/buildのいずれかの指定が必要
build(Dockerfile)を使用する場合は、一度イメージを作成しコンテナを作成することになる

command 実行コマンド

コマンド実行を行う場合はコマンドを指定する
DockerfileにCMD指定がある場合は上書きされる

docker-compose.yml
testserver:
 image: ubuntu

 command: /bin/bash

links/external_links コンテナ名:エイリアス名

指定したコンテナに対し容易にアクセス可能なように環境変数にIPアドレスなどを自動的に設定して、コンテナ名やエイリアス名でアクセスできるようになる機能(リンク機能)

docker-compose.yml
testserver:
 image: ubuntu

 links:
  - dbserver:mysql

links指定は同一のdocker-compose.ymlに定義があるコンテナのみ指定可能であることに対し、external_linksは外部の別のコンテナとリンク機能を使って連携するときに指定する
docker-compose.ymlを使用しない場合は、以下のコマンドでdocker run時にもリンク機能の指定が可能

docker run --link 接続したいコンテナ名:エイリアス名 イメージ名 実行コマンド

引数で指定したコンテナに対し環境変数に自動的に設定してくれる
ただし、同一ホストマシン上で起動しているコンテナ間でしか、アクセスできないという制限がある

ports/expose "ポート番号"

コンテナの公開するポート指定に使用する
「ホストマシンのポート番号:コンテナのポート番号」の形式でホストマシンのポートを明示的に指定することもできるが、記載がなければランダムなポートが使用される
必ず""(ダブルクォート)で囲む必要がある

docker-compose.yml
testserver:
 image: ubuntu

 ports:
  - "80:80"

ホストマシンには公開せず、リンク機能を使って連携するコンテナにのみポートを公開する場合は、expose指定となる
その場合は、ホストマシンのポート番号は省略する

docker-compose.yml
testserver:
 image: ubuntu

 expose:
  - "8000"

volumes マウントポイント

ボリュームをマウントする場合に使用する
ホスト側でマウントするパスを指定する場合は、「ホストマシンのフォルダパス:コンテナのフォルダパス」の形式で指定する

docker-compose.yml
testserver:
 image: ubuntu

 volumes:
  - /var/lib/mysql

volumes_from マウント先のコンテナ名

特定のコンテナに対しボリュームをマウントする場合に使用する

docker-compose.yml
testserver:
 image: ubuntu

 volumes_from:
  - dataserver

environment 環境変数名=値

環境変数を指定する場合に使用する

docker-compose.yml
testserver:
 image: ubuntu

 environment:
  - HOGE=hoge

container_name コンテナ名

生成されるコンテナに名前を付けるときに使用する

docker-compose.yml
testserver:
 image: ubuntu

 container_name: webserver

labels ラベル内容

コンテナにラベルを付けるときに使用する

docker-compose.yml
testserver:
 image: ubuntu

 labels:
  - "description=testserver"

docker-compose.ymlを使いコンテナ生成を行うdocker-composeコマンド

docker-compose up

docker-compose.ymlを使って複数のコンテナの生成/起動を行う

-f でdocker-compose.ymlのファイル指定が可能
-f がなければカレントにあるdocker-compose.ymlを使う
-d でバックグラウンド起動する

> docker-compose -f webdb-docker-compose.yml up -d
Creating wordpress_dbserver_1 ...
Creating wordpress_dbserver_1 ... done
Creating wordpress_webserver_1 ...
Creating wordpress_webserver_1 ... done
webdb-docker-compose.yml
webserver:
 image: wordpress
 ports:
  - "80:80"
 links:
  - dbserver:mysql

dbserver:
 image: mysql
 environment:
  MYSQL_ROOT_PASSWORD: password

コンテナ起動を確認

> docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                NAMES
d9c5c3b521a5        wordpress           "docker-entrypoint..."   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp   wordpress_webserver_1
f02a94dcee33        mysql               "docker-entrypoint..."   About a minute ago   Up About a minute   3306/tcp             wordpress_dbserver_1

コンテナ名は正確には「実行フォルダ_docker-compose.ymlのコンテナ名_通番」なるらしい
そのためdocker-compose.yml記載のコンテナ名はサービス名と言われる

docker-compose scale コンテナ名=数

起動コンテナ数を指定する時に使用する

> docker-compose scale webserver=1 dbserver=2
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Creating wordpress_webserver_1 ...
Creating wordpress_webserver_1 ... done
Creating wordpress_dbserver_1 ...
Creating wordpress_dbserver_2 ...
Creating wordpress_dbserver_1 ... done
Creating wordpress_dbserver_2 ... done

複数起動時に矛盾が発生する場合はエラーが発生する
例えばwebserverを2つ起動する場合は80ポートが競合する、、、

> docker-compose scale webserver=2 dbserver=1
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
WARNING: The "webserver" service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash.
Creating wordpress_webserver_1 ...
Creating wordpress_webserver_2 ...
Creating wordpress_webserver_1 ... error
Creating wordpress_webserver_2 ... done

ERROR: for wordpress_webserver_1  Cannot start service webserver: driver failed programming external connectivity on endpoint wordpress_webserver_1 (e1a6f29e4ec9f31c40b5470cf9109c98765c5a7e03a10013758063beb54b8436): Bind for 0.0.0.0:80 failed: port is already allocated
ERROR: Cannot start service webserver: driver failed programming external connectivity on endpoint wordpress_webserver_1 (e1a6f29e4ec9f31c40b5470cf9109c98765c5a7e03a10013758063beb54b8436): Bind for 0.0.0.0:80 failed: port is already allocated

docker-compose ps

複数コンテナの一覧表示を行う
docker psコマンドと比較すると気持ちシンプル表示になっている?

> docker-compose ps
        Name                       Command               State         Ports
-----------------------------------------------------------------------------------
wordpress_dbserver_1    docker-entrypoint.sh mysqld      Up      3306/tcp
wordpress_dbserver_2    docker-entrypoint.sh mysqld      Up      3306/tcp
wordpress_webserver_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:80->80/tcp

> docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
d9f2dec9af02        mysql               "docker-entrypoint..."   5 minutes ago       Up 5 minutes        3306/tcp             wordpress_dbserver_1
cde58d78dc3d        mysql               "docker-entrypoint..."   5 minutes ago       Up 5 minutes        3306/tcp             wordpress_dbserver_2
816fcbe2c4f7        wordpress           "docker-entrypoint..."   5 minutes ago       Up 5 minutes        0.0.0.0:80->80/tcp   wordpress_webserver_1

docker-compose logs

コンテナのログを確認する場合に使用する
コンテナごとのログが表示される

> docker-compose logs
Attaching to wordpress_dbserver_1, wordpress_dbserver_2, wordpress_webserver_1
webserver_1  | WordPress not found in /var/www/html - copying now...
webserver_1  | Complete! WordPress has been successfully copied to /var/www/html
dbserver_1   | Initializing database
webserver_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
dbserver_2   | Initializing database
dbserver_1   | 2018-01-27T02:09:56.866053Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
webserver_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
dbserver_2   | 2018-01-27T02:09:56.887342Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
~~~省略~~~

docker-compose run コンテナ名 実行コマンド

起動したコンテナに新たにコマンドを実行する場合に使用する
runのあとにコンテナ名を指定すると指定したコンテナだけの操作となる(他のコマンドでも同様)
コンテナ内でコマンド実行したい場合など/bin/bashを実行する

> docker-compose run webserver /bin/bash
Starting wordpress_dbserver_1 ... done
Starting wordpress_dbserver_2 ... done
root@8271d38f7036:/var/www/html#

docker-compose start

複数のコンテナを一括で起動する場合に使用する

> docker-compose start
Starting dbserver  ... done
Starting webserver ... done

> docker-compose ps
        Name                       Command               State         Ports
-----------------------------------------------------------------------------------
wordpress_dbserver_1    docker-entrypoint.sh mysqld      Up      3306/tcp
wordpress_dbserver_2    docker-entrypoint.sh mysqld      Up      3306/tcp
wordpress_webserver_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:80->80/tcp

docker-compose stop

複数のコンテナを一括で停止する場合に使用する

> docker-compose stop
Stopping wordpress_dbserver_1  ... done
Stopping wordpress_dbserver_2  ... done
Stopping wordpress_webserver_1 ... done

docker-compose restart

複数のコンテナを一括で再起動する場合に使用する

> docker-compose restart
Restarting wordpress_dbserver_1  ... done
Restarting wordpress_dbserver_2  ... done
Restarting wordpress_webserver_1 ... done

docker-compose kill

複数のコンテナを一括で強制停止する場合に使用する

> docker-compose kill
Killing wordpress_dbserver_1  ... done
Killing wordpress_dbserver_2  ... done
Killing wordpress_webserver_1 ... done

> docker-compose ps
        Name                       Command                State     Ports
-------------------------------------------------------------------------
wordpress_dbserver_1    docker-entrypoint.sh mysqld      Exit 137
wordpress_dbserver_2    docker-entrypoint.sh mysqld      Exit 137
wordpress_webserver_1   docker-entrypoint.sh apach ...   Exit 137

docker-compose rm

複数のコンテナを一括で削除する場合に使用する

> docker-compose rm
Going to remove wordpress_dbserver_1, wordpress_dbserver_2, wordpress_webserver_1
Are you sure? [yN] y
Removing wordpress_dbserver_1      ... done
Removing wordpress_dbserver_2      ... done
Removing wordpress_webserver_1     ... done

参考

プログラマのためのDocker教科書 第6章

わかりやすくてDockerの入門書的な良本です^^
みんな購入していて売れ行き好調なのか第2版が発売されていたのでリンク更新