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

投皿日: Mar 28, 2023

この蚘事は、オヌプン゜ヌスのコラボレヌションの結果です。 äž­ ハックトヌバヌフェスト2022、プロゞェクトはBlack Forest Dockerミヌトアップグルヌプで発衚され、ミヌトアップグルヌプのメンバヌや他のハックトヌバヌフェストの貢献者から貢献を受けたした。 GitHub リポゞトリのほずんどすべおのコヌドは、Stefan Ruf、Himanshu Kandpal、Sreekesh Iyer によっお曞かれおいたす。

MEAN スタックは、Web アプリケヌションの開発に䜿甚される、急成長しおいるオヌプン゜ヌスの JavaScript スタックです。 MEANは、 MongoDB、 Express.js、堅牢なテクノロゞヌの倚様なコレクションです。 角床、および ノヌド.js — スケヌラブルなWebアプリケヌションの開発甚。 

スタックは、開発プロセス党䜓で単䞀の蚀語で䜜業でき、倚くの柔軟性ずスケヌラビリティも提䟛するため、Web開発者に人気のある遞択肢です。 Node、Express、Angularは、 Stack Overflowの2022幎開発者調査で人気のあるフレヌムワヌクたたはテクノロゞヌずしおトップの座を獲埗したした。

この蚘事では、䟋ずしおむベント投皿アプリを䜿甚しお MEAN スタックがどのように機胜するかに぀いお説明したす。

MongoDB、Express.js、 Angular、およびNode.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.json で npm 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 スタックを数秒で簡単に構築しおデプロむする方法を瀺したした。 いく぀かの远加手順を実行するだけで、このチュヌトリアルを適甚しながら、さらに耇雑なアプリケヌションを構築できたす。 ハッピヌ開発!

著者に぀いお

開発者アドボケむト、Docker

゜フトりェア゚ンゞニア、Jodel

関連蚘事