開発にコンテナを使う¶
事前準備¶
コンテナとしてイメージを実行 で、イメージ構築をし、それコンテナ化アプリケーションとして実行します。
概要¶
この章では、これまでのモジュールで構築したアプリケーションの、ローカル開発環境をセットアップする方法を説明します。イメージの構築には Docker を使い、すべてをとても簡単にする Docker Compose も使います。
ローカルデータベースとコンテナ¶
まず、コンテナでデータベースを実行する方法と、データを保持するためにボリュームとネットワーク機能を使い、アプリケーションがデータベースと通信できるようにする方法を説明します。それから、compose ファイルの中にすべてを入れ込みます。このファイルは1つのコマンドで、ローカル開発環境のセットアップと実行をできるようにします。最後に、コンテナ内で実行しているアプリケーションに、デバッガを接続する方法を説明します。
MongoDB をダウンロードし、インストールし、設定し、Mongo データベースをサービスとして実行する代わりに、MongoDB 用の Docker 公式イメージを使い、コンテナとして実行できるようになります。
コンテナ内で MogoDB を実行する前に、2つのボリュームを作成しておきたいです。これは、Docker が
それでは、ボリュームを作成しましょう。作成するボリュームの1つは MogoDB のデータ用で、もう1つは設定ファイル用です。
$ docker volume create mongodb
$ docker volume create mongodb_config
次は、アプリケーションとデータベースが相互に対話できるようにするためのネットワークを作成します。ネットワークは
$ docker network create mongodb
次は、コンテナとして MongoDB を実行し、先ほど作成したボリュームとネットワークに接続できるようにします。Docker は Hub からイメージを取得し、ローカルでイメージを実行します。
$ docker run -it --rm -d -v mongodb:/data/db \
-v mongodb_config:/data/configdb -p 27017:27017 \
--network mongodb \
--name mongodb \
mongo
うまくいけば、これで MongoDB を実行していますので、 server.js
を更新し、MongoDB を使いメモリ上のデータストアを使わないようにしましょう。
const ronin = require( 'ronin-server' )
const mocks = require( 'ronin-mocks' )
const database = require( 'ronin-database' )
const server = ronin.server()
database.connect( process.env.CONNECTIONSTRING )
server.use( '/', mocks.server( server.Router(), false, false ) )
server.start()
ronin-database
モジュールを追加済みであれば、データベースに接続し、メモリ上のフラグは false にするよう、コードを変更します。そして、コンテナに変更を含めるため、イメージの再構築が必要です。
まず、アプリケーションで npm を使い ronin-database
モジュールを追加しましょう。
$ npm install ronin-database
それから、イメージを構築できます。
$ docker build --tag node-docker .
次はコンテナを実行しましょう。ですが、アプリケーションがデータベースに接続するために使う接続文字列を知るため、環境変数 CONNECTIONSTRING
の設定が今回は必要です。これを docker run
コマンドで実行します。
$ docker run \
-it --rm -d \
--network mongodb \
--name rest-server \
-p 8000:8000 \
-e CONNECTIONSTRING=mongodb://mongodb:27017/notes \
node-docker
接続文字列の最後にある notes
は、データベースの名前です。
アプリケーションをデータベースに接続し、メモを追加できるかどうか確かめましょう。
$ curl --request POST \
--url http://localhost:8000/notes \
--header 'content-type: application/json' \
--data '{"name": "this is a note", "text": "this is a note that I wanted to take while I was working on writing a blog post.", "owner": "peter"}'
サービスからは以下の JSON が返ってくるでしょう。
{"code":"success","payload":{"_id":"5efd0a1552cd422b59d4f994","name":"this is a note","text":"this is a note that I wanted to take while I was working on writing a blog post.","owner":"peter","createDate":"2020-07-01T22:11:33.256Z"}}
Compose を使ってローカルで開発¶
このセクションでは、 node-docker と MongoDB を1つのコマンドで起動するための Compose ファイルを作成します。また、 node-docker をデバッグモードで起動するための Compose ファイルも作成しますので、実行中の node プロセスにデバッガを接続できるようになります。
IDE のメモ機能やテキストエディタを使い、 docker-compose.dev.yml
という名前の新しいファイルを作成します。ファイル内に以下の命令をコピー&ペーストします。
version: '3.8'
services:
notes:
build:
context: .
ports:
- 8000:8000
- 9229:9229
environment:
- SERVER_PORT=8000
- CONNECTIONSTRING=mongodb://mongo:27017/notes
volumes:
- ./:/app
command: npm run debug
mongo:
image: mongo:4.2.8
ports:
- 27017:27017
volumes:
- mongodb:/data/db
- mongodb_config:/data/configdb
volumes:
mongodb:
mongodb_config:
この Compose ファイルは docker run
コマンドに一切パラメータを渡す必要がないため、とても便利です。Compose ファイル内で宣言的にパラメータを指定します。
ポート 9229
を公開していますので、デバッガをアタッチできます。また、ローカルのソースコードを実行中のコンテナにマッピングしていますので、テキストエディタで変更できるだけなく、それらの変更をコンテナに取り込めます。
Compose ファイルを使う上で、もう1つの素晴らしい機能は、サービス名を使ってサービスの名前解決をできるようになります。そのため、接続文字列として mongo
が使えるようになります。 mongo という名前を使えるのは、 MongoDB サービスに対して Compose ファイル内でそのように名付けたからです。
デバッグモードでアプリケーションを起動するには、 package.json
ファイルで、 アプリケーションをデバッグモードで起動するよう、 npm に命令行を追加する必要があります。
package.json
ファイルを開き、scripts セクションに以下の行を追加します。
"debug": "nodemon --inspect=0.0.0.0:9229 server.js"
お分かりのように、 nodemon を使おうとしています。nodemon はサーバをデバッグモードで起動し、ファイルの変更も監視し、変更があればサーバを再起動します。以下のコマンドをターミナルで実行し、プロジェクトのディレクトリ内に nodemon をインストールします。
$ npm install nodemon
アプリケーションを起動し、適切に動作しているか確認しましょう。
$ docker-compose -f docker-compose.dev.yml up --build
--build
フラグを渡したため、 Docker はイメージをコンパイルした後、イメージを起動します。
正常に動作すると、次のような画面が見えます。
それから、API エンドポイントをテストしましょう。以下の curl コマンドを実行します:
$ curl --request GET --url http://localhost:8000/notes
次のような反応を受け取るでしょう:
{"code":"success","meta":{"total":0,"count":0},"payload":[]}
デバッガを接続¶
about:inspect
Open dedicated DevTools for Node ( Node 用の専用 DevTools を開く)のリンクをクリックします。これはコンテナ内で実行している Node.js プロセスに接続した DevTools が開きます。
ソースコードを変更し、ブレイクポイントを設定します。
次のコードを既存の server.use()
宣言の上に追加し、ファイルを保存します。ブレイクポイントを適切に設定できるようにするため、ここで示すように、 return 宣言がその行の中にあるのを確認します。
server.use( '/foo', (req, res) => {
return res.json({ "foo": "bar" })
})
Compose アプリケーションを実行しているターミナルを見ると、nodemon が変更を検出し、アプリケーションを再読み込みします。
Chrome DevTools に移動し直し、 return res.json({ "foo": "bar" })
背源を含むブレイクポイントを設定し、それからブレイクポイントをトリガとするため以下のコマンドを実行します。
$ curl --request GET --url http://localhost:8000/foo
ブレイクポイントでコードが停止するのが見えれば、通常通りにデバッグのために利用できるようになります。変数の調査と監視、ブレイクポイントの条件設定、スタックトレースの表示等ができます。
次のステップ¶
この章では、通常のコマンドラインとほとんど同じように使える、一般的な開発用イメージ作成方法を説明しました。また、 Compose ファイルもセットアップし、ソースコードを実行中のコンテナにマップし、デバッグポイントを公開しました。
次の章では、 Docker で単体テストを実行する方法を説明します。
フィードバック¶
フィードバックを通し、このトピックの改善を支援ください。考えがあれば、 Docker Docs GitHub リポジトリに issue を作成して教えてください。あるいは、更新の提案のために RP を作成 してください。
参考
- Use containers for development