序章

アプリケーションを積極的に開発している場合は、 Docker を使用すると、ワークフローとアプリケーションを本番環境にデプロイするプロセスを簡素化できます。 開発中のコンテナを使用すると、次の利点があります。

  • 環境は一貫しています。つまり、システムの競合を心配することなく、プロジェクトに必要な言語と依存関係を選択できます。
  • 環境が分離されているため、問題のトラブルシューティングや新しいチームメンバーの参加が容易になります。
  • 環境は移植可能であり、コードをパッケージ化して他の人と共有することができます。

このチュートリアルでは、Dockerを使用してNode.jsアプリケーションの開発環境をセットアップする方法を説明します。 Docker Compose を使用して、2つのコンテナー(1つはNodeアプリケーション用、もう1つは MongoDB データベース用)を作成します。 このアプリケーションはNodeとMongoDBで動作するため、セットアップでは次のようになります。

  • ホスト上のアプリケーションコードをコンテナ内のコードと同期して、開発中の変更を容易にします。
  • アプリケーションコードへの変更が再起動せずに機能することを確認します。
  • アプリケーションのデータ用にユーザーとパスワードで保護されたデータベースを作成します。
  • このデータを永続化します。

このチュートリアルの最後に、Dockerコンテナで実行されている動作するサメ情報アプリケーションがあります。

前提条件

このチュートリアルに従うには、次のものが必要です。

  • Ubuntu 18.04を実行している開発サーバーと、root以外のユーザー sudo 特権とアクティブなファイアウォール。 これらの設定方法のガイダンスについては、この初期サーバー設定ガイドを参照してください。
  • Ubuntu18.04にDockerをインストールして使用する方法の手順1と2に従ってサーバーにDockerをインストールします。
  • Ubuntu 18.04にDockerComposeをインストールする方法のステップ1に従って、サーバーにDockerComposeをインストールします。

ステップ1—プロジェクトのクローンを作成して依存関係を変更する

このセットアップを構築する最初のステップは、プロジェクトコードのクローンを作成し、プロジェクトの依存関係を含むpackage.jsonファイルを変更することです。 nodemonをプロジェクトのdevDependenciesに追加し、開発中に使用することを指定します。 でアプリケーションを実行する nodemon コードに変更を加えるたびに自動的に再起動されるようにします。

まず、 DigitalOceanCommunityGitHubアカウントからnodejs-mongo-mongooseリポジトリのクローンを作成します。 このリポジトリには、 MongoDBをノードアプリケーションと統合する方法で説明されているセットアップのコードが含まれています。このコードでは、Mongooseを使用してMongoDBデータベースを既存のノードアプリケーションと統合する方法について説明しています。

リポジトリをと呼ばれるディレクトリに複製します node_project:

  1. git clone https://github.com/do-community/nodejs-mongo-mongoose.git node_project

に移動します node_project ディレクトリ:

  1. cd node_project

プロジェクトを開きます package.json を使用してファイル nano またはお気に入りの編集者:

  1. nano package.json

プロジェクトの依存関係の下と閉じ中括弧の上に、新しい中括弧を作成します devDependencies を含むオブジェクト nodemon:

〜/ node_project / package.json
...
"dependencies": {
    "ejs": "^2.6.1",
    "express": "^4.16.4",
    "mongoose": "^5.4.10"
  },
  "devDependencies": {
    "nodemon": "^1.18.10"
  }    
}

編集が終了したら、ファイルを保存して閉じます。

プロジェクトコードを配置し、その依存関係を変更したら、コンテナ化されたワークフローのコードのリファクタリングに進むことができます。

ステップ2—コンテナを操作するようにアプリケーションを構成する

コンテナ化されたワークフロー用にアプリケーションを変更することは、コードをよりモジュール化することを意味します。 コンテナは環境間の移植性を提供します。コードは、基盤となるオペレーティングシステムから可能な限り分離されたままにすることで、それを反映する必要があります。 これを実現するために、コードをリファクタリングして、ノードの process.env プロパティをさらに活用します。このプロパティは、実行時にユーザー環境に関する情報を含むオブジェクトを返します。 コードでこのオブジェクトを使用して、実行時に環境変数を使用して構成情報を動的に割り当てることができます。

から始めましょう app.js、メインアプリケーションのエントリポイント。 ファイルを開きます。

  1. nano app.js

内部には、の定義が表示されます port 定数、およびこの定数を使用してアプリケーションがリッスンするポートを指定するリッスン関数

〜/ home / node_project / app.js
...
const port = 8080;
...
app.listen(port, function () {
  console.log('Example app listening on port 8080!');
});

再定義しましょう port を使用して実行時に動的な割り当てを可能にする定数 process.env 物体。 定数定義に次の変更を加え、 listen 関数:

〜/ home / node_project / app.js
...
const port = process.env.PORT || 8080;
...
app.listen(port, function () {
  console.log(`Example app listening on ${port}!`);
});

私たちの新しい定数定義は port 実行時に渡された値を動的に使用するか、 8080. 同様に、 listen テンプレートリテラルを使用する関数。これは、接続をリッスンするときにポート値を補間します。 ポートを他の場所にマッピングするため、これらのリビジョンにより、環境の変化に応じてこのファイルを継続的にリビジョンする必要がなくなります。

編集が終了したら、ファイルを保存して閉じます。

次に、データベース接続情報を変更して、構成資格情報を削除します。 を開きます db.js この情報を含むファイル:

  1. nano db.js

現在、ファイルは次のことを行います。

  • アプリケーションデータのスキーマとモデルを作成するために使用しているObjectDocument Mapper (ODM)であるMongooseをインポートします。
  • データベースのクレデンシャルを、ユーザー名とパスワードを含む定数として設定します。
  • mongoose.connectメソッドを使用してデータベースに接続します。

ファイルの詳細については、MongoDBをノードアプリケーションと統合する方法ステップ3を参照してください。

ファイルを変更する最初のステップは、機密情報を含む定数を再定義することです。 現在、これらの定数は次のようになっています。

〜/ node_project / db.js
...
const MONGO_USERNAME = 'sammy';
const MONGO_PASSWORD = 'your_password';
const MONGO_HOSTNAME = '127.0.0.1';
const MONGO_PORT = '27017';
const MONGO_DB = 'sharkinfo';
...

この情報をハードコーディングする代わりに、 process.env これらの定数の実行時値をキャプチャするオブジェクト。 次のようにブロックを変更します。

〜/ node_project / db.js
...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;
...

編集が終了したら、ファイルを保存して閉じます。

この時点で、変更しました db.js アプリケーションの環境変数を操作するには、これらの変数をアプリケーションに渡す方法が必要です。 を作成しましょう .env 実行時にアプリケーションに渡すことができる値を含むファイル。

ファイルを開きます。

  1. nano .env

このファイルには、削除した情報が含まれます db.js:アプリケーションのデータベースのユーザー名とパスワード、およびポート設定とデータベース名。 ここにリストされているユーザー名、パスワード、およびデータベース名を、自分の情報で更新することを忘れないでください。

〜/ node_project / .env
MONGO_USERNAME=sammy
MONGO_PASSWORD=your_password
MONGO_PORT=27017
MONGO_DB=sharkinfo

元々表示されていたホスト設定を削除していることに注意してください db.js. ここで、Docker Composeファイルのレベルでホストを定義し、サービスとコンテナーに関するその他の情報を示します。

編集が終了したら、このファイルを保存して閉じます。

あなたの .env ファイルに機密情報が含まれている場合は、それがプロジェクトに含まれていることを確認する必要があります .dockerignore.gitignore バージョン管理またはコンテナにコピーされないようにファイルを作成します。

あなたの .dockerignore ファイル:

  1. nano .dockerignore

ファイルの最後に次の行を追加します。

〜/ node_project / .dockerignore
...
.gitignore
.env

編集が終了したら、ファイルを保存して閉じます。

The .gitignore このリポジトリのファイルにはすでに含まれています .env、ただし、そこにあることを確認してください。

  1. nano .gitignore
~~ / node_project / .gitignore
...
.env
...

この時点で、プロジェクトコードから機密情報を正常に抽出し、この情報をコピーする方法と場所を制御するための対策を講じています。 これで、データベース接続コードに堅牢性を追加して、コンテナー化されたワークフロー用に最適化できます。

手順3—データベース接続設定の変更

次のステップは、アプリケーションがデータベースに接続できない場合を処理するコードを追加することにより、データベース接続方法をより堅牢にすることです。 このレベルの復元力をアプリケーションコードに導入することは、Composeを使用してコンテナーを操作する場合の推奨プラクティスです。

開ける db.js 編集用:

  1. nano db.js

以前に追加したコードと、 url Mongoの接続URIとMongooseconnectメソッドの定数:

〜/ node_project / db.js
...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;

mongoose.connect(url, {useNewUrlParser: true});

現在、私たちの connect メソッドは、Mongoの新しいURLパーサーを使用するようにMongooseに指示するオプションを受け入れます。 このメソッドにさらにいくつかのオプションを追加して、再接続を試行するためのパラメーターを定義しましょう。 これを行うには、 options 新しいURLパーサーオプションに加えて、関連情報を含む定数。 Mongo定数の下に、次の定義を追加します。 options 絶え間ない:

〜/ node_project / db.js
...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

const options = {
  useNewUrlParser: true,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 500, 
  connectTimeoutMS: 10000,
};
...

The reconnectTries オプションは、Mongooseに無期限に接続を試み続けるように指示します。 reconnectInterval 接続試行間の期間をミリ秒単位で定義します。 connectTimeoutMS 接続の試行に失敗する前にMongoドライバーが待機する期間として10秒を定義します。

これで、新しいものを使用できます options マングースで一定 connect マングースの接続設定を微調整する方法。 また、潜在的な接続エラーを処理するためにpromiseを追加します。

現在、マングース connect メソッドは次のようになります。

〜/ node_project / db.js
...
mongoose.connect(url, {useNewUrlParser: true});

既存のものを削除する connect メソッドを使用して、次のコードに置き換えます。 options 定数と約束:

〜/ node_project / db.js
...
mongoose.connect(url, options).then( function() {
  console.log('MongoDB is connected');
})
  .catch( function(err) {
  console.log(err);
});

接続が成功した場合、関数は適切なメッセージをログに記録します。 それ以外の場合は、をキャッチしてエラーをログに記録し、トラブルシューティングを可能にします。

完成したファイルは次のようになります。

〜/ node_project / db.js
const mongoose = require('mongoose');

const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

const options = {
  useNewUrlParser: true,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 500,
  connectTimeoutMS: 10000,
};

const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;

mongoose.connect(url, options).then( function() {
  console.log('MongoDB is connected');
})
  .catch( function(err) {
  console.log(err);
});

編集が終了したら、ファイルを保存して閉じます。

これで、アプリケーションがデータベースに接続できない可能性がある場合に対処するために、アプリケーションコードに復元力が追加されました。 このコードを配置すると、Composeを使用したサービスの定義に進むことができます。

ステップ4—DockerComposeを使用したサービスの定義

コードをリファクタリングすると、次のように記述できます。 docker-compose.yml サービス定義をファイルします。 Composeのserviceは実行中のコンテナーであり、サービス定義—これをユーザーに含めます docker-compose.yml file —各コンテナイメージの実行方法に関する情報が含まれています。 作成ツールを使用すると、複数のサービスを定義して、マルチコンテナーアプリケーションを構築できます。

ただし、サービスを定義する前に、 wait-for というツールをプロジェクトに追加して、データベースの起動タスクが完了した後にのみアプリケーションがデータベースへの接続を試行するようにします。 このラッパースクリプトは、 netcat を使用して、特定のホストとポートがTCP接続を受け入れているかどうかをポーリングします。 これを使用すると、データベースが接続を受け入れる準備ができているかどうかをテストすることにより、アプリケーションのデータベースへの接続の試行を制御できます。

Composeではdepends_onオプションを使用してサービス間の依存関係を指定できますが、この順序は、コンテナーの準備ではなく、コンテナーが実行されているかどうかに基づいています。 使用する depends_on ユーザーとパスワードの追加を含むデータベースの起動タスク時にのみアプリケーションを接続する必要があるため、セットアップには最適ではありません。 admin 認証データベースが完成しました。 使用の詳細については wait-for および起動順序を制御するその他のツールについては、作成ドキュメントの関連する推奨事項を参照してください。

というファイルを開きます wait-for.sh:

  1. nano wait-for.sh

次のコードをファイルに貼り付けて、ポーリング関数を作成します。

〜/ node_project / app / wait-for.sh
#!/bin/sh

# original script: https://github.com/eficode/wait-for/blob/master/wait-for

TIMEOUT=15
QUIET=0

echoerr() {
  if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
}

usage() {
  exitcode="$1"
  cat << USAGE >&2
Usage:
  $cmdname host:port [-t timeout] [-- command args]
  -q | --quiet                        Do not output any status messages
  -t TIMEOUT | --timeout=timeout      Timeout in seconds, zero for no timeout
  -- COMMAND ARGS                     Execute command with args after the test finishes
USAGE
  exit "$exitcode"
}

wait_for() {
  for i in `seq $TIMEOUT` ; do
    nc -z "$HOST" "$PORT" > /dev/null 2>&1
    
    result=$?
    if [ $result -eq 0 ] ; then
      if [ $# -gt 0 ] ; then
        exec "$@"
      fi
      exit 0
    fi
    sleep 1
  done
  echo "Operation timed out" >&2
  exit 1
}

while [ $# -gt 0 ]
do
  case "$1" in
    *:* )
    HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
    PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
    shift 1
    ;;
    -q | --quiet)
    QUIET=1
    shift 1
    ;;
    -t)
    TIMEOUT="$2"
    if [ "$TIMEOUT" = "" ]; then break; fi
    shift 2
    ;;
    --timeout=*)
    TIMEOUT="${1#*=}"
    shift 1
    ;;
    --)
    shift
    break
    ;;
    --help)
    usage 0
    ;;
    *)
    echoerr "Unknown argument: $1"
    usage 1
    ;;
  esac
done

if [ "$HOST" = "" -o "$PORT" = "" ]; then
  echoerr "Error: you need to provide a host and port to test."
  usage 2
fi

wait_for "$@"

コードの追加が完了したら、ファイルを保存して閉じます。

スクリプトを実行可能にします。

  1. chmod +x wait-for.sh

次に、 docker-compose.yml ファイル:

  1. nano docker-compose.yml

まず、を定義します nodejs 次のコードをファイルに追加して、アプリケーションサービスを実行します。

〜/ node_project / docker-compose.yml
version: '3'

services:
  nodejs:
    build:
      context: .
      dockerfile: Dockerfile
    image: nodejs
    container_name: nodejs
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=db
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB 
    ports:
      - "80:8080"
    volumes:
      - .:/home/node/app
      - node_modules:/home/node/app/node_modules
    networks:
      - app-network
    command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js

The nodejs サービス定義には、次のオプションが含まれます。

  • build:これは、以下を含む構成オプションを定義します。 contextdockerfile、これは、Composeがアプリケーションイメージをビルドするときに適用されます。 Docker Hub などのレジストリの既存のイメージを使用する場合は、代わりに image命令を使用して、ユーザー名、リポジトリ、イメージタグに関する情報を使用できます。

  • context:これは、イメージビルドのビルドコンテキスト(この場合は現在のプロジェクトディレクトリ)を定義します。

  • dockerfile:これは Dockerfile Composeがアプリケーションイメージのビルドに使用するファイルとして、現在のプロジェクトディレクトリにあります。 このファイルの詳細については、Dockerを使用してNode.jsアプリケーションを構築する方法を参照してください。

  • image, container_name:これらは画像とコンテナに名前を適用します。

  • restart:これは再起動ポリシーを定義します。 デフォルトは no、ただし、コンテナが停止しない限り再起動するように設定しました。

  • env_file:これは、Composeに、というファイルから環境変数を追加することを通知します。 .env、ビルドコンテキストにあります。

  • environment:このオプションを使用すると、で定義したMongo接続設定を追加できます。 .env ファイル。 設定していないことに注意してください NODE_ENVdevelopment、これはExpressのデフォルトの動作であるため NODE_ENV 設定されていません。 本番環境に移行するときは、これを次のように設定できます。 production ビューのキャッシュを有効にし、エラーメッセージの詳細を減らします。 また、指定したことに注意してください db ステップ2で説明されているように、ホストとしてのデータベースコンテナ。

  • ports:これはポートをマップします 80 ホストからポートへ 8080 コンテナに。

  • volumes:ここには2種類のマウントが含まれています:

    • 1つ目は、 bind mount で、ホスト上のアプリケーションコードをにマウントします。 /home/node/app コンテナのディレクトリ。 これにより、ホストコードに加えた変更がすぐにコンテナに入力されるため、迅速な開発が容易になります。
    • 2つ目は、 volume という名前で、 node_modules. Dockerを実行すると npm install アプリケーションにリストされている命令 Dockerfile, npm アプリケーションの実行に必要なパッケージを含むコンテナに新しいnode_modulesディレクトリを作成します。 作成したバインドマウントは、この新しく作成されたものを非表示にします node_modules ただし、ディレクトリ。 以来 node_modules ホストが空の場合、バインドは空のディレクトリをコンテナにマップし、新しいディレクトリをオーバーライドします node_modules ディレクトリを作成し、アプリケーションが起動しないようにします。 名前付き node_modules ボリュームは、コンテンツを永続化することでこの問題を解決します /home/node/app/node_modules ディレクトリとそれをコンテナにマウントし、バインドを非表示にします。

    このアプローチを使用するときは、次の点に注意してください

    • バインドは、の内容をマウントします node_modules ホストへのコンテナ上のディレクトリとこのディレクトリはによって所有されます root、名前付きボリュームはDockerによって作成されたため。
    • 既存の場合 node_modules ホスト上のディレクトリ、それはオーバーライドします node_modules コンテナ上に作成されたディレクトリ。 このチュートリアルで構築しているセットアップは、に存在しないことを前提としています。 node_modules ディレクトリとあなたが作業しないこと npm あなたのホストで。 これは、実行環境間の依存関係を最小限に抑えるアプリケーション開発への12要素アプローチと一致しています。
  • networks:これは、アプリケーションサービスが参加することを指定します app-network ネットワーク。ファイルの下部で定義します。

  • command:このオプションを使用すると、Composeがイメージを実行するときに実行するコマンドを設定できます。 これはオーバーライドすることに注意してください CMD アプリケーションで設定した命令 Dockerfile. ここでは、を使用してアプリケーションを実行しています wait-for スクリプト、ポーリングします db ポートでのサービス 27017 データベースサービスの準備ができているかどうかをテストします。 準備テストが成功すると、スクリプトは設定したコマンドを実行します。 /home/node/app/node_modules/.bin/nodemon app.js、でアプリケーションを開始するには nodemon. これにより、アプリケーションを再起動しなくても、コードに加えた将来の変更が確実に再ロードされます。

次に、を作成します db アプリケーションサービス定義の下に次のコードを追加して、サービスを提供します。

〜/ node_project / docker-compose.yml
...
  db:
    image: mongo:4.1.8-xenial
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
    volumes:  
      - dbdata:/data/db   
    networks:
      - app-network  

に定義した設定の一部 nodejs サービスは同じままですが、次の変更も加えました。 image, environment、 と volumes 定義:

  • image:このサービスを作成するために、Composeは 4.1.8-xenial DockerHubのMongoイメージ。 Mongoイメージが変更されたときに発生する可能性のある将来の競合を回避するために、特定のバージョンを固定しています。 バージョンの固定の詳細については、Dockerfileのベストプラクティスに関するDockerのドキュメントを参照してください。
  • MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORDmongo imageは、これらの環境変数を使用可能にして、データベースインスタンスの初期化を変更できるようにします。 MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD 一緒に作成します root のユーザー admin 認証データベースを作成し、コンテナの起動時に認証が有効になっていることを確認します。 設定しました MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD 私たちの値を使用して .env ファイル、これを db を使用したサービス env_file オプション。 これを行うことは、 sammy アプリケーションユーザーは、データベースインスタンスの rootユーザーになり、そのロールのすべての管理特権と操作特権にアクセスできます。 本番環境で作業する場合は、適切なスコープの特権を持つ専用のアプリケーションユーザーを作成する必要があります。 <$>[注] ノート: 既存のデータディレクトリを配置してコンテナを起動した場合、これらの変数は有効にならないことに注意してください。 <$>
  • dbdata:/data/db:指定されたボリューム dbdata Mongoのデフォルトデータディレクトリに保存されているデータを保持します。 /data/db. これにより、コンテナを停止または削除した場合にデータが失われることがなくなります。

また、 db へのサービス app-network とのネットワーク networks オプション。

最後のステップとして、ボリュームとネットワークの定義をファイルの最後に追加します。

〜/ node_project / docker-compose.yml
...
networks:
  app-network:
    driver: bridge

volumes:
  dbdata:
  node_modules:  

ユーザー定義のブリッジネットワーク app-network コンテナは同じDockerデーモンホスト上にあるため、コンテナ間の通信を有効にします。 これにより、アプリケーション内のトラフィックと通信が合理化されます。これは、同じブリッジネットワーク上のコンテナ間のすべてのポートを開き、ポートを外部に公開しないためです。 したがって、私たちの dbnodejs コンテナは相互に通信でき、ポートを公開するだけで済みます 80 アプリケーションへのフロントエンドアクセス用。

私たちのトップレベル volumes キーはボリュームを定義します dbdatanode_modules. Dockerがボリュームを作成すると、ボリュームのコンテンツはホストファイルシステムの一部に保存されます。 /var/lib/docker/volumes/、それはDockerによって管理されています。 各ボリュームの内容は、下のディレクトリに保存されます /var/lib/docker/volumes/ ボリュームを使用する任意のコンテナにマウントされます。 このようにして、ユーザーが作成するサメの情報データは、 dbdata 削除して再作成してもボリューム db 容器。

完成した docker-compose.yml ファイルは次のようになります。

〜/ node_project / docker-compose.yml
version: '3'

services:
  nodejs:
    build:
      context: .
      dockerfile: Dockerfile
    image: nodejs
    container_name: nodejs
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=db
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB
    ports:
      - "80:8080"
    volumes:
      - .:/home/node/app
      - node_modules:/home/node/app/node_modules
    networks:
      - app-network
    command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js 

  db:
    image: mongo:4.1.8-xenial
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
    volumes:     
      - dbdata:/data/db
    networks:
      - app-network  

networks:
  app-network:
    driver: bridge

volumes:
  dbdata:
  node_modules:  

編集が終了したら、ファイルを保存して閉じます。

サービス定義が整ったら、アプリケーションを開始する準備が整います。

ステップ5—アプリケーションのテスト

あなたと docker-compose.yml ファイルを配置したら、 docker-composeupコマンドを使用してサービスを作成できます。 docker-compose down を使用してコンテナーを停止および削除することにより、データが保持されることをテストすることもできます。

まず、コンテナイメージを構築し、を実行してサービスを作成します docker-compose up とともに -d フラグ、次に実行されます nodejsdb バックグラウンドのコンテナ:

  1. docker-compose up -d

サービスが作成されたことを確認する出力が表示されます。

Output
... Creating db ... done Creating nodejs ... done

また、サービスからのログ出力を表示することにより、起動プロセスに関するより詳細な情報を取得できます。

  1. docker-compose logs

すべてが正しく開始されている場合は、次のように表示されます。

Output
... nodejs | [nodemon] starting `node app.js` nodejs | Example app listening on 8080! nodejs | MongoDB is connected ... db | 2019-02-22T17:26:27.329+0000 I ACCESS [conn2] Successfully authenticated as principal sammy on admin

docker-compose ps を使用して、コンテナーのステータスを確認することもできます。

  1. docker-compose ps

コンテナが実行されていることを示す出力が表示されます。

Output
Name Command State Ports ---------------------------------------------------------------------- db docker-entrypoint.sh mongod Up 27017/tcp nodejs ./wait-for.sh db:27017 -- ... Up 0.0.0.0:80->8080/tcp

あなたのサービスが実行されていると、あなたは訪問することができます http://your_server_ip ブラウザで。 次のようなランディングページが表示されます。

Get SharkInfoボタンをクリックします。 サメの名前とそのサメの一般的な性格の説明を入力できる入力フォームのあるページが表示されます。

フォームに、選択したサメを追加します。 このデモンストレーションの目的で、追加します Megalodon Shark Shark Name フィールドに移動し、 Ancient Shark Character フィールドへ:

送信ボタンをクリックします。 このサメの情報が表示されたページが表示されます。

最後のステップとして、データベースコンテナを削除しても、入力したデータが保持されることをテストできます。

ターミナルに戻り、次のコマンドを入力して、コンテナとネットワークを停止および削除します。

  1. docker-compose down

私たちはではなくであることに注意してください --volumes オプション; したがって、私たちの dbdata ボリュームは削除されません。

次の出力は、コンテナとネットワークが削除されたことを確認します。

Output
Stopping nodejs ... done Stopping db ... done Removing nodejs ... done Removing db ... done Removing network node_project_app-network

コンテナを再作成します。

  1. docker-compose up -d

次に、サメ情報フォームに戻ります。

お好みの新しいサメを入力してください。 一緒に行きます Whale SharkLarge:

送信をクリックすると、入力済みのデータを失うことなく、新しいサメがデータベースのサメコレクションに追加されたことがわかります。

これで、アプリケーションは、データの永続性とコードの同期が有効になっているDockerコンテナで実行されます。

結論

このチュートリアルに従うことで、Dockerコンテナーを使用してNodeアプリケーションの開発セットアップを作成しました。 機密情報を抽出し、アプリケーションの状態をアプリケーションコードから切り離すことで、プロジェクトをよりモジュール化して移植性の高いものにしました。 ボイラープレートも構成しました docker-compose.yml 開発のニーズや要件の変化に応じて修正できるファイル。

開発するにつれて、コンテナ化された CloudNativeワークフロー用のアプリケーションの設計についてさらに学ぶことに興味があるかもしれません。 これらのトピックの詳細については、Kubernetes用アプリケーションのアーキテクチャおよびKubernetes用アプリケーションの最新化を参照してください。

このチュートリアルで使用されるコードの詳細については、Dockerを使用してNode.jsアプリケーションを構築する方法およびMongoDBをノードアプリケーションと統合する方法を参照してください。 コンテナーを使用してNginxリバースプロキシを使用してNodeアプリケーションをデプロイする方法については、 Nginx、Let’s Encrypt、およびDockerComposeを使用してコンテナー化されたNode.jsアプリケーションを保護する方法を参照してください。