このチュートリアルでは、コンテナー アプリケーションにデータを保持する方法について説明します。 実行または更新しても、データは引き続き使用できます。 データを保持するために使用されるボリュームには、主に 2 つの種類があります。 このチュートリアルでは、名前付きボリュームについて説明します。
また、バインド マウント について学習します。これは、ホスト上の正確なマウントポイントを制御します。 バインド マウントを使用してデータを保持できますが、コンテナーにさらにデータを追加することもできます。 アプリケーションで作業する場合は、バインド マウントを使用してソース コードをコンテナーにマウントし、コードの変更を確認したり、応答したり、変更をすぐに確認したりすることができます。
このチュートリアルでは、イメージレイヤー、レイヤーキャッシュ、マルチステージビルドも紹介します。
このチュートリアルでは、次の方法について説明します。
- コンテナー間のデータを理解する。
- 名前付きボリュームを使用してデータを保持します。
- バインド マウントを使用する。
- イメージ レイヤーを表示します。
- キャッシュの依存関係。
- マルチステージ ビルドについて理解する。
前提 条件
このチュートリアルでは、前のチュートリアル「 Visual Studio Code でコンテナー アプリを作成して共有する」を続けます。 前提条件を含む、その 1 つから始めます。
コンテナー間のデータを理解する
このセクションでは、2 つのコンテナーを開始し、それぞれにファイルを作成します。 あるコンテナーで作成されたファイルは、別のコンテナーでは使用できません。
次のコマンドを使用して、
ubuntu
コンテナーを起動します。docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
このコマンドは、
&&
を使用して 2 つのコマンドを呼び出します。 最初の部分は、1 つの乱数を選択し、/data.txt
に書き込みます。 2 番目のコマンドは、コンテナーを実行し続けるためにファイルを監視しています。VS Code のコンテナー エクスプローラーで、ubuntu コンテナーを右クリックし、[ Attach Shell]\(シェルのアタッチ\) を選択します。
Ubuntu コンテナーでシェルを実行しているターミナルが開きます。
次のコマンドを実行して、
/data.txt
ファイルの内容を確認します。cat /data.txt
ターミナルには、1 から 10000 までの数値が表示されます。
コマンド ラインを使用してこの結果を表示するには、
docker ps
コマンドを使用してコンテナー ID を取得し、次のコマンドを実行します。docker exec <container-id> cat /data.txt
別の
ubuntu
コンテナーを起動します。docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
このコマンドを使用して、フォルダーの内容を確認します。
docker run -it ubuntu ls /
最初のコンテナーのみのスクラッチ領域に書き込まれたため、そこに
data.txt
ファイルは存在しません。これら 2 つの Ubuntu コンテナーを選択します。 右クリックし、[削除] 選択します。 コマンド ラインから、
docker rm -f
コマンドを使用して削除できます。
名前付きボリュームを使用して todo データを保持する
既定では、todo アプリはデータを の /etc/todos/todo.db
に格納します。
SQLite データベースは、データを 1 つのファイルに格納するリレーショナル データベースです。
このアプローチは、小規模なプロジェクトに対して機能します。
ホスト上に 1 つのファイルを保持できます。 次のコンテナーで使用できるようにすると、アプリケーションは中断した場所から再開できます。 ボリュームを作成してアタッチするか、マウントして、データが格納されているフォルダーに接続することで、データを保持できます。 コンテナーは todo.db ファイルに書き込み、そのデータはボリューム内のホストに保持されます。
このセクションでは、という名前のボリュームを使用します。 Docker は、ディスク上のボリュームの物理的な場所を維持します。 ボリュームの名前を参照すると、Docker によって適切なデータが提供されます。
docker volume create
コマンドを使用してボリュームを作成します。docker volume create todo-db
[コンテナー] で、getting-started を選んで右クリックします。 [停止] を選択して、アプリ コンテナーを停止します。
コマンド ラインからコンテナーを停止するには、
docker stop
コマンドを使用します。次のコマンドを使用して、getting-started コンテナーを開始します。
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
ボリューム パラメーターは、マウントするボリュームと場所
/etc/todos
を指定します。ブラウザーを更新してアプリを再読み込みします。 ブラウザー ウィンドウを閉じた場合は、
http://localhost:3000/
に移動します。 todo リストにいくつかの項目を追加します。todo アプリの 入門 コンテナを削除します。 コンテナー エクスプローラーでコンテナーを右クリックし、[ 削除 ] を選択するか、
docker stop
コマンドとdocker rm
コマンドを使用します。同じコマンドを使用して新しいコンテナーを開始します。
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
このコマンドは、以前と同じドライブをマウントします。 ブラウザーを更新します。 追加した項目は引き続き一覧に表示されます。
getting-started コンテナーをもう一度削除します。
以下で説明する名前付きボリュームとバインド マウントは、既定の Docker エンジン インストールでサポートされるボリュームの主な種類です。
財産 | 名前付きボリューム | バインド マウント |
---|---|---|
ホストの場所 | Docker が選択する | あなたが制御する |
マウント例 (-v を使用) |
my-volume:/usr/local/data | /path/to/data:/usr/local/data |
新しいボリュームにコンテナーの内容を設定する | はい | いいえ |
ボリューム ドライバーをサポートする | はい | いいえ |
NFS、SFTP、NetApp などをサポートするために使用できるボリューム ドライバー プラグインは多数あります。 これらのプラグインは、Swarm や Kubernetes などのクラスター化された環境で複数のホストでコンテナーを実行する場合に特に重要です。
Docker で "実際に" データが保存される場所を確認したい場合は、次のコマンドを実行します。
docker volume inspect todo-db
この結果と同様に、出力を確認します。
[
{
"CreatedAt": "2019-09-26T02:18:36Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
"Name": "todo-db",
"Options": {},
"Scope": "local"
}
]
Mountpoint
は、データが格納される実際の場所です。
ほとんどのコンピューターでは、ホストからこのディレクトリにアクセスするにはルート アクセスが必要です。
バインド マウントを使用する
バインド マウント では、ホスト上の正確なマウント ポイントを制御します。 この方法ではデータが保持されますが、多くの場合、より多くのデータをコンテナーに提供するために使用されます。 バインド マウントを使用すると、ソース コードをコンテナーにマウントして、コードの変更を確認したり、応答したり、変更をすぐに確認したりすることができます。
開発ワークフローをサポートするためにコンテナーを実行するには、次の手順を実行します。
getting-started
コンテナーを削除します。app
フォルダーで、次のコマンドを実行します。docker run -dp 3000:3000 -w /app -v ${PWD}:/app node:lts-alpine sh -c "yarn install && yarn run dev"
このコマンドには、次のパラメーターが含まれています。
-
-dp 3000:3000
以前と同じです。 デタッチ モードで実行し、ポート マッピングを作成します。 - コンテナー内の作業ディレクトリ
-w /app
。 -
-v ${PWD}:/app"
バインドは、コンテナー内のホストから/app
ディレクトリに現在のディレクトリをマウントします。 -
node:lts-alpine
使用するイメージ。 このイメージは、Dockerfileからのアプリの基本イメージです。 -
sh -c "yarn install && yarn run dev"
はコマンドです。sh
を使用してシェルを起動し、yarn install
実行してすべての依存関係をインストールします。 次に、yarn run dev
実行されます。package.json
を見ると、dev
スクリプトでnodemon
が開始されています。
-
docker logs
を使用してログを監視できます。docker logs -f <container-id>
$ nodemon src/index.js [nodemon] 2.0.20 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node src/index.js` Using sqlite database at /etc/todos/todo.db Listening on port 3000
この一覧に最後のエントリが表示されたら、アプリが実行されています。
ログの監視が完了したら、ターミナル ウィンドウで任意のキーを選択するか、外部ウィンドウで Ctrl +選択します。
VS Code で、src/static/js/app.jsを開きます。 109 行目の [項目の追加] ボタンのテキストを変更します。
- {submitting ? 'Adding...' : 'Add Item'} + {submitting ? 'Adding...' : 'Add'}
変更を保存します。
ブラウザーを更新します。 変更が表示されます。
node:lts-alpine
コンテナーを削除します。app
フォルダーで、次のコマンドを実行して、前の手順で作成したnode_modules
フォルダーを削除します。rm -r node_modules
イメージ レイヤーを表示する
画像を構成するレイヤーを確認できます。
docker image history
コマンドを実行して、イメージ内の各レイヤーの作成に使用されたコマンドを確認します。
docker image history
を使用して、チュートリアルで以前に作成した 入門 イメージのレイヤーを確認します。docker image history getting-started
結果は次の出力のようになります。
IMAGE CREATED CREATED BY SIZE COMMENT a78a40cbf866 18 seconds ago /bin/sh -c #(nop) CMD ["node" "/app/src/ind… 0B f1d1808565d6 19 seconds ago /bin/sh -c yarn install --production 85.4MB a2c054d14948 36 seconds ago /bin/sh -c #(nop) COPY dir:5dc710ad87c789593… 198kB 9577ae713121 37 seconds ago /bin/sh -c #(nop) WORKDIR /app 0B b95baba1cfdb 13 days ago /bin/sh -c #(nop) CMD ["node"] 0B <missing> 13 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B <missing> 13 days ago /bin/sh -c #(nop) COPY file:238737301d473041… 116B <missing> 13 days ago /bin/sh -c apk add --no-cache --virtual .bui… 5.35MB <missing> 13 days ago /bin/sh -c #(nop) ENV YARN_VERSION=1.21.1 0B <missing> 13 days ago /bin/sh -c addgroup -g 1000 node && addu… 74.3MB <missing> 13 days ago /bin/sh -c #(nop) ENV NODE_VERSION=12.14.1 0B <missing> 13 days ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 13 days ago /bin/sh -c #(nop) ADD file:e69d441d729412d24… 5.59MB
各線は、画像内のレイヤーを表します。 出力は、基礎が下にあり、最新のレイヤーが上にあることを示しています。 この情報を使用すると、各レイヤーのサイズを確認でき、大きな画像の診断に役立ちます。
いくつかの行が切り捨てられます。
--no-trunc
パラメーターを追加すると、完全な出力が得られます。docker image history --no-trunc getting-started
キャッシュの依存関係
レイヤーが変更されたら、すべてのダウンストリーム レイヤーも再作成する必要があります。 こちらが再度、Dockerfile です。
FROM node:lts-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "/app/src/index.js"]
Dockerfile 内の各コマンドは、イメージ内の新しいレイヤーになります。
レイヤーの数を最小限に抑えるために、依存関係のキャッシュをサポートするために、Dockerfile を再構築できます。
ノード ベースのアプリケーションの場合、これらの依存関係は package.json
ファイルで定義されます。
この方法では、最初にそのファイルのみをコピーし、依存関係をインストールしてから、他のすべてをコピー します。
プロセスは、package.json
に変更があった場合にのみ、yarn の依存関係を再作成します。
Dockerfile を更新して、最初に
package.json
にコピーし、依存関係をインストールしてから、他のすべてをコピーします。 新しいファイルを次に示します。FROM node:lts-alpine WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install --production COPY . . CMD ["node", "/app/src/index.js"]
docker build
を使用して新しいイメージをビルドします。docker build -t getting-started .
次のような出力が表示されます。
Sending build context to Docker daemon 219.1kB Step 1/6 : FROM node:lts-alpine ---> b0dc3a5e5e9e Step 2/6 : WORKDIR /app ---> Using cache ---> 9577ae713121 Step 3/6 : COPY package* yarn.lock ./ ---> bd5306f49fc8 Step 4/6 : RUN yarn install --production ---> Running in d53a06c9e4c2 yarn install v1.17.3 [1/4] Resolving packages... [2/4] Fetching packages... info fsevents@1.2.9: The platform "linux" is incompatible with this module. info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... [4/4] Building fresh packages... Done in 10.89s. Removing intermediate container d53a06c9e4c2 ---> 4e68fbc2d704 Step 5/6 : COPY . . ---> a239a11f68d8 Step 6/6 : CMD ["node", "/app/src/index.js"] ---> Running in 49999f68df8f Removing intermediate container 49999f68df8f ---> e709c03bc597 Successfully built e709c03bc597 Successfully tagged getting-started:latest
すべてのレイヤーが再構築されました。 Dockerfileを変更したため、この結果が予想されます。
src/static/index.htmlに変更を加えます。 たとえば、タイトルを 「The Awesome Todo App」と表示するように変更します。
docker build
をもう一度使用して Docker イメージをビルドします。 今回は、出力が少し異なって見えるはずです。Sending build context to Docker daemon 219.1kB Step 1/6 : FROM node:lts-alpine ---> b0dc3a5e5e9e Step 2/6 : WORKDIR /app ---> Using cache ---> 9577ae713121 Step 3/6 : COPY package* yarn.lock ./ ---> Using cache ---> bd5306f49fc8 Step 4/6 : RUN yarn install --production ---> Using cache ---> 4e68fbc2d704 Step 5/6 : COPY . . ---> cccde25a3d9a Step 6/6 : CMD ["node", "/app/src/index.js"] ---> Running in 2be75662c150 Removing intermediate container 2be75662c150 ---> 458e5c6f080c Successfully built 458e5c6f080c Successfully tagged getting-started:latest
ビルド キャッシュを使用しているため、はるかに高速になります。
マルチステージ ビルド
マルチステージ ビルドは、複数のステージを使用してイメージを作成するのに役立つ非常に強力なツールです。 これらにはいくつかの利点があります。
- ビルド時の依存関係とランタイムの依存関係を分離する
- アプリの実行に必要なものだけを出荷することで、画像全体のサイズを小さくする
このセクションでは、簡単な例を示します。
Maven/Tomcat の例
Java ベースのアプリケーションをビルドするときは、ソース コードを Java バイトコードにコンパイルするために JDK が必要です。 その JDK は運用環境では必要ありません。 Maven や Gradle などのツールを使用して、アプリのビルドを支援している場合があります。 これらのツールは、最終的なイメージでも必要ありません。
FROM maven AS build
WORKDIR /app
COPY . .
RUN mvn package
FROM tomcat
COPY --from=build /app/target/file.war /usr/local/tomcat/webapps
この例では、1 つのステージ (build
) を使用して、Maven を使用して実際の Java ビルドを実行します。
2 番目のステージは "FROM tomcat" から始まり、build
ステージからファイルをコピーします。
最終的なイメージは、作成される最後のステージのみです。このステージは、--target
パラメーターを使用してオーバーライドできます。
React の例
React アプリケーションをビルドするときは、JavaScript コード、Sass スタイルシートなどを静的 HTML、JavaScript、CSS にコンパイルするための Node 環境が必要です。 サーバー側のレンダリングを行っていない場合は、実稼働ビルド用の Node 環境も必要ありません。
FROM node:lts-alpine AS build
WORKDIR /app
COPY package* yarn.lock ./
RUN yarn install
COPY public ./public
COPY src ./src
RUN yarn run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
この例では、node:lts-alpine
イメージを使用してビルドを実行し、レイヤー のキャッシュを最大化し、出力を nginx コンテナーにコピーします。
リソースのクリーンアップ
この一連のチュートリアルを続けるには、これまでに行ったことをすべて保持してください。
次の手順
コンテナー アプリのデータを保持するオプションについて学習しました。
次に何をしたいですか?
Docker Compose を使用して複数のコンテナーを操作する:
MySQL と Docker Compose を使用してマルチコンテナー アプリを作成する
Azure Container Apps にデプロイする:
クイック スタート: Visual Studio Code を使用して Azure Container Apps にデプロイする
チュートリアル: Azure Container Apps にデプロイする
Azure App Service へのデプロイ
- コンテナー化されたアプリを Azure にデプロイする