Docker を使用してローカルノード.js開発環境をセットアップする方法

Docker は、最新のアプリケーションを構築し、CI/CD パイプラインを設定するための事実上のツールセットであり、オンプレミスとクラウドのコンテナーでアプリケーションを構築、出荷、実行するのに役立ちます。 

AWS EC2 などのシンプルなコンピューティングインスタンスで実行している場合でも、ホストされている Kubernetes サービスのようなより洗練されたインスタンスで実行している場合でも、Docker のツールセットは新しい BFF です。 

しかし、ローカルノード.js開発環境はどうですか? ローカル開発環境をセットアップしながら、オンボーディングのハードルを調整することは、控えめに言ってもイライラする可能性があります。

特効薬はありませんが、Dockerとそのツールセットの助けを借りて、物事をはるかに簡単にすることができます。

目次:

ローカルノード.js開発環境をセットアップする方法 — パート 1

DockerのMoby DockのクジラがNode.jsロゴの入ったホワイトボードを指差す。

このチュートリアルでは、フロントエンドにReact、いくつかのマイクロサービスにNodeとExpress、データストアにMongoDbを使用する比較的複雑なアプリケーション用にローカルNode.js開発環境を設定する方法について説明します。 Docker を使用してイメージを構築し、Docker Compose を使用してすべてをはるかに簡単にします。

ご質問やご意見がある場合、または単に接続したい場合。 コミュニティSlack または @rumplのTwitterで私に連絡できます。

申し込み

前提 条件

このチュートリアルを完了するには、次のものが必要です。

  • 開発用コンピューターにインストールされている Docker です。 Docker デスクトップをダウンロードしてインストールできます。
  • Docker Hub から Docker ID にサインアップします。
  • 開発用コンピューターに Git がインストールされている。
  • ファイルの編集に使用する IDE またはテキスト エディター。 私はVSCodeをお勧めします。

ステップ 1: コードリポジトリをフォークする

最初に行うことは、コードをローカル開発マシンにダウンロードすることです。 次のgitコマンドを使用してこれを実行してみましょう。

git クローン https://github.com/rumpl/memphis.git

コードがローカルになったので、プロジェクトの構造を見てみましょう。 任意の IDE でコードを開き、ルートレベルのディレクトリを展開します。 次のファイル構造が表示されます。

├── docker-compose.yml
├── ノートサービス
├── リーディングリストサービス
├── ユーザーサービス
└── ヨーダウイ

このアプリケーションは、いくつかの単純なマイクロサービスとReact.jsで記述されたフロントエンドで構成されています。 また、データストアとして MongoDB を使用します。

通常、この時点で、MongoDBのローカルバージョンを開始するか、プロジェクトを調べて、アプリケーションがMongoDBを探す場所を見つけます。 次に、各マイクロサービスを個別に開始し、既定の構成が機能することを期待して UI を起動します。

ただし、これは非常に複雑でイライラする可能性があります。 特に、マイクロサービスが異なるバージョンのNodeを使用していて.js構成が異なる場合。

代わりに、アプリケーションを Docker 化し、データベースをコンテナーに配置することで、このプロセスを簡単にする手順を説明しましょう。 

ステップ 2: アプリケーションを Docker 化する

Dockerは、一貫した開発環境を提供するための優れた方法です。 これにより、各サービスとUIをコンテナで実行できます。 また、ローカルで開発し、1つのdockerコマンドで依存関係を開始できるように設定します。

最初にやりたいことは、各アプリケーションをドッキングすることです。 マイクロサービスはすべて Node.js で記述されており、同じ Dockerfile を使用できるため、マイクロサービスから始めましょう。

ドッカーファイルの作成

メモサービスディレクトリに Dockerfile を作成し、次のコマンドを追加します。

Node.js を使用して notes-service ディレクトリ内の Dockerfile。

これは、Node.jsで使用する非常に基本的なドッカーファイルです。 コマンドに慣れていない場合は、 入門ガイドから始めることができます。 また、リファレンス ドキュメントもご覧ください。

ドッカーイメージの構築

Dockerfile を作成したので、イメージをビルドしましょう。 メモサービスディレクトリにいることを確認し、次のコマンドを実行します。

cd notes-service
docker build -t notes-service .
Docker ビルドターミナルの出力は、ノートサービスディレクトリにあります。

イメージがビルドされたので、それをコンテナーとして実行し、動作していることをテストしましょう。

docker run --rm -p 8081:8081 --name notes notes-service

Docker は、ノートサービスディレクトリにあるターミナル出力を実行します。

このエラーから、mongodbへの接続に問題があることがわかります。 この時点で、次の 2 つのことが壊れています。

  1. アプリケーションに接続文字列を指定しませんでした。
  2. MongoDBはローカルで実行されていません。

これを解決するには、データベースの共有インスタンスに接続文字列を提供できますが、データベースをローカルで管理できるようにし、開発に使用している同僚のデータを台無しにする心配をしないようにする必要があります。 

ステップ 3: ローカライズされたコンテナで MongoDB を実行する

MongoDBをダウンロードする代わりに、Mongoデータベースサービスをインストール、構成、および実行します。 MongoDB用の Docker公式イメージ を使用して、コンテナで実行できます。

コンテナでMongoDBを実行する前に、Dockerが永続的なデータと構成を保存するために管理できるボリュームをいくつか作成する必要があります。 バインドマウントを使用する代わりに、Dockerが提供するマネージドボリュームを使用するのが好きです。 ボリュームに関するすべてのドキュメントを読むことができます。

ドッカー用のボリュームの作成

ボリュームを作成するために、データ用に 1 つ、MongoDB の構成用に 1 つ作成します。

ドッカーボリュームはモンゴッドを作成します

ドッカーボリューム作成mongodb_config

ユーザー定義のブリッジ・ネットワークの作成

次に、アプリケーションとデータベースが相互に通信するために使用するネットワークを作成します。 このネットワークはユーザー定義のブリッジネットワークと呼ばれ、接続文字列を作成するときに使用できる優れたDNSルックアップサービスを提供します。

ドッカーネットワーククリエイトモンゴッド

これで、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

ステップ 4: 環境変数を設定する

MongoDB が実行されたので、アプリケーションがリッスンするポートとデータベースへのアクセスに使用する接続文字列を認識できるように、いくつかの環境変数も設定する必要があります。 これは、docker runコマンドで正しく行います。

docker run \
-it --rm -d \
--network mongodb \
--name notes \
-p 8081:8081 \
-e SERVER_PORT=8081 \
-e SERVER_PORT=8081 \
-e DATABASE_CONNECTIONSTRING=mongodb://mongodb:27017/yoda_notes \
notes-service

ステップ 5: データベース接続をテストする

アプリケーションがデータベースに接続され、メモを追加できることをテストしましょう。

curl --request POST \
--url http://localhost:8081/services/m/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"}}

テストが完了したら、「docker stop notes mongodb」を実行してコンテナを停止します。

すごい!Node.js のローカル開発環境の Docker 化の最初の手順を完了しました。 パートIIでは、Docker Composeを使用して、先ほど実行したプロセスを簡素化する方法について説明します。

ローカルノード.js開発環境をセットアップする方法 — パート 2

パート I では、Docker イメージの作成と Node.js アプリケーション用のコンテナーの実行について説明しました。 また、コンテナーでのデータベースの設定と、ローカル開発環境のセットアップでボリュームとネットワークがどのように役割を果たすかについても説明しました。

パートIIでは、コンパイル、モジュールの追加、アプリケーションのデバッグをすべてコンテナ内で行うことができる開発イメージの作成と実行について説明します。 これにより、新しいアプリケーションまたはプロジェクトに移行する際の開発者のセットアップ時間を短縮できます。 この場合、イメージには Node.js と NPM または YARN がインストールされている必要があります。 

また、Docker Compose を使用して、開発マシン上で完全なマイクロサービス アプリケーションをローカルに設定して実行するプロセスを合理化する方法についても簡単に説明します。

Node.js アプリケーションの実行に使用できる開発イメージを作成しましょう。

ステップ 1: ドッカーファイルを開発する

開発用コンピューターにローカル ディレクトリを作成し、Dockerfile や開発イメージに必要なその他のファイルを保存するための作業ディレクトリとして使用できます。

$ mkdir -p ~/projects/dev-image

このフォルダーに Dockerfile を作成し、次のコマンドを追加します。

FROM node:18.7.0
RUN apt-get update && apt-get install -y \
  nano \
  Vim

まず、node:18.7.0 の公式イメージを使用します。 このイメージは開発イメージの作成に適していることがわかりました。 コンテナ内でファイルをすばやく編集したい場合に備えて、画像にいくつかのテキストエディタを追加するのが好きです。

基本イメージの ENTRYPOINT に依存し、イメージの開始時に CMD をオーバーライドするため、Dockerfile に ENTRYPOINT または CMD を追加しませんでした。

ステップ 2: Docker イメージをビルドする

イメージを構築しましょう。

$ docker build -t node-dev-image .

そして今、私たちはそれを実行することができます。

$ docker run -it --rm --name dev -v $(pwd):/code node-dev-image bash

bashコマンドプロンプトが表示されます。 これで、コンテナー内で JavaScript ファイルを作成し、Node.js で実行できます。

ステップ 3: イメージをテストする

次のコマンドを実行して、イメージをテストします。

$ node -e 'console.log("hello from inside our container")'
hello from inside our container

すべてがうまくいけば、実用的な開発イメージがあります。 これで、通常のbashターミナルで行うすべてのことを実行できます。

上記の Docker コマンドを notes-service ディレクトリ内で実行すると、コンテナ内のコードにアクセスできるようになります。 notesサービスを開始するには、/codeディレクトリに移動して実行します npm run start

ステップ 4: 作成を使用してローカルで開発する

ノートサービスプロジェクトは、データストアとして MongoDB を使用します。 パートIで覚えていると思いますが、Mongoコンテナを手動で起動し、メモサービスと同じネットワークに接続する必要がありました。 また、アプリケーションとMongoDBを再起動してもデータを保持できるように、いくつかのボリュームを作成する必要がありました。

代わりに、1つのコマンドでノートサービスとMongoDbを開始するための作成ファイルを作成します。 また、デバッグモードでノートサービスを開始するように作成ファイルを設定します。 このようにして、デバッガーを実行中のノードプロセスに接続できます。

任意の IDE またはテキストエディタでノートサービスを開き、docker-compose.dev.yml という名前の新しいファイルを作成します。 以下のコマンドをコピーしてファイルに貼り付けます。

services:
 notes:
   build:
     context: .
   ports:
     - 8080:8080
     - 9229:9229
   environment:
     - SERVER_PORT=8080
     - DATABASE_CONNECTIONSTRING=mongodb://mongo:27017/notes
   volumes:
     - ./:/code
   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:


この作成ファイルは、「docker run」コマンドに渡すためにすべてのパラメーターを入力する必要がないため、非常に便利です。 作成ファイルで宣言的にそれを行うことができます。

デバッガーをアタッチできるように、ポート 9229 を公開しています。 また、ローカルソースコードを実行中のコンテナにマッピングして、テキストエディタで変更を加え、それらの変更をコンテナで取得できるようにしています。

作成ファイルを使用するもう1つの本当に優れた機能は、サービス名を使用するためのサービス解決が設定されていることです。 その結果、接続文字列に "mongo" を使用できるようになりました。 「mongo」を使用するのは、それが作成ファイルでmongoサービスに名前を付けたためです。

アプリケーションを起動して、正しく実行されていることを確認しましょう。

$ docker compose -f docker-compose.dev.yml up --build

"–build" フラグを渡して、Docker がイメージをコンパイルしてから起動するようにします。

すべてがうまくいけば、メモとmongoサービスからのログが表示されます。

Dockerは、メモとmongoサービスからのログを表示するターミナル出力を作成します。
[クリックで拡大]

次に、API エンドポイントをテストしましょう。 次の curl コマンドを実行します。

$ curl --request GET --url http://localhost:8080/services/m/notes

次の応答が表示されます。

{"コード":"成功","メタ":{"合計":0,"カウント":0},"ペイロード":[]}

ステップ 5: デバッガーに接続する

Chromeブラウザに付属のデバッガを使用します。 マシンでChromeを開き、アドレスバーに次のように入力します。

概要:検査

以下の画面が開きます。

DevTools は Chrome ブラウザーで機能し、デバイスとリモート ターゲットの一覧を表示します。

[ノード専用の開発ツールを開く] リンクをクリックします。 これにより、コンテナー内の実行中の Node.js プロセスに接続されている DevTools が開きます。

ソース コードを変更してから、ブレークポイントを設定しましょう。 

次のコードを 19 行目の server.js ファイルに追加し、ファイルを保存します。

server.use( '/foo', (req, res) => {
   return res.json({ "foo": "bar" })
 })

作成アプリケーションが実行されているターミナルを見ると、nodemonが変更に気づき、アプリケーションをリロードしていることがわかります。

Docker は、nodemon でリロードされたアプリケーションを示すターミナル出力を作成します。
[クリックで拡大]

Chrome 開発ツールに戻り、20 行目にブレークポイントを設定します。 次に、次の curl コマンドを実行してブレークポイントをトリガーします。

$ curl --request GET --url http://localhost:8080/foo

ブーム 20行目でコードが壊れているのを見たはずですが、今では通常と同じようにデバッガを使用することができます。 変数の検査と監視、条件付きブレークポイントの設定、スタックトレースの表示など、さまざまなことができます。

結論

この記事では、Node.js のローカル開発環境の Docker 化の最初の手順を完了しました。 次に、さらに一歩進んで、通常のコマンドラインのように使用できる一般的な開発イメージを作成しました。 また、ソース コードを実行中のコンテナーにマップするように作成ファイルを設定し、デバッグ ポートを公開しました。

さらに詳しく