バインドマウントの利用

読む時間の目安: 2 分

前節においては 名前つきボリューム を取り上げて、データベース上のデータを保存するようにしました。 名前つきボリュームは単にデータを保存したいだけであれば、十分に使えます。 その際には どこに データが保存されるのかを気にかける必要もありません。

バインドマウント(bind mounts)の場合は、ホスト上のマウントポイントを正確に制御することになります。 このマウントによってデータ保存を行ないますが、コンテナーに対してこれとは違ったデータ提供のためにも用いられることがあります。 アプリケーションを開発する際には、バインドマウントを利用してソースコードをコンテナー内にマウントすることができます。 これを行うことでアプリケーションがコード変更を識別でき、これに応じてわれわれも正しく変更を確認することができます。

Node ベースのアプリケーションとして nodemon があり、ファイル変更を監視してその後にアプリケーションを再起動するという優れたツールです。 たいていのプログラミング言語やフレームワークに対しても同様のツールがあります。

ボリューム種類の単純比較

バインドマウントと名前つきボリュームは Docker Engine が提供する 2 種類のボリュームです。 これ以外にも別の状況において利用できるボリュームドライバーがあります(SFTPCephNetAppS3 などです)。

  名前つきボリューム バインドマウント
ホスト側ディレクトリ Docker が制御 ユーザーが制御
マウント例(-v利用時) my-volume:/usr/local/data /path/to/data:/usr/local/data
新ボリュームにコンテナー内容を取り込む Yes No
ボリュームドライバーのサポート Yes No

開発対応のコンテナー起動

開発作業に対応するようなコンテナー起動を行うため、以下を行っていくことにします。

  • ソースコードをコンテナー内にマウントします。
  • 依存パッケージをすべてインストールします。「dev」パッケージもインストールします。
  • ファイルシステム変更の監視に nodemon を利用します。

さて始めていきます。

  1. これまでのgetting-startedコンテナーは一切動いていないことを確認します。

  2. アプリケーションディレクトリから以下のコマンドを実行します。 これがどのようになるのかは後に説明します。

     $ docker run -dp 3000:3000 \
         -w /app -v "$(pwd):/app" \
         node:12-alpine \
         sh -c "yarn install && yarn run dev"
    

    PowerShell を利用している場合は以下のコマンドとします。

     PS> docker run -dp 3000:3000 `
         -w /app -v "$(pwd):/app" `
         node:12-alpine `
         sh -c "yarn install && yarn run dev"
    
    • -dp 3000:3000 - 前回と同様です。 デタッチ(バックグラウンド)モードで実行し、ポートマッピングを生成します。
    • -w /app - 「ワーキングディレクトリ」つまりカレントディレクトリを設定し、コマンドをそこから実行します。
    • -v "$(pwd):/app" - ホスト上のカレントディレクトリを、コンテナー内の/appディレクトリにバインドマウントします。
    • node:12-alpine - 利用イメージです。 ちなみにこれはアプリケーションがベースイメージとするように Dockerfile 内で指定しています。
    • sh -c "yarn install && yarn run dev" - コマンドです。 ここではshを起動して(alpine にはbashがないので)yarn installを実行します。 これによって依存パッケージを すべて インストールし、さらにyarn run devを実行します。 package.jsonの中身を見ればわかるように、devスクリプトからnodemonを起動しています。
  3. docker logsを実行すればログ確認ができます。 このログから準備万端であることがわかります。

     $ docker logs -f <container-id>
     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`
     Using sqlite database at /etc/todos/todo.db
     Listening on port 3000
    

    ログの確認を終えるにはCtrl+Cを入力して終了させます。

  4. それではアプリに変更を加えてみます。 src/static/js/app.jsファイルにおいて「Add Item」ボタン”の名前を単純に「Add」とします。 この修正を行うのは 109 行めです。

     -                         {submitting ? 'Adding...' : 'Add Item'}
     +                         {submitting ? 'Adding...' : 'Add'}
    
  5. 単純にページを更新します(あるいは改めて開きます)。 ブラウザー上には変更した内容がほぼ即座に反映されたはずです。 Node サーバーの再起動にはほんの数秒しかかかりませんから、もしエラー発生した場合は数秒待ってページ更新を行ってみてください。

    Add ボタンのラベルを修正したスナップショット

  6. 他に変更したい内容があれば、どんどん行ってください。 作業が完了したらコンテナーを停止した上で、以下を実行して新たなイメージをビルドしてください。

     $ docker build -t getting-started .
    

バインドマウントを利用することは、ローカル開発環境においては ごくごく 普通のことです。 これを使う利点は、開発作業を進めるマシンにおいては、ビルドツールや開発環境すべてをインストールする必要がなくなるということです。 docker runコマンドを 1 つ実行するだけで、開発環境がプルされすぐに利用可能になります。 この後には Docker Compose の説明を行っていきますが、そのときにはコマンド実行がもっと単純になります(もうすでにたくさんのフラグを使っていますから)。

まとめ

ここまでにデータの保存を行い、会社へ投資してくれる人、会社の設立者から要求があったとしても、即対応できるようになりました。 やりました。 あれ、何でしょう? 驚きのニュースが飛び込んできましたよ。

このプロジェクトが今後の開発対象として選定されました!

本番環境へ移行させるためには、データベースとして SQLite での作業としていたものを、もっとスケールアップしたものに変更することが必要です。 作業が複雑にはならないようにリレーショナルデータベースは使い続けるとして、アプリケーションから利用するデータベースは MySQL とします。 だけどどうやって MySQL を実行するのでしょう。 どうやったら複数コンテナーが互いにやりとりできるようになるのでしょう。 さぁ次の説明に進みます。

get started, setup, orientation, quickstart, intro, concepts, containers, docker desktop