Docker

【中級者向け】「Docker compose」でサクッと複数のコンテナを一元管理する

ご挨拶

お疲れさまです、寺井です。

前回コンテナについて触れた記事(【初心者向け】今更だけどDockerを使ってコンテナでアプリケーションを構築したい)から少し間が空いてしまいましたが、その続きとなっております。

前回の最後では息巻いて「次はAWSサービスと絡めるでぇ~!!」とか言ってましたが、コンテナの理解が浅すぎるような気がしたので、もう少し深く掘り下げていこうと思った次第です。

Dockerの周辺機能には様々な便利ツールがあるとのことですが、その中でも今回は「Docker Compose」について触れてみます。

最初にまとめ

「Docker Compose」とは

Docker Compose とは、複数コンテナのアプリケーションを定義・共有するために役立つように、開発されたツールです。
Compose があれば、サービスを定義する YAML ファイルを作成し、コマンドを1つ実行するだけで、瞬時にすべて立ち上げたり、すべて解体できます。
引用:Docker Compose を使う — Docker-docs-ja 20.10 ドキュメント

なんでDockerはクジラで、Docker Composeはタコなんでしょう。
教えて!!ChatGPTさん!!!

~~~

寺井:
Dockerがクジラで、Docker Composeはタコのイメージを使っている由来はあるのか

ChatGPT:
DockerとDocker Composeのシンボルやマスコットの由来については、特定の公式な説明や文書はありません。ただし、DockerとDocker Composeのロゴやアートワークには、クジラとタコが描かれていることが一般的です。

Dockerのロゴには、青いクジラ(一般的にはクジラの尾の一部)が使用されています。これは、Dockerがコンテナ化されたアプリケーションを取り扱う際に、大きな負荷や複雑さを背負っているイメージを表現している可能性があります。また、クジラは水中でスムーズに移動できる動物としても知られており、Dockerがアプリケーションの開発、デプロイ、実行をシームレスに行うことを象徴しているかもしれません。

一方、Docker Composeのロゴには、タコが使用されています。タコの多くの足は、柔軟性と多様性を表現している可能性があります。Docker Composeは、複数のDockerコンテナを組み合わせて複雑なアプリケーションスタックを定義し、管理するためのツールです。タコの足のように、Docker Composeはアプリケーションの異なるコンポーネントを柔軟に調整し、繋ぎ合わせることができるという意味合いかもしれません。

~~~

なんかめちゃくちゃそれっぽいこと言ってますね。

脱線しそうなんで、気を取り直して本題に戻ります。

Docker Composeのメリット

Dockerエンジンとの差分

Dockerエンジン Docker Compose
シングルコンテナの管理 複数のコンテナを一括管理
「docker run」で個別にコンテナを起動 「docker-compose up」で複数のコンテナを起動

主要なメリット

  1. マルチコンテナ管理の簡易化:
    • 複数のコンテナを同時に起動、停止、ビルド、削除などの操作ができる
  2. 一貫した環境再現性:
    • docker-compose.ymlにサービスを定義することで複数の環境を再現することが容易になる
  3. サービス間の依存関係の明確化
    • 各サービスの依存関係を定義することができる(depends_on)
  4. 簡易なスケーリング:
    • コマンド一つでサービスのインスタンス数を増減することで柔軟なスケーリングが可能

簡単に言えばたくさんのコンテナを扱いやすくさせてくれるようなイメージでしょうか。

やってみる

ここからは実際に触ってみます!!

今回は「Docker Compose」を使って、複数のコンテナを一括で管理できるようになるところまでやってみようと思います。

検証環境

今回は「Docker Compose」の操作に焦点をあててますので、Dockerのインストールやイメージの作成については、前回の記事を参考にしていただければ幸いです。

OS/ミドルウェア

検証環境 Version
Amazon Linux 2
Docker 20.10.23
Docker Compose 2.19.1

セキュリティグループ

ポート範囲 ソース
8080 - 8090 My IP

セットアップ

Docker composeを使用するための初期設定を行います。

Docker Composeのバイナリファイルを最新のリリースからダウンロードして「/usr/local/bin/」に設置します。

curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

コマンドの補足

オプション 内容
-L リダイレクトを追跡してダウンロード
-o 保存先ディレクトリ指定
$(uname -s)、$(uname -m) OSとアーキテクチャに応じて置き換え
バイナリファイルに実行権限を付与
chmod +x /usr/local/bin/docker-compose
バージョンチェック
docker-compose version

--------
Docker Compose version v2.19.1
--------

これにて「docker-compose」コマンドを使用する環境が整いました。

設定ファイル(docker-compose.yml)の作成

せっかくなので2つのコンテナを定義して、同時に起動できるようにしてみたいと思います。
(既に作成済のDockerイメージを使用します。)

現在のDockerイメージの一覧を取得
docker image ls

--------
REPOSITORY    TAG       IMAGE ID       CREATED              SIZE
my-app-v2.0   latest    8c69cd6091ba   About a minute ago   1.01GB
my-app-v1.0   latest    7202d0e87eee   2 minutes ago        1.01GB
python        3.9       1d7821476b67   3 weeks ago          997MB
python        3.8       db2bf59cb82f   3 weeks ago          997MB
--------

python3.8の「my-app-v1.0」と、python3.9の「my-app-v2.0」がある状態となっています。

Docker Composeでは、「docker-compose.yml」という名前の設定ファイルを作成し、そこにどのようなサービス(コンテナ)を動かすのかを記述します。

プロジェクト用のディレクトリを作成
mkdir compose_test
cd compose_test/
docker-compose.ymlファイルを作成
vi docker-compose.yml
「docker-compose.yml」ファイルを作成
vi docker-compose.yml

中身は以下の内容で作成

services: # サービスを定義
  # 1つ目のサービス
  my-app-py39: # 任意のユニークなサービス名
    image: my-app-v1.0:latest # Dockerのイメージを指定(REPOSITORY:TAG)
    ports: # ポートマッピング
      - 8080:5000 # ホストの8080番ポートをコンテナの5000番ポートにマッピング
  # 2つ目のサービス
  my-app-py38:
    image: my-app-v2.0:latest
    ports:
      - 8081:5000
構文や設定値をチェック
docker-compose config

--------
name: compose_test
services:
  my-app-py38:
    image: my-app-v1.0:latest
    networks:
      default: null
    ports:
    - mode: ingress
      target: 5000
      published: "8080"
      protocol: tcp
  my-app-py39:
    image: my-app-v2.0:latest
    networks:
      default: null
    ports:
    - mode: ingress
      target: 5000
      published: "8081"
      protocol: tcp
networks:
  default:
    name: compose_test_default
--------

明示的に記載しなくてもデフォルトで設定されている項目が表示されているようですね。

イメージを起動

使用する「docker-compose.yml」を指定して起動します。
(今回は「-f」オプションでdocker-compose.ymlを指定していますが、ファイルがあるディレクトリ上で実行する場合は指定しなくてもOK

docker-compose -f ./docker-compose.yml up

--------
[+] Running 3/0
 ? Network compose_test_default          Created                                                                        0.1s
 ? Container compose_test-my-app-py38-1  Created                                                                        0.0s
 ? Container compose_test-my-app-py39-1  Created                                                                        0.0s
Attaching to compose_test-my-app-py38-1, compose_test-my-app-py39-1
︙
--------

docker-compose up オプションの補足

オプション 内容
-f {パス} docker-compose.ymlファイルのパス
-d, --detach バックグラウンドで実行
--build 起動前にイメージ再ビルド
--scale {SERVICE}={NUM} 指定した数だけスケーリング
  • {SERVICE}:「docker-compose.yml」で指定したユニークなサービス名(今回だと「my-app」)
  • {NUM}:スケーリング数を指定
    (今回は特に触れません。)

コンテナの状態確認

バックグラウンドで起動しているコンテナの一覧を確認

docker-compose ps -a

--------
NAME                         IMAGE                COMMAND             SERVICE             CREATED             STATUS              PORTS
compose_test-my-app-py38-1   my-app-v1.0:latest   "python app.py"     my-app-py38         2 seconds ago       Up 1 second         0.0.0.0:8080->5000/tcp, :::8080->5000/tcp
compose_test-my-app-py39-1   my-app-v2.0:latest   "python app.py"     my-app-py39         2 seconds ago       Up 1 second         0.0.0.0:8081->5000/tcp, :::8081->5000/tcp
--------

無事2つのリッスンポートでそれぞれに対応したコンテナサービスが起動されていますね!

起動しているコンテナのログ確認

{サーバのIP:8080}、{サーバのIP:8081}にアクセスすると、ログにアクセスログが記録されます。

docker-compose logs

--------
compose_test-my-app-py39-1  |  * Serving Flask app 'app'
compose_test-my-app-py39-1  |  * Debug mode: on
compose_test-my-app-py39-1  | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
compose_test-my-app-py39-1  |  * Running on all addresses (0.0.0.0)
compose_test-my-app-py39-1  |  * Running on http://127.0.0.1:5000
compose_test-my-app-py39-1  |  * Running on http://172.28.0.2:5000
compose_test-my-app-py39-1  | Press CTRL+C to quit
compose_test-my-app-py39-1  |  * Restarting with stat
compose_test-my-app-py39-1  |  * Debugger is active!
compose_test-my-app-py39-1  |  * Debugger PIN: 795-130-392
compose_test-my-app-py39-1  | {クライアントIP} - - [11/Jul/2023 17:34:05] "GET / HTTP/1.1" 200 -
︙
compose_test-my-app-py38-1  |  * Serving Flask app 'app'
compose_test-my-app-py38-1  |  * Debug mode: on
compose_test-my-app-py38-1  | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
compose_test-my-app-py38-1  |  * Running on all addresses (0.0.0.0)
compose_test-my-app-py38-1  |  * Running on http://127.0.0.1:5000
compose_test-my-app-py38-1  |  * Running on http://172.28.0.3:5000
compose_test-my-app-py38-1  | Press CTRL+C to quit
compose_test-my-app-py38-1  |  * Restarting with stat
compose_test-my-app-py38-1  |  * Debugger is active!
compose_test-my-app-py38-1  |  * Debugger PIN: 129-644-005
compose_test-my-app-py38-1  | {クライアントIP} - - [11/Jul/2023 17:34:04] "GET / HTTP/1.1" 200 -
--------

サービス毎に分かれてログが保存されているので分かりやすいですね~

コンテナの再起動

docker-compose restart

--------
[+] Restarting 2/2
 ? Container compose_test-my-app-py39-1  Started                                                                        1.4s
 ? Container compose_test-my-app-py38-1  Started                                                                        1.3s
--------

コンテナを終了

docker-compose down

--------
[+] Running 2/2
 ? Container compose_test-my-app-1  Removed                                                                             0.2s
 ? Network compose_test_default     Removed                                                                             0.1s
--------

サービス毎のコントロール

Composeによるコントロールについては、「docker-compose.yml」の[services]セクションに定義した一意のサービス名を指定することで、個別のコントロールが可能です。
(今回でいう「my-app-py38」や「my-app-py39」)

services:
  my-app-py39: # ←これ
    image: my-app-v1.0:latest
    ports:
      - 8080:5000

例えば特定のサービスだけを再起動したいときなどに便利かと思われます。

docker-compose restart my-app-py39

--------
[+] Restarting 1/1
 ? Container compose_test-my-app-py39-1  Started                                                                        0.8s
--------

感想

簡単なコマンド操作一つで、複数の環境を同時に操作できるのは、シンプルに感動しました。(スゲェ

今回の記事を書いている中で、
Dockerの基礎的な部分に関してもう少し触った方が良いと感じたので、次回は

  • Docker コンテナ・ネットワーク
  • Docker ボリュームとデータの永続化

のあたりについてやれたら良いなとか妄想してます。

最後までご覧いただきありがとうございました!
また次回も宜しくお願いします。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA