バインド マウント(bind mount) の使用

前章では、データベース内のデータを保持するため、 名前付きボリューム(named volume) を使う方法を説明しました。シンプルにデータを保存したい場合には、名前付きボリュームは優れていますが、「どこ」にデータが保管されているか心配したくありません。

バインド マウント(bind mount) であれば、ホスト上の正確なマウントポイントを管理できます。バインド マウントはデータ保持に使えますが、使用時はコンテナに対する追加データの指定が度々必要です。アプリケーションの動作中でも、バインド マウントを使ってソースコードをコンテナ内にマウントすると、コードの変更が見えたり反映したりできるようになります。つまり、アプリケーションに対する変更は、直ちに見えるでしょう。

Node をベースとするアプリケーション nodemon は素晴らしいツールです。ファイルの変更を監視し、アプリケーションを再起動します。他の言語やフレームワークでも、同様なツールがあります。

ボリューム型の素早い比較

バインド マウントと名前付きボリュームは、Docker Engine に組み込まれている2つの主なボリューム型です。しかしながら、他の利用例( SFTPCephNetAppS3 、 等)をサポートする追加ボリュームドライバが利用可能です。

  名前付きボリューム バインド マウント
ホスト上の場所 Docker が選択 自分で管理
マウント例( -v を使用) my-volume:/usr/local/data /path/to/data:/usr/local/data
コンテナの内容に新しいボリュームを加える はい いいえ
ボリューム ドライバのサポート はい いいえ

開発モードのコンテナを起動

開発ワークフローをサポートするコンテナを実行するには、以下の作業をします。

  • ソースコードをコンテナ内にマウント
  • 「dev」(開発段階の)依存関係を含む、全ての依存関係をインストール
  • ファイルシステムの変更を監視する nodemon を監視

それでは、やってみましょう!

  1. これまでの getting-started コンテナを実行していないのを確認します。
  1. app ディレクトリで以下のコマンドを実行します。何をしようとしているかは、後ほど説明します。

    $ 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 … 以前と同じです。 デタッチド(detached) (バックグラウンド)モードで実行し、 ポート割り当て(port mapping) を作成
    • -w /app … コマンドを実行する場所として、「 作業ディレクトリ(working directory) 」またはカレント ディレクトリを指定
    • -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 を開始する
  1. 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 を実行します。

  1. 次は、アプリを変更しましょう。 src/static/js/app.js ファイル内で、「Add Item」ボタンを、シンプルに「Add」と表示するように変えます。変更には 109 行目を変えるだけです。

    -                         {submitting ? 'Adding...' : 'Add Item'}
    +                         {submitting ? 'Adding...' : 'Add'}
    
  1. ページを単に再読み込みすると(あるいは、ページを開きます)、ほぼ直ちにブラウザに変更が反映しているのが分かるでしょう。Node サーバの再起動には、数秒かかるかもしれず、もしエラーが出てしまった場合には、数秒後に再起動を試してください。

    Add ボタンのラベルを更新したスクリーンショット
  1. あとは作りたいように他にも自由に変更します。終わったら、コンテナを停止し、以下のコマンドを使って新しいイメージを構築します。

    $ docker build -t getting-started .
    

バインド マウントの使用は、ローカル開発のセットアップで「非常に」一般的です。この利点は、開発マシンに全ての構築ツールや環境を入れる必要がないからです。 docker run コマンド1つだけで、開発環境を持ってきて、すぐに始められます。後のステップで、(たくさんのフラグ指定が必要な)コマンド実行を簡単にするのに役立つ Docker Compose を説明します。

まとめ

これで、データベースを保持し、必要に応じて素早く対応でき、投資家や創設者の要望に応えられるようになりました。やった! 良いニュースが届きました!

あなたのプロジェクトが今後の開発対象として選ばれました!

本番環境を準備するには、データベースを SQLite からスケール可能な何かへ以降する必要があります。扱いやすさのため、関係データベースを使い続け、アプリケーションが MySQL を使うように切り替えます。ですが、どうやって MySQL を動かせばよいのでしょうか? どのようにしてコンテナ間がお互いに通信できるのでしょうか? 次で解説します。

参考

Part 6: User bind mounts
https://docs.docker.com/get-started/06_bind_mounts/