Docker Composeは複数のDockerコンテナをまとめて立ち上げることができる便利なツールである。
いくつかのケースについて実例をあげながら設定方法を記載していこうと思う。
別docker-composeのコンテナを参照する
1つ目のdocker-composeでDBを、2つ目のdocker-composeでWebアプリを立ち上げて、WebアプリからDBを参照するケースを考える。
基本的には、network
で同一ネットワークに所属するように設定し、external_links
で外部コンテナにアクセスできるように設定すればよい。
DB用docker-compose.ymlの設定
version: '3'
services:
postgres:
image: postgres:latest
container_name: "database"
- このコンテナが所属するネットワーク名は、デフォルトで
${ディレクトリ名}_default
になる。今回のケースではdatabase_default
になる。-
database_default
という名前が気持ち悪ければ、networks
設定を行なってもいい。
-
- 今回はdockerネットワーク外からアクセスしてないので、
ports
設定は行なっていない。
Webアプリ用docker-compose.ymlの設定
version: '3'
services:
web:
build: .
image: web-application
container_name: "web-application"
ports:
- "8080:8080"
environment:
- DATABASE_URL=jdbc:postgresql://database:5432/research # DBのURL
external_links:
- database # 参照先コンテナ名を指定。エイリアスもつけられる
networks:
- database_default
networks:
database_default:
external: true
- databaseコンテナと同じネットワークに所属させる必要がある。
- databaseコンテナが所属するネットワーク名は
docker network ls
でも確認できる。
- databaseコンテナが所属するネットワーク名は
-
external_links
を設定することで、別Docker Composeで立ち上げたdatabase
コンテナに到達可能になっている。 -
environment
の設定で、DBのURLを環境変数に設定しているが、ホスト名がexternal_linksで指定したコンテナ名database
になっていることに注意。 -
Dockerfile
の作成も必要だが今回は省略。
実行
DB側のフォルダで
docker-compose up
Webアプリ側のフォルダで
docker-compose up --build
同一Docker Compose内で別コンテナ(サービス)を立ち上げる
同一Docker Compose内でWebアプリとキャッシュサーバを立ち上げるケースを考える。
通常は特に何も考えず定義すればOK。
docker-compose.ymlの設定
version: '3'
services:
web:
build: .
image: web-application
ports:
- "8080:8080"
memcached:
image: memcached:latest
- 同一ネットワークに所属させる必要があるが、何も指定しなければデフォルトで同一ネットワークになるため特に設定は必要なし。
-
external_links
を使うために、webコンテナをdatabase_default
に所属させたりしていると、memcachedコンテナも明示的に同じnetworkに所属させる必要があるので要注意。
実行
docker-compose up --build
外部APIを呼び出す
Docker Composeで立ち上げたWebアプリから、Dockerネットワーク外のAPIを呼び出すことを考える。
本当に外部APIを呼び出すパターンと、ホストマシン(localhost)で動かしているAPIを呼び出すパターンの2パターンを検証した。
外部APIはextra_hosts
の設定が必要で、ホストマシン上のAPIにはhost.docker.internal
でアクセスできる。
dockder-compose.ymlの設定
version: '3'
services:
web:
build: .
image: web-application
container_name: "web-application"
ports:
- "8080:8080"
environment:
- EXTERNAL_API_BASE=https://hoge.com/ # 外部APIのベースURL
- INTERNAL_API_BASE=http://host.docker.internal:8081/fuga # ホストマシン上APIのベースURL
extra_hosts:
- "hoge.com:11.22.33.44"
-
extra_hosts
に設定した内容が、コンテナ起動時に/etc/hosts
に書き込まれる。 - アプリケーション内では、
EXTERNAL_API_URL
とINTERNAL_API_URL
の二つの環境変数を読み込んで利用する。
docker-compose.yml内で動的に変数置き換えする
今回は、20190512
の様な文字列を実行時に動的に取得して、コンテナ内でWORK_DIR
環境変数として利用するケースを考える。
結論としては、docker-compose実行時の環境変数を設定するしかない。
公式ドキュメントはこちら
dockder-compose.ymlの設定
version: '3'
services:
web:
build: .
image: web-application
container_name: "web-application"
ports:
- "8080:8080"
environment:
- WORK_DIR=${TODAY}
- docker-compose.yml内で変数置き換えできるのは以下の二つ。
- env_file(デフォルトだと
.env
)で指定した環境変数 - docker-compose実行時の環境変数
- env_file(デフォルトだと
- env_fileは静的な値しか設定できないので、今回は動的に値を設定できるdocker-compose実行時の環境変数を利用した。
実行
TODAY
環境変数をシェルで設定してから、docker-compose up
を実行する。
export TODAY=$(date "+%Y%m%d")
docker-compose up --build
その他Tips
- Dockerイメージの名称はDocker Daemon上でユニークにする必要がある。なので
web
とかユニーク性が低い言葉は使わない方が良い。 - docker-compose.ymlの変更が反映されてない気がするときは、とりあえず
docker-compose down
を試してみる。 - WEBアプリをローカル環境で開発するときの構成はこんな感じがいいと思う(いずれ記事を書く予定)
- ミドルウェア(DBやmemcachedやnginxなど)はdocker-composeで立ち上げる
- WEBアプリのリポジトリ内に、docker-composeで利用するファイルを一通り突っ込む
- DBのマイグレーションSQL
- nginxのconfファイル
-
docker-compose up
で立ち上げ - ローカルPC上でアプリを起動
-
gradle bootRun
とかactivator run
とか - アプリからはdocker-composeで立ち上げたミドルウェアたちを参照する
- これだとAutoReloadもできる