MEAN スタックで構築されたイベント投稿アプリのコンテナ化

この記事は、オープンソースのコラボレーションの結果です。 中 ハックトーバーフェスト2022、プロジェクトはBlack Forest Dockerミートアップグループで発表され、ミートアップグループのメンバーや他のハックトーバーフェストの貢献者から貢献を受けました。 GitHub リポジトリのほとんどすべてのコードは、Stefan Ruf、Himanshu Kandpal、Sreekesh Iyer によって書かれています。

MEAN スタックは、Web アプリケーションの開発に使用される、急成長しているオープンソースの JavaScript スタックです。 MEANは、 MongoDBExpress.js、堅牢なテクノロジーの多様なコレクションです。 角度、および ノード.js — スケーラブルなWebアプリケーションの開発用。 

スタックは、開発プロセス全体で単一の言語で作業でき、多くの柔軟性とスケーラビリティも提供するため、Web開発者に人気のある選択肢です。 Node、Express、Angularは、 Stack Overflowの2022年開発者調査で人気のあるフレームワークまたはテクノロジーとしてトップの座を獲得しました。

この記事では、例としてイベント投稿アプリを使用して MEAN スタックがどのように機能するかについて説明します。

mongodb、expressのスタックロゴを意味します。 JS、角度、およびノード。 Js

MEAN スタックはどのように機能しますか?

MEAN は、次の 4 つのコンポーネントで構成されます。

  • MongoDB — NoSQL データベース 
  • ExpressJS — NodeJS 用のバックエンドウェブアプリケーションフレームワーク
  • Angular — 動的なシングルページのウェブアプリケーションを構築するための JavaScript ベースのフロントエンドウェブ開発フレームワーク
  • NodeJS — とりわけ、ブラウザの外部で JavaScript コードを実行できるようにする JavaScript ランタイム環境

ここでは、さまざまなコンポーネントがどのように連携するかを簡単に説明します。

  • ユーザーは、Angularコンポーネントで構築されたWebブラウザーを介してフロントエンドと対話します。 
  • バックエンドサーバーは、NodeJS上で実行されているExpressJSを介してフロントエンドコンテンツを配信します。
  • データは、フロントエンドに戻る前にMongoDBデータベースからフェッチされます。 ここでは、アプリケーションがユーザーに表示します。
  • データ変更要求を引き起こす対話はすべて、ノードベースの Express サーバーに送信されます。

なぜMEANスタックはそれほど人気があるのですか?

MEAN スタックは、アプリケーションのクライアント側とサーバー側の両方に同じ言語が使用されるフルスタックの JavaScript Web アプリケーションを構築するためによく使用されます。 このアプローチにより、開発がより効率的で一貫性のあるものになり、開発者はアプリケーションのフロントエンドとバックエンドの両方で作業しやすくなります。

MEAN スタックは、次のようないくつかの理由で人気があります。

  • 簡単な学習曲線 -- JavaScript と JSON を使い慣れていれば、簡単に始めることができる。 MEANの構造により、JavaScriptとJSONだけで3層アーキテクチャ(フロントエンド、バックエンド、データベース)を簡単に構築できます。
  • モデルビューアーキテクチャ — MEANは モデルビューコントローラアーキテクチャをサポートし、 スムーズでシームレスな開発プロセスをサポートします。
  • コンテキストの切り替えを削減 — MEAN はフロントエンドとバックエンドの両方の開発に JavaScript を使用するため、開発者は言語の切り替えについて心配する必要はありません。 この機能により、開発効率が向上します。
  • オープンソースと活発なコミュニティサポート — MEAN スタックは純粋にオープンソースです。 すべての開発者は、堅牢なWebアプリケーションを構築できます。 そのフレームワークは、コーディング効率を向上させ、より迅速なアプリ開発を促進します。

イベント投稿アプリの実行

イベント投稿アプリの主なコンポーネントは次のとおりです。

  • モンゴデブ
  • エクスプレス.js
  • 角度
  • ノード.js
  • Docker Desktop

イベント投稿アプリのデプロイは迅速なプロセスです。 まず、 リポジトリのクローンを作成し、 クライアントとバックエンドを設定してから、アプリケーションを起動します。 

次に、次の手順を実行します。

git clone https://github.com/dockersamples/events 
cd events/backend
npm install
npm run dev

イベント投稿アプリの大まかな流れ

イベント投稿アプリを介した情報の流れを図 1 に示し、次の手順で説明します。

イベント投稿アプリのコンポーネント (ブラウザー、フロントエンド コンテナー、バックエンド サーバー、mongodbなど) を経由する情報の流れを示す図。
図1: イベント投稿アプリの一般的なフロー。
  1. ユーザーがブラウザでイベント投稿アプリのWebサイトにアクセスします。
  2. フロントエンドフレームワークであるAngularJSは、必要なHTML、CSS、およびJavaScriptファイルをサーバーから取得し、Webサイトの初期ビューをレンダリングします。
  3. ユーザーがイベントのリストを表示したり、新しいイベントを作成したりする場合、AngularJSはバックエンドサーバーにHTTPリクエストを送信します。
  4. バックエンド Web フレームワークである Express.js は、要求を受信して処理します。 この手順には、MongoDB データベースと対話してデータを取得または格納し、フロントエンドがデータにアクセスするための API を提供することが含まれます。
  5. バックエンド サーバーはフロントエンドに応答を送信し、AngularJS はそれを受信してビューの更新に使用します。
  6. ユーザーが新しいイベントを作成すると、AngularJS はバックエンド サーバーに POST 要求を送信し、Express.js はそれを受信して処理します。 エクスプレス.js 新しいイベントを MongoDB データベースに保存します。
  7. バックエンドサーバーはフロントエンドに確認応答を送信し、AngularJSはそれを受信してビューを更新し、新しいイベントを表示するために使用します。
  8. JavaScript ランタイムである Node.js は、アプリケーションのサーバー側ロジックを処理し、リアルタイムの更新を可能にします。 これには、Express.js サーバーの実行、WebSocket を使用したリアルタイム更新の処理、およびその他のサーバー側タスクの処理が含まれます。

その後、ブラウザの http://localhost:80 でイベント投稿にアクセスできます(図2)。

青い「新しいイベントを追加」ボタンのスクリーンショット。
図2: 新しいイベントを追加します。

[ 新しいイベントの追加 ] を選択して詳細を追加します (図 3)。

名前、開催者、日付などのイベントの詳細を追加するためのダイアログ ボックスのスクリーンショット。
図3: イベントの詳細を追加します。

イベントの詳細を保存して、最終結果を確認します(図4)。

今後のイベントを示すディスプレイのスクリーンショット (ベルリンとバンガロールでの Docker イベントの例を含む)。
図4: 今後のイベントを表示します。

MEAN スタックをコンテナ化する理由

MEAN スタックをコンテナー化することで、アプリケーションの一貫性があり、移植性が高く、簡単に拡張できる環境が実現し、セキュリティとデプロイの容易さが向上します。 MEAN スタックをコンテナー化することには、次のようないくつかの利点があります。

  • 一貫性: コンテナー化により、アプリケーションの環境がさまざまな開発環境、テスト環境、および運用環境で一貫していることが保証されます。 このアプローチにより、依存関係や構成のバージョンが異なるなど、環境の違いから発生する可能性のある問題が排除されます。
  • ポータビリティ: コンテナはポータブルに設計されているため、異なる環境間で簡単に移動できます。 この機能により、MEAN スタックアプリケーションをオンプレミスやクラウドなどのさまざまな環境に簡単にデプロイできます。
  • 隔離: コンテナーは、アプリケーションとホスト環境の間の分離レベルを提供します。 したがって、アプリケーションは必要なリソースにのみアクセスでき、同じホスト上で実行されている他のアプリケーションに干渉することはありません。
  • 拡張性: コンテナは、アプリケーションのニーズに応じて簡単にスケールアップまたはスケールダウンできるため、リソースのより効率的な使用とパフォーマンスの向上につながります。

イベント投稿アプリのコンテナ化

Docker は、MEAN スタックをコンテナ化するのに役立ち、イベント投稿アプリケーション、ランタイム、構成、およびオペレーティングシステムレベルの依存関係全体をバンドルできます。 コンテナには、クロスプラットフォームのマルチアーキテクチャWebアプリケーションを出荷するために必要なすべてのものが含まれます。 

Docker 公式イメージを使用して、Docker コンテナー内でこのアプリを実行する方法について説明します。 まず、 Dockerデスクトップをダウンロードして 、インストールプロセスを完了する必要があります。 この手順には、Docker CLI、Docker Compose、およびユーザーフレンドリーな管理 UI が含まれており、それぞれ後で役立ちます。

Docker は、 Dockerfile を使用して各イメージのレイヤーを作成します。 各レイヤーには、基本イメージの標準構成に起因する重要な変更が格納されます。 次に、プロジェクト リポジトリのルートに空の Dockerfile を作成します。

Angularフロントエンドのコンテナ化

Angularフロントエンドをコンテナ化するためのマルチステージDockerfileを構築します。 

Dockerfile は、Docker コンテナー イメージをアセンブルするための手順を含むプレーンテキスト ファイルです。 Dockerがコマンドを使用してイメージをビルドすると、これらの命令が docker build 読み取られて実行され、最終的なイメージが作成されます。 

マルチステージ ビルドでは、Docker ビルドでコンパイル、パッケージ化、単体テストに 1 つの基本イメージを使用できます。 別のイメージは、アプリケーションのランタイムを保持します。 この設定により、最終的なイメージのセキュリティが強化され、フットプリントが縮小されます (開発ツールやデバッグ ツールが含まれていないため)。 

アプリケーションの Dockerfile を作成するプロセスを見ていきましょう。 まず、フロントエンド アプリのルートに名前 Dockerfile を持つ次の空のファイルを作成します。

touch Dockerfile

次に、Dockerfile ファイルで基本イメージを定義する必要があります。 ここでは、 ノードドッカー公式イメージの安定したLTSバージョンを選択しました。 このイメージには、Node.js アプリケーションを実行するために必要なすべてのツールとパッケージが付属しています。

FROM node:lts-alpine AS build

次に、イメージのアプリケーション コードを格納するディレクトリを作成しましょう。 これは、アプリケーションの作業ディレクトリとして機能します。

WORKDIR /usr/src/app

次の手順 COPY では、 package.json ホスト コンピューターからコンテナー イメージに and src ファイルをコピーします。 

このコマンドは COPY 2 つのパラメーターを取ります。 1 つ目は、イメージにコピーするファイルを Docker に指示します。 2つ目は、これらのファイルをコピーする場所をDockerに指示します。 という作業ディレクトリ /usr/src/appにすべてをコピーします。

COPY package.json .

COPY package-lock.json .
RUN npm ci

次に、ソースコードをイメージに追加する必要があります。 このコマンドは、以前にファイルで行った package.json のと同じように使用します COPY 。 

手記: Docker イメージをビルドするときに、 package.json アプリケーション コードとは別にファイルをコピーするのが一般的です。 この手順により、Docker はアプリケーション コード レイヤーとは別にnode_modulesレイヤーをキャッシュできるため、Docker のビルド プロセスが大幅に高速化され、開発ワークフローを改善できます。

COPY . .

次に、を使用して npm run build 、以下から package.jsonビルドスクリプトを実行します。

RUN npm run build

次のステップでは、Nginxイメージをベースとして使用し、ファイルを /etc/nginx ディレクトリにコピーする nginx.conf ビルドの第2段階を指定する必要があります。また、コンパイルされた TypeScript コードをビルド ステージからディレクトリにコピーします /usr/share/nginx/html

FROM nginx:stable-alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=build /usr/src/app/dist/events /usr/share/nginx/html

最後に、この命令は EXPOSE 、コンテナが実行時にリッスンするポートをDockerに指示します。 ポートが TCP と UDP のどちらでリッスンするかを指定できます。 プロトコルが指定されていない場合の既定値は TCP です。

EXPOSE 80

これが私たちの完全な ドッカーファイルです:

# Builder container to compile typescript
FROM node:lts-alpine AS build
WORKDIR /usr/src/app

# Install dependencies
COPY package.json .
COPY package-lock.json .
RUN npm ci

# Copy the application source
COPY . .
# Build typescript
RUN npm run build



FROM nginx:stable-alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=build /usr/src/app/dist/events /usr/share/nginx/html

EXPOSE 80

それでは、イメージを構築しましょう。 docker build 上記のようにコマンドを実行しますが、フラグを使用します -f Dockerfile 。このフラグは、 -f ドッカーファイル名を指定します。 "." コマンドは、現在のディレクトリをビルド コンテキストとして使用し、stdin から Dockerfile を読み取ります。 -t 結果の画像にタグを付けます。

docker build . -f Dockerfile -t events-fe:1

ノード.jsバックエンドのコンテナ化

次のステップとして、バックエンド用の Dockerfile を作成するプロセスを見ていきましょう。 まず、バックエンド Node アプリのルートに次の空 Dockerfile を作成します。

# Builder container to compile typescript
FROM node:lts-alpine AS build
WORKDIR /usr/src/app

# Install dependencies
COPY package.json .
COPY package-lock.json .
RUN npm ci

# Copy the application source
COPY . .
# Build typescript
RUN npm run build



FROM node:lts-alpine
WORKDIR /app
COPY package.json .
COPY package-lock.json .
COPY .env.production .env

RUN npm ci --production

COPY --from=build /usr/src/app/dist /app

EXPOSE 8000
CMD [ "node", "src/index.js"]

この Dockerfile は、コンテナー化された環境で TypeScript アプリケーションを構築して実行するのに役立ち、開発者はアプリケーションをより簡単にパッケージ化して配布できます。

という名前の buildビルド プロセスの最初のステージは、公式の Node .js LTS Alpine Docker イメージに基づいています。 作業ディレクトリ /usr/src/app を設定し、コマンド package-lock.jsonnpm ci 依存関係をインストールするためのファイルとファイルをコピー package.json します。次に、アプリケーションのソース コード全体をコピーし、コマンドを使用して TypeScript を npm run build ビルドします。

という名前の productionビルド プロセスの第 2 段階では、公式の Node.js LTS Alpine Docker イメージも使用されます。 作業ディレクトリ /app を に設定し、 をコピーします。 package.jsonpackage-lock.json, と .env.production ファイル。 次に、コマンドを使用して npm ci --production 本番環境の依存関係のみをインストールし、前のステージの出力であるコンパイルされた TypeScript コードを /usr/src/app/dist から にコピーします /app

最後に、ポート 8000 を公開し、コンテナーの起動時にコマンドを実行 node src/index.js します。

作成ファイルを使用したサービスの定義

Docker 作成 ファイル内でサービスがどのように表示されるかを次に示します。

services:
  frontend:
    build:
      context: "./frontend/events"
      dockerfile: "./Dockerfile"
    networks:
      - events_net
  backend:
    build:
      context: "./backend"
      dockerfile: "./Dockerfile"
    networks:
      - events_net
  db:
    image: mongo:latest
    ports:
      - 27017:27017
    networks:
      - events_net
  proxy:
    image: nginx:stable-alpine
    environment:
      - NGINX_ENVSUBST_TEMPLATE_SUFFIX=.conf
      - NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx
    volumes:
      - ${PWD}/nginx.conf:/etc/nginx/templates/nginx.conf.conf
    ports:
      - 80:80
    networks:
      - events_net

networks:
  events_net:

サンプル アプリケーションには、次の部分があります。

  • Docker イメージによってサポートされる 4 つのサービス: Angular フロントエンド、ノード.jsバックエンド、MongoDB データベース、プロキシ サーバーとしての Nginx
  • フロントエンドとバックエンドのサービスは、次の場所にあるDockerfilesから構築されます。 ./frontend/events そして ./backend それぞれディレクトリ。 どちらのサービスも、という events_netネットワークに接続されています。
  • db サービスは、最新バージョンの MongoDB Docker イメージに基づいており、ポート 27017 を公開します。 フロントエンドおよびバックエンドサービスと同じ events_net ネットワークに接続されます。
  • プロキシサービスは、Nginx Dockerイメージの安定した高山バージョンに基づいています。 Nginx構成ファイルでの環境変数の置換を可能にするNGINX_ENVSUBST_TEMPLATE_SUFFIXとNGINX_ENVSUBST_OUTPUT_DIRの2つの環境変数が定義されています。 
  • プロキシ サービスには、ローカル nginx.conf ファイルを /etc/nginx/templates/nginx.conf.conf コンテナー内にマップするボリュームも定義されています。 最後に、ポート 80 を公開し events_net 、ネットワークに接続します。
  • events_net ネットワークはファイルの末尾で定義され、すべてのサービスがそれにアタッチされます。この設定により、サービス名をホスト名として使用してコンテナ間の通信が可能になります。

リポジトリを複製するか、 docker-compose.yml GitHub の Dockersamples から直接ファイルをダウンロードできます。

コンテナサービスの起動

MEAN アプリケーションスタックを開始するには、次のコマンドを実行します。

docker compose up -d 

次に、コマンドを使用して、 docker compose ps スタックが正しく実行されていることを確認します。 端末は以下の出力を生成します。

$ docker compose ps   
NAME                IMAGE                 COMMAND                  SERVICE             CREATED             STATUS              PORTS
events-backend-1    events-backend        "docker-entrypoint.s…"   backend             29 minutes ago      Up 29 minutes       8000/tcp
events-db-1         mongo:latest          "docker-entrypoint.s…"   db                  5 seconds ago       Up 4 seconds        0.0.0.0:27017->27017/tcp
events-frontend-1   events-frontend       "/docker-entrypoint.…"   frontend            29 minutes ago      Up 29 minutes       80/tcp
events-proxy-1      nginx:stable-alpine   "/docker-entrypoint.…"   proxy               29 minutes ago      Up 29 minutes       0.0.0.0:80->80/tcp

Docker ダッシュボードを使用したコンテナーの表示

また、Docker ダッシュボードを利用してコンテナーの ID を表示し、アプリケーションに簡単にアクセスまたは管理することもできます (図 5)。

実行中のコンテナーを示す Docker ダッシュボードのスクリーンショット。
図5: Docker ダッシュボードで実行中のコンテナーを表示する。

結論

万丈!Docker を使用して MEAN ベースのイベント送信アプリケーションをコンテナー化する方法を正常に学習しました。 1 つの YAML ファイルで、Docker Compose を使用して MEAN スタックを数秒で簡単に構築してデプロイする方法を示しました。 いくつかの追加手順を実行するだけで、このチュートリアルを適用しながら、さらに複雑なアプリケーションを構築できます。 ハッピー開発!

フィードバック

「MEANスタックで構築されたイベント投稿アプリのコンテナ化」に関する0の考え