この記事では、MySQL と docker Compose をしてマルチコンテナー アプリを作成する方法について説明します。 複数のコンテナーを持つアプリでは、コンテナーを特殊なタスク専用にして、各コンテナーが 1 つのタスクに集中できるようにします。 マルチコンテナー アプリを使用する利点は多数あります。
- 個別のコンテナーを使用すると、データベースとは異なる方法で API とフロントエンド リソースを管理できます。
- 複数のコンテナーを使用すると、バージョンを分離してバージョンを更新できます。
- ローカル データベースは、運用環境のデータベースに使用されるコンテナーとマネージド サービスで管理できます。
- マルチコンテナー アプリは、プロセス マネージャーを使用して複数のプロセスを実行するよりも効率的であり、コンテナーの起動/シャットダウンが複雑になります。
このチュートリアルでは、次の操作を行います。
- MySQL を起動する
- MySQL を使用してマルチコンテナー アプリを実行する
- アプリの Docker Compose ファイルを作成する
- Docker Compose を使用してアプリケーション スタックを実行する
前提 条件
この記事は、チュートリアル シリーズの一部です。 この手順は、Linux コンテナー Docker Desktop を必要とする確立された例に基づいて構築されています。
推奨される方法は、最初のチュートリアル「前提条件を満たす コンテナー アプリを作成する」、チュートリアル「 アプリにデータを保持する」を完了することです。 これらのチュートリアルを実行したら、この記事で説明されている手順に進んでください。
Visual Studio Code
このチュートリアル シリーズでは、Visual Studio Code (VS Code) の手順について説明します。 この環境での作業については、次の考慮事項を確認してください。
左側のメニューを使用して、 コンテナー エクスプローラー または エクスプローラー (ファイルとフォルダー) ビューを切り替えます。
VS Code で [ターミナル] >を選択して、コマンドラインウィンドウを開きます。 Ctrl+Shift+` (バック ティック) キーボード ショートカットを使うこともできます。
特に指定しない限り、Bash ウィンドウでコマンドを実行します。
Bash
ラベルが付いたほとんどのコマンドは、Bash ウィンドウまたは VS Code コマンド ライン ウィンドウで実行されます。
MySQL データベース管理システムを起動する
既定では、コンテナーは分離して実行されます。 コンテナーは、同じコンピューター上の他のプロセスや他のコンテナーを認識しません。
コンテナー間の通信を有効にするには、同じネットワークに接続する必要があります。 同じネットワーク上の複数のコンテナーで、データを共有し、相互に情報を処理できます。
コンテナーをネットワークにアタッチするには、2 つの方法があります。 作成中にコンテナーをネットワークにアタッチすることも、後で既存のコンテナーをネットワークにアタッチすることもできます。
この例では、ネットワークを作成し、起動時に MySQL コンテナーをアタッチします。
todo-app
という名前のネットワークを作成します。docker network create todo-app
todo-mysql-data
という名前の MySQL コンテナーを起動し、todo-app
ネットワークにアタッチします。 このコマンドは、MySQL データベースmysql
のネットワーク エイリアスtodos
を作成します。コマンドを実行するときに、
<your-password>
プレースホルダーの MySQL ルート パスワードを入力します。docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=<your-password> -e MYSQL_DATABASE=todos mysql:lts
このコマンドでは、
MYSQL_ROOT_PASSWORD
とMYSQL_DATABASE
環境変数も定義します。 詳細については、mySQL Docker Hub の一覧 参照してください。警告
このチュートリアルでは、最も安全な方法ではない MySQL データベースで認証するためのパスワード資格情報について説明します。 より安全な認証方法については、MySQL のドキュメント を参照してください。
次の手順で使用するコンテナー ID を取得します。
docker ps
mysql
ネットワーク上のコンテナーに接続できることを確認します。コマンドを実行するときに、
<mysql-container-id>
プレースホルダーのコンテナー ID を入力します。docker exec -it <mysql-container-id> mysql -p
プロンプトで、
todo-mysql-data
コンテナーの作成時に指定したパスワードを入力します。MySQL シェルで、データベースを一覧表示し、
todos
データベースが表示されていることを確認します。SHOW DATABASES;
次の出力が表示されます。
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | todos | +--------------------+ 5 rows in set (0.00 sec)
接続を終了してコマンド ライン プロンプトに戻すには、「終了」と入力します。
MySQL を使用してアプリを実行する
todo
アプリでは、MySQL 接続設定を指定する特定の環境変数の設定がサポートされています。 次の表に、サポートされている変数と、このセクションで示した例で使用する値を示します。
変数名 | 値の例 | 説明 |
---|---|---|
MYSQL_HOST |
mysql |
MySQL サーバーのホスト名。 |
MYSQL_USER |
root |
接続に使用するユーザー名。 |
MYSQL_PASSWORD |
<your-password> |
接続に使用するパスワード。 この例では、ルート パスワードを <your-password> プレースホルダーに置き換えます。 |
MYSQL_DATABASE |
todos |
接続の確立後に使用するデータベースの名前。 |
警告
環境変数を使用して接続設定を設定することは開発に適していますが、運用環境でアプリケーションを実行する場合は、この方法はお勧めしません。 詳細については、「シークレット データに環境変数を使用しない理由」を参照してください。
より安全なメカニズムは、コンテナー オーケストレーション フレームワークによって提供されるシークレット サポートを使用することです。 ほとんどの場合、これらのシークレットは実行中のコンテナーにファイルとしてマウントされます。
次の例では、アプリを起動し、アプリ コンテナーを MySQL コンテナーに接続します。
次の
docker
コマンドを実行します。 前に説明した環境変数をコマンドで指定する方法に注目してください。コマンドを実行するときは、
<your-password>
プレースホルダーの MySQL ルート パスワードを必ず入力してください。docker run -dp 3000:3000 -w /app -v ${PWD}:/app --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=<your-password> -e MYSQL_DB=todos node:lts-alpine sh -c "yarn install && yarn run dev"
VS Code エディターで、コンテナー エクスプローラーを開き、アプリ コンテナーを右クリックし、[ログの 表示] を選択します。
docker logs
コマンドを使用して、コマンド ラインからログを表示することもできます。ログ出力を確認します。 アプリが MySQL データベースに接続されていることを示す行に注目してください:
Connected to mysql db at host mysql
。# Previous log messages omitted $ nodemon src/index.js [nodemon] 1.19.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Connected to mysql db at host mysql Listening on port 3000
インターネット ブラウザーで、実行中のアプリケーションに移動します:
http://localhost:3000
。実行中のアプリケーションで、todo リストにいくつかの項目を追加します。
データベースを確認できるように、
mysql
ネットワーク上の MySQL コンテナー データベースに接続します。コマンドを実行するときに、
<mysql-container-id>
プレースホルダーのコンテナー ID を入力します。docker exec -ti <mysql-container-id> mysql -p todos
プロンプトで、
todo-mysql-data
コンテナーの作成時に指定したパスワードを入力します。MySQL シェルで、追加した
todo_items
がtodos
データベースに書き込まれたことを確認します。use todos; select * from todo_items;
次の例のような出力が表示されます。
+--------------------------------------+--------------------+-----------+ | id | name | completed | +--------------------------------------+--------------------+-----------+ | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! | 0 | | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome! | 0 | +--------------------------------------+--------------------+-----------+
これで、別のコンテナーで実行されている外部データベースにデータを格納するアプリケーションが作成されました。 この手順では、ネットワークを使用してコンテナー間の通信を有効にする方法を示します。
Docker Compose ファイルを作成する
Docker Compose は、マルチコンテナー アプリケーションの定義と共有に役立ちます。 Docker Compose ファイルでは、必要なすべてのサービスを指定できるため、関連するすべてのプロセスを 1 つのコマンドで開始または終了できます。 プロジェクト リポジトリのルートにある Docker Compose ファイルでアプリケーション スタックを定義し、バージョン管理の下で構成を維持できます。 このアプローチを使用すると、他のユーザーがリポジトリを複製するときにプロジェクトに貢献できます。
次の例では、マルチコンテナー アプリケーション todo
用に Docker Compose ファイルを構成します。
todo
アプリ プロジェクトのルートで、docker-compose.ymlという名前の Docker Compose ファイルを作成します。手記
既定では、YAML スキーマのバージョンは最新バージョンに設定されます。 アプリを実行すると、スキーマのバージョンが古い場合は、警告メッセージが表示されます。 現在のスキーマ バージョンと互換性マトリックスを確認するには、「概要 (Compose ファイル)を参照してください。
docker-compose.yml ファイルに、次の要素を追加します。 アプリの
name
を指定し、アプリケーションの一部として実行するservices
(またはコンテナー) の一覧を開始します。name: todo services:
サービスの一覧は、アプリに固有です。 たとえば、
app
、web
、db
、proxy
などです。services
要素の定義は、後の手順で拡張します。ヒント
インデントは、.yml ファイルで重要です。 VS Code で編集している場合、Intellisense は形式または構文のエラーを示します。
services
ファイル内の 定義に戻ります。 コンテナーのイメージを含むapp
サービス要素を定義するエントリを追加して、定義を拡張します。services: app: image: node:lts-alpine
サービスの任意の名前を選択できます。 名前は自動的にネットワーク エイリアスになり、MySQL サービスを定義するときに便利です。
app
要素定義を拡張して、実行するcommand
を指定します。app: image: node:lts-alpine command: sh -c "yarn install && yarn run dev"
ports
サービスで使用するapp
を定義します。 これらのポートは、MySQL でアプリを実行するために使用されるコマンドの-p 3000:3000
引数に対応していることに注意してください。app: image: node:lts-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000
working_dir
サービスの作業ディレクトリapp
と、マップされたvolumes
を特定します。app: image: node:lts-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app
Docker Compose ボリュームを定義する場合は、現在のディレクトリに基づいて相対パスを使用できます。
environment
サービスapp
コマンドを実行するときに使用する変数定義を指定します。app: image: node:lts-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: <your-password> MYSQL_DB: todos
忘れずに、
<your-password>
プレースホルダーの MySQL ルート パスワードを入力してください。mysql
サービス定義の後に MySQL サービスapp
の定義を追加します。 表示されている要素の名前と値を、同じインデントで指定します。services: app: ... mysql: image: mysql:lts
mysql
サービス定義は、MySQL を開始前に使用したコマンドに対応します。 サービスを定義すると、ネットワーク エイリアスが自動的に受信されます。volumes
サービス用にマッピングされたmysql
を特定します。services: app: ... mysql: image: mysql:lts volumes: - todo-mysql-data:/var/lib/mysql
environment
サービスmysql
コマンドを実行するときに使用する変数定義を指定します。services: app: ... mysql: image: mysql:lts volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: <your-password> MYSQL_DATABASE: todos
忘れずに、
<your-password>
プレースホルダーの MySQL ルート パスワードを入力してください。アプリ全体のボリューム マッピングを定義します。
volumes:
セクションの後に、同じインデントを持つservices:
セクションを追加します。services: ... volumes: todo-mysql-data:
完成した docker-compose.yml ファイルが次の例のようになることを確認します。
<your-password>
プレースホルダーの MySQL ルート パスワードが表示されます。name: todo services: app: image: node:lts-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: <your-password> MYSQL_DB: todos mysql: image: mysql:lts volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: <your-password> MYSQL_DATABASE: todos volumes: todo-mysql-data:
Docker Compose を使用してアプリケーション スタックを実行する
これで、docker-compose.yml ファイルの実行を試すことができます。
アプリケーションとデータベースの実行中のインスタンスをすべて停止します。
VS Code の次の手順に従います。
CONTAINER EXPLORER (Container Tools 拡張機能) を開く。
実行中のコンテナーごとに、コンテナーを右クリックし、[の削除]選択します。
マルチコンテナー アプリとすべてのサービスを開始します。
VS Code の次の手順に従います。
EXPLORER (ファイルとフォルダー) ビューを開きます。
docker-compose.yml を右クリックして [Compose アップ] を選びます。
次の例のような出力が表示されます。
[+] Building 0.0s (0/0) [+] Running 2/2 ✔ Container app-app-1 Started 0.9s ✔ Container app-mysql-1 Running
この操作により、アプリとネットワークのマップされたボリュームが作成されます。 既定では、Docker Compose はアプリケーション スタック専用のネットワークを作成します。
実行中のコンテナーのログを確認します。
VS Code の次の手順に従います。
CONTAINER EXPLORER (Container Tools 拡張機能) を開く。
アプリ コンテナーを右クリックし、[ログの表示] 選択します。
次の例のような出力が表示されます。
mysql_1 | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections. mysql_1 | Version: '5.7.27' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) app_1 | Connected to mysql db at host mysql app_1 | Listening on port 3000
ログには、サービス名とインスタンス番号 (各行の先頭に
app_1
など) が表示されます。 この形式は、サービスとインスタンスによってメッセージを区別するのに役立ちます。 各サービスのログは、1 つのストリームにインターリーブされます。 この方法では、タイミング関連の問題を監視できます。これで、インターネット ブラウザーで実行中のアプリケーションに移動できるようになりました:
http://localhost:3000
。
Docker Compose と実行中のコンテナーを停止する
アプリとコンテナーの使用が完了したら、それらを削除できます。
VS Code の次の手順に従います。
EXPLORER (ファイルとフォルダー) ビューを開きます。
docker-compose.yml を右クリックして [Compose ダウン] を選びます。
この操作により、実行中のすべてのコンテナーが停止され、ネットワークが削除されます。
既定では、作成ファイル内の名前付きボリュームは削除されません。 これらのボリュームを削除する場合は、docker-compose down --volumes
コマンドを使用できます。
リソースのクリーンアップ
このチュートリアル シリーズの Prerequisites コンポーネントをインストールに適用した場合は、将来の Docker 開発のために構成を再利用できます。 コンポーネントを削除またはアンインストールすることは必須ではありません。