バインド マウント の使用¶
Part 5 ではデータベース内のデータを保持するため、ボリュームのマウントを使いました。アプリケーションのデータをどこかに保持する必要がある場合、ボリュームマウントは良い選択肢です。
本章で分かるのは、バインドマウントの使い方と、ファイル変更を監視してアプリケーションを自動的に再起動する nodemon と呼ばれるツールについてです。
ボリューム型の素早い比較¶
以下の表が示すのは、ボリュームマウントとバインドマウントの主な違いです。
ホスト上の場所 |
Docker が選択 |
自分で決める |
マウント例( |
|
|
コンテナの内容に新しいボリュームを加える |
はい |
いいえ |
ボリューム ドライバのサポート |
はい |
いいえ |
バインド マウントを試す¶
アプリケーション開発でバインドマウントを使う方法を学ぶ前に、どのようにしてバインドマウントが動作するのか実用的な理解をするために、簡単な実験を行えます。
ターミナルを開き、ディレクトリを getting-started リポジトリの
app
に変更します。
以下のコマンドは、バインドマウントした
ubuntu
コンテナでbash
を実行します。Mac / Linux
$ docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash
Windows
PowerShell でコマンドを実行します。
$docker run -it --mount "type=bind,src=$pwd,target=/src" ubuntu bash
--mount
オプションは Docker に対してバインドマウントの作成を命令します。src
で示す場所は、ホストマシン上の現在の作業ディレクトリ(getting-started/app
)です。target
で示す場所は、コンテナ内に現れるディレクトリ(/src
)です。
コマンドの実行後、コンテナが持つファイルシステムのルートディレクトリ内で、Docker は対話式の
bash
セッションを開始します。root@ac1237fad8db:/# pwd / root@ac1237fad8db:/# ls bin dev home media opt root sbin srv tmp var boot etc lib mnt proc run src sys usr
src
ディレクトリにディレクトリを変更します。ここはコンテナ起動時にマウントしたディレクトリです。このディレクトリ内容の一覧を表示したら、ホストマシン上の
getting-started/app
ディレクトリと同じようにファイルを表示します。root@ac1237fad8db:/# cd src root@ac1237fad8db:/src# ls Dockerfile node_modules package.json spec src yarn.lock
myfile.txt
という名前の新しいファイルを作成します。root@ac1237fad8db:/src# touch myfile.txt root@ac1237fad8db:/src# ls Dockerfile myfile.txt node_modules package.json spec src yarn.lock
ホスト上の
app
ディレクトリを開き、ディレクトリ内にmyfile.txt
があるかどうか調べます。├── app/ │ ├── Dockerfile │ ├── myfile.txt │ ├── node_modules/ │ ├── pacakge.json │ ├── spec/ │ ├── src/ │ └── yarn.lock
ホストから
myfile.txt
ファイルを削除します。
コンテナ内で、再び
app
ディレクトリ内の内容を一覧表示します。今度はファイルが消えてしまったと分かります。root@ac1237fad8db:/src# ls Dockerfile node_modules package.json spec src yarn.lock
対話型のコンテナセッションを
Ctrl
+D
で停止します。
以上がバインドマウントの簡単な紹介のすべてです。この手順では、ホストとコンテナ間でどのようにファイルを共有しているのかと、どちらにも変更が直ちに反映されるのを示しました。これでソフトウェア開発にバインドマウントを利用できます。
コンテナのデプロイ¶
ローカル開発環境のセットアップで、バインドマウントの利用は一般的です。利点は、開発マシン上に全ての構築ツールや環境をインストールする必要がありません。docker run コマンドを1回実行するだけで、Docker は依存関係とツールを取得します。
開発用のコンテナでアプリを実行¶
以下の手順で示すのは、バインドマウントがある開発用のコンテナを実行する手順です:
バインドマウントしてコンテナを実行するには、 CLI か Docker Desktop を使えます。
CLI
これまでの
getting-started
コンテナが動作していないのを確認します。
getting-started/app
ディレクトリから以下のコマンドを実行します。Mac / Linux
$ docker run -dp 127.0.0.1:3000:3000 \ -w /app --mount type=bind,src="$(pwd)",target=/app \ node:18-alpine \ sh -c "yarn install && yarn run dev"Windows
このコマンドを PowerShell で実行します。
- $ docker run -dp 127.0.0.1:3000:3000 `
-w /app --mount "type=bind,src=$pwd,target=/app" ` node:18-alpine ` sh -c "yarn install && yarn run dev"
以下はコマンドの詳細です:
-dp 127.0.0.1:3000:3000
… 以前と同じです。デタッチド(バックグラウンド)モードで実行し、ポート割り当てを作成します。
-w /app
… 「作業ディレクトリ 」 またはカレントディレクトリを指定します。
--mount "type=bind,src=$pwd,target=/app"
… ホスト上のカレントディレクトリを、コンテナ内の/app
ディレクトリにバインドマウントします。
node:18-alpine
… 使用するイメージです。なお、これが Dockerfile からアプリを作成するベースイメージです。
sh -c "yarn install && yarn run dev"
… シェルを開始するのにsh
を使い( alpine にはbash
はありません)、パッケージをインストールするためyarn install
を実行し、開発用サーバを開始するためにyarn run dev
を実行します。packagejson
の中を見ると、dev
スクリプトがnodemon
を起動しているのが分かります。
docker logs <container-id>
を使いログを観察できます。準備が調えば、次のような表示になるでしょう:$ docker logs -f <container-id> nodemon src/index.js [nodemon] 2.0.20 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Using sqlite database at /etc/todos/todo.db Listening on port 3000ログの観察が終わったら、
Ctrl
+C
を入力して終了します。
Docker Desktop
これまでの
getting-started
コンテナが動作していないのを確認します。
バインドマウントしてイメージを起動します。
Docker Desktop の一番上にある検索ボックスを選びます。
検索ウインドウで Images タブを選びます。
検索ボックスでコンテナ名を
getting-started
と指定します。Tip
検索でフィルタを使えば local images (ローカルイメージ)のみ表示できます。
自分が作ったイメージを選び、 Run (実行)を選びます。
Optional settings を選びます。
Host path (ホスト側パス)で、ホストマシン上の
app
ディレクトリのパスを指定しますContainer path (コンテナ側パス)で
/app
を指定します。Run (実行)を選びます。
Docker Desktop を使ってコンテナのログを観察できます。
Docker Desktop の Containers を選びます。
コンテナ名を選びます。
準備が調えば、次の様な表示になるでしょう:
$ docker logs -f <container-id> nodemon src/index.js [nodemon] 2.0.20 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Using sqlite database at /etc/todos/todo.db Listening on port 3000
開発用コンテナにアプリをデプロイ¶
ホストマシン上のアプリを更新し、コンテナ内に変更が反映されるのを確認します。
src/static/js/app.js
ファイル内の 109 行目の、「Add Item」ボタンをシンプルに「Add」と表示するように変えます。- {submitting ? 'Adding...' : 'Add Item'} + {submitting ? 'Adding...' : 'Add'}
ファイルを保存します。
ウェブブラウザでページを再読み込みしたら、ほぼ直ちに変更が反映しているのが分かるでしょう。Node サーバの再起動には、数秒かかるかもしれず、もしエラーが出てしまった場合には、数秒後に再読み込みを試してください。
あとは、他も自由気ままに変更します。変更後は毎回ファイルを保存しますと、
nodemon
プロセスがコンテナ内のアプリを再起動します。終わったら、コンテナを停止し、以下のコマンドを使って新しいイメージを構築します。$ docker build -t getting-started .
次のステップ¶
現段階で、データベースを保持できるようになり、イメージを再構築しなくても、開発しているアプリを変更できるのが分かりました。
ボリュームマウントとバインドマウントに加え、より複雑かつ専門的なユースケースに対応するため、Docker は他のマウントタイプやストレージドライバをサポートします。
アプリの本番環境を準備するには、データベースを SQLite からスケール可能な何かに移行する必要があります。扱いやすさのため、関係データベースの採用にあたり、アプリケーションが MySQL を使うように切り替えます。ですが、どうやって MySQL を動かせばよいのでしょうか? どのようにしてコンテナ間でお互いが通信できるのでしょうか? これは次のセクションで学びます。
参考
- Part 6: User bind mounts