sioaji2012のブログ

普段は組み込み開発でC言語のみです。主にプログラムや勉強日記です

Docker お勉強 04 Docker Compose

もくもくで使わせてもらっている docker-compose.yml が何なのかわからないので調べます。 下記ページを読みながら、覚え書きを記載していきます。

DockerCompose

・Dockerツール群の一つであるDockerComposeを使うと、コンテナ立ち上げ設定をファイル化(yml形式)して管理することが可能になります。
・docker-compose で起動する場合は、Dockerfileを使ってイメージ作成します。

.yml →YAMLファイル →ヤムルファイル

  • データ構造を記述するフォーマットの一つ
  • jsonのスーパーセット(上位互換みたいな感じ)だそう
  • json形式でもymlとして認識してくれるらしい
  • DockerComposeではこのyml形式ファイルを使って、コンテナ起動に関してを記述していきます。
    docker-compose.yml

version:   バージョン番号

Compose file versions and upgrading

現在の最新は '3'

version: '3'

services:   各コンテナに関しての記述を行っていく

services:
  web_co:
  • services構造直下に各コンテナに関しての記述を行っていく。
    次の構造(キー)としては各サービス名となる。(上記:web_co)
  • 立ち上げるコンテナごとに記述内容が異なるはずですので、区分して記述するために構造を分割します。
  • 任意の名前でOK
  • この名前がコンテナの名前になるわけではありません。

build:   構築時に適用するオプションを指定

build で指定できるのは、
・構築用コンテクストのパスを含む文字列
・context の配下にある特定の物(オブジェクト)
・dockerfile のオプション、 引数
build: ./dir

build:
  context: ./dir
  dockerfile: Dockerfile-alternate
  args:
    buildno: 1

【もくもく例】

    build:
      context: .
      args:
        REDMINE_VERSION: $REDMINE_VERSION

context:   Dockerfile があるパスや Git URLを指定

・Dockerfile があるディレクトリのパスや Git リポジトリの URL を指定します。
・値に相対パスを指定したら、Compose ファイルのある場所を基準とした相対パスとして解釈します。
・指定したディレクトリが構築コンテクストとなり、Docker デーモンに送信します。
・Compose は生成時の名前で構築・タグ付けし、それがイメージとなります。
build:
  context: ./dir

【もくもく例】

    build:
      context: .

args:   build のオプション(args)

・構築時に build のオプション(args)を追加します。
・配列でも辞書形式(「foo=bar」の形式)も指定できます。
・ブール演算子(true、false、yes、no)を使う場合はクォートで囲む必要があります。
 そうしないと YAML パーサは True か False か判別できません。
・構築時に引数のキーとして解釈する環境変数の値は、Compose を実行するマシン上のみです。
build:
  args:
    buildno: 1
    user: someuser

build:
  args:
    - buildno=1
    - user=someuser

【もくもく例】

    build:
      args:
        REDMINE_VERSION: $REDMINE_VERSION

image:   コンテナの作成元イメージを指定する

・コンテナを実行時に元となるイメージを指定します。
・リポジトリ名・タグあるいはイメージ ID の一部を指定できます。
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
  • すでに存在するimageを探してくれます。
    docker runの時と同じ様にまずローカルのimageから検索して、なければDockerHubからの取得を試みてくれます。
  • イメージが存在していなければ、Compose は pull (取得)を試みます。
    しかし build を指定している場合は除きます。その場合、指定されたタグやオプションを使って構築します。

【もくもく例】

  web_co:
    build:
      context: .
      args:
        REDMINE_VERSION: $REDMINE_VERSION
    image: redmine_co_sqlite3

command:   デフォルトのコマンドを上書きする

デフォルトのコマンドを上書きします。
command: bundle exec thin -p 3000
  • これは Dockerfile の書き方に似せることもできます。
command: [bundle, exec, thin, -p, 3000]

【もくもく例】

    command: >
      bash -c "bundle exec rake redmine:plugins:migrate &&
           bundle exec rails s -p 3000 -b '0.0.0.0'"


⬇Dockerfile側は、こう書いてある⬇

CMD bundle exec rails s -p 3000 -b '0.0.0.0'

(docker run だとプラグインなしでRedmine起動。composeはプラグインつき起動)

environment:   環境変数を追加する

・環境変数を追加します。
・配列もしくは辞書形式(dictionary)で指定できます。
・boolean 値 (true、false、yes、no のいずれか) は、
 YMLパーサによって True や False に変換されないよう、クォートで囲む必要があります。
・キーだけの環境変数は、Compose の実行時にマシン上で指定するものであり、
 シークレット(API鍵などの秘密情報)やホスト固有の値を指定するのに便利です。
environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET

【もくもく例】

    environment:
      RAILS_ENV: development

volumes:   コンテナ内にマウントするボリュームを指定する

マウント・パスまたは名前を付けたボリュームは、
・オプションでホストマシン上のパス指定 →( ホスト:コンテナ )
・アクセス・モード →( ホスト:コンテナ:rw )
を指定できます。 

・ホスト上の相対パスをマウント可能です。
・相対パスは Compose 設定ファイルが使っているディレクトリを基準とします。
・相対パスは . または .. で始まります。
volumes:
  # パスを指定したら、Engine はボリュームを作成
  - /var/lib/mysql

  # 絶対パスを指定しての割り当て
  - /opt/data:/var/lib/mysql

  # ホスト上のパスを指定する時、Compose ファイルからのパスを指定
  - ./cache:/tmp/cache

  # ユーザの相対パスを使用
  - ~/configs:/etc/configs/:ro

  # 名前付きボリューム(Named volume)
  - datavolume:/var/lib/mysql

ホスト側のパスを指定せず、 volume_driver を指定したい場合があるかもしれません。

使用するボリュームドライバを指定する
volume_driver: mydriver

【もくもく例】

    volumes:
      - .:/tmp/redmine_co/plugins/redmine_issue_badge

( ホスト:コンテナ )

ports:   公開用のポートを指定する

・公開用のポートです。
・ホスト側とコンテナ側の両方のポートを指定 →( ホスト側:コンテナ側 )
・コンテナ側のポートのみも指定できます(ホスト側はランダムなポートが選ばれます)。

注釈
* ホスト側:コンテナ側 の書式でポートを割り当てる時、コンテナのポートが 60 以下でエラーが発生します。
これは YAML が xx:yy 形式の指定を、60 進数(60が基準)の数値とみなすからです。
そのため、ポートの割り当てには常に文字列として指定することを推奨します。

ports:
 - "3000"
 - "3000-3005"
 - "8000:8000"
 - "9090-9091:8080-8081"
 - "49100:22"
 - "127.0.0.1:8001:8001"
 - "127.0.0.1:5000-5010:5000-5010"

【もくもく例】

    ports:
      - "3000:3000"

実行オプション docker-compose build

【もくもく例】

 REDMINE_VERSION=master docker-compose build --force-rm --no-cache

rm:   停止済みのサービス・コンテナを削除する

使い方: rm [オプション] [サービス...]

オプション:
    -f, --force   確認なく削除する
    -v            コンテナにアタッチしているアノニマス・ボリュームも削除
    -a, --all     docker-compose run で作成した一度だけのコンテナを全て削除
                  docker-compose run
デフォルトでは、コンテナにアタッチしている匿名ボリューム(anonymous volume)を削除しません。
ボリュームを削除するには -v オプションを使います。
全てのボリュームを表示するには docker volume ls を使います。
(明示的に削除しなければ)ボリューム内にあるデータは失われません。

build:   構築する

使い方: build [オプション] [サービス...]

オプション:
--force-rm  常に中間コンテナを削除
--no-cache  構築時にイメージのキャッシュを使わない
--pull      常に新しいバージョンのイメージ取得を試みる
  • サービスは プロジェクト名_サービス として構築時にタグ付けられます。 例: composetest_db 。
  • サービスの Dockerfile や構築ディレクトリの内容に変更を加える場合は、 docker-compose build で再構築を実行します。

実行オプション docker-compose up

【もくもく例】

docker-compose up -d

up:   サービス用のコンテナの構築、作成、起動、アタッチを行う

使い方: up [オプション] [サービス...]

オプション:
    -d                         デタッチド・モード: バックグラウンドでコンテナを実行し、新しいコンテナ名を表示
                               --abort-on-container-exit と同時に使えない
    --no-color                 白黒で画面に表示
    --no-deps                  リンクしたサービスを表示しない
    --force-recreate           設定やイメージに変更がなくても、コンテナを再作成する
                               --no-recreate と同時に使えません
    --no-recreate              コンテナが既に存在していれば、再作成しない
                               --force-recreate と同時に使えない
    --no-build                 イメージが見つからなくても構築しない
    --build                    コンテナを開始前にイメージを構築する
    --abort-on-container-exit  コンテナが1つでも停止したら全てのコンテナを停止
                               -d と同時に使えない
    -t, --timeout TIMEOUT      アタッチしている、あるいは既に実行中のコンテナを
                               停止する時のタイムアウト秒数を指定 (デフォルト:10 )
    --remove-orphans           Compose ファイルで定義されていないサービス用のコンテナを削除
  • 既に実行している場合は、このコマンドによってリンクされているサービスも起動します。
  • docker-compose up コマンドは各コンテナの出力を統合します。
  • コマンドを終了(exit)すると、全てのコンテナを停止します。
  • docker-compose up -d で実行すると、コンテナをバックグラウンドで起動し、実行し続けます。
  • もしサービス用のコンテナが存在している場合、かつ、コンテナを作成後にサービスの設定やイメージを変更している場合は、 docker-compose up -d を実行すると、 設定を反映するためにコンテナを停止・再作成します(マウントしているボリュームは、そのまま保持します)。
  • Compose が設定を反映させないようにするには、 --no-recreate フラグを使います。
  • Compose で処理時、強制的に全てのコンテナを停止・再作成するには --force-recreate フラグを使います。

ひとまず、ここまで。

【もくもくのdocker-compose.yml】

version: '3'
services:
  # start service for redmine with plugin
  # 1. $ docker-compose build --force-rm --no-cache
  # 2. $ docker-compose up -d
  #
  # If you want to change Redmine's version,
  #
  # 1. $ REDMINE_VERSION=master docker-compose build --force-rm --no-cache
  # 2. $ docker-compose up -d
  #
  #
  web_co:
    build:
      context: .
      args:
        REDMINE_VERSION: $REDMINE_VERSION
    image: redmine_co_sqlite3
    container_name: redmine_co_sqlite3
    command: >
      bash -c "bundle exec rake redmine:plugins:migrate &&
           bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      RAILS_ENV: development
    volumes:
      - .:/tmp/redmine_co/plugins/redmine_issue_badge
    ports:
      - "3000:3000"