Share via


Create Express.js virtual machine using Azure CLI

このチュートリアルでは、Express.js アプリ用の Linux 仮想マシン (VM) を作成します。 この VM は、cloud-init 構成ファイルで構成され、NGINX と Express.js アプリの GitHub リポジトリが含まれています。 SSH を使用して VM に接続し、トレースのログ記録を含めるように Web アプリを変更して、公開された Express.js サーバー アプリを Web ブラウザーで表示します。

このチュートリアルに含まれるタスクは次のとおりです。

  • Azure CLI を使用して Azure にサインインする
  • Azure CLI を使用して Azure Linux VM リソースを作成する
    • パブリック ポート 80 を開く
    • GitHub リポジトリから Express.js Web アプリのデモをインストールする
    • Web アプリの依存関係をインストールする
    • Web アプリの起動
  • Azure CLI を使用して Azure 監視リソースを作成する
    • SSH を使用して VM に接続する
    • npm を使用して Azure SDK クライアント ライブラリをインストールする
    • Application Insights クライアント ライブラリ コードを追加して、カスタム トレースを作成する
  • ブラウザーから Web アプリを表示する
    • /trace ルートを要求して、Application Insights ログにカスタム トレースを生成する
    • Azure CLI を使用して、ログに収集されたトレースの数を表示する
    • Azure portal でトレースの一覧を表示する
  • Azure CLI を使用してリソースを削除する

Azure サブスクリプションを作成するか、既存のものを使用する

アクティブなサブスクリプションがある Azure アカウントが必要です。 無料で作成できます。

前提条件

  • VM に接続するための SSH: Azure Cloud Shell、または SSH を含む bash シェルなどの最新ターミナルを使用します。
  • Azure Cloud Shell で Bash 環境を使用します。 詳細については、「Azure Cloud Shell の Bash のクイックスタート」を参照してください。

  • CLI リファレンス コマンドをローカルで実行する場合、Azure CLI をインストールします。 Windows または macOS で実行している場合は、Docker コンテナーで Azure CLI を実行することを検討してください。 詳細については、「Docker コンテナーで Azure CLI を実行する方法」を参照してください。

    • ローカル インストールを使用する場合は、az login コマンドを使用して Azure CLI にサインインします。 認証プロセスを完了するには、ターミナルに表示される手順に従います。 その他のサインイン オプションについては、Azure CLI でのサインインに関するページを参照してください。

    • 初回使用時にインストールを求められたら、Azure CLI 拡張機能をインストールします。 拡張機能の詳細については、Azure CLI で拡張機能を使用する方法に関するページを参照してください。

    • az version を実行し、インストールされているバージョンおよび依存ライブラリを検索します。 最新バージョンにアップグレードするには、az upgrade を実行します。

1. Web ページ用の Application Insights リソースを作成する

すべての Azure リソース用の Azure リソース グループと、Web アプリのログ ファイルを Azure クラウドに収集するための Monitor リソースを作成します。 リソース グループを作成することにより、リソースを見つけやすくなり、完了時に削除しやすくなります。 Azure Monitor は Azure サービスの名前ですが、Application Insights はこのチュートリアルで使用するクライアント ライブラリの名前です。

  1. (省略可能) サブスクリプションが複数ある場合は、az account set を使用して既定のサブスクリプションを設定してから、残りのコマンドを完了します。

    az account set \
        --subscription "ACCOUNT NAME OR ID" 
    
  2. az group create を使用して Azure リソース グループを作成します。 rg-demo-vm-eastus という名前を使用します。

    az group create \
        --location eastus \
        --name rg-demo-vm-eastus 
    

Azure CLI を使用して Azure Monitor リソースを作成する

  1. Azure CLI に Application Insights 拡張機能をインストールします。

    az extension add -n application-insights
    
  2. az monitor app-insights component create を使用して監視リソースを作成するには、次のコマンドを使用します。

    az monitor app-insights component create \
      --app demoWebAppMonitor \
      --location eastus \
      --resource-group rg-demo-vm-eastus \
      --query instrumentationKey --output table
    
  3. 出力から結果をコピーします。後でその値が instrumentationKey として必要になります。

  4. このターミナルは開いたままにしてください。次のステップで使用します。

2. Azure CLI を使用して Linux 仮想マシンを作成する

cloud-init 構成ファイルを使用して、NGINX リバース プロキシ サーバーと Express.js サーバーの両方を作成します。 NGINX は、Express.js ポート (3000) をパブリック ポート (80) に転送するために使用されます。

  1. cloud-init-github.txt という名前のローカル ファイルを作成して次の内容をファイルに保存するか、ローカル コンピューターにリポジトリのファイルを保存することができます。 cloud init 形式のファイルは、Azure CLI コマンドのターミナル パスと同じフォルダーに存在している必要があります。

    #cloud-config
    package_upgrade: true
    packages:
      - nginx
    write_files:
      - owner: www-data:www-data
        path: /etc/nginx/sites-available/default
        content: |
          server {
            listen 80 default_server;
            server_name _;
            location / {
              # First, try if the file exists locally, otherwise request it from the app
              try_files $uri @app;
            }
            location @app {
              proxy_pass http://localhost:3000;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header X-Forwarded-For $remote_addr;
              proxy_set_header Host $host;
              proxy_cache_bypass $http_upgrade;
            }
          }
    runcmd:
      # install Node.js
      - 'curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -'
      - 'sudo apt-get install -y nodejs'
      # clone GitHub Repo into myapp directory
      - 'cd /home/azureuser'
      - git clone "https://github.com/Azure-Samples/js-e2e-vm" myapp
      # Start app
      - 'cd myapp && npm install && npm start'
      # restart NGINX
      - systemctl restart nginx
    
  2. ファイルの runcmd セクションを確認して、その内容を理解します。

    runcmd には、いくつかのタスクがあります。

    • Node.js をダウンロードしてインストールします
    • GitHub から myapp ディレクトリにサンプル Express.js リポジトリを複製します
    • アプリケーションの依存関係をインストールします
    • PM2 を使用して Express.js アプリを開始します

仮想マシンのリソースを作成する

  1. ターミナルで Azure CLI コマンド az vm create を入力して、Linux 仮想マシンの Azure リソースを作成します。 このコマンドでは、cloud-init ファイルから VM が作成され、SSH キーが生成されます。 コマンドを実行すると、キーが格納されている場所が表示されます。

    az vm create \
      --resource-group rg-demo-vm-eastus \
      --name demo-vm \
      --location eastus \
      --public-ip-sku Standard \
      --image UbuntuLTS \
      --admin-username azureuser \
      --generate-ssh-keys \
      --custom-data cloud-init-github.txt
    
  2. この処理には数分かかることがあるため、待機します。

  3. publicIpAddress の値を控えておきます。これは、ブラウザーで Web アプリを表示するため、および VM に接続するために必要です。 この IP が失われた場合は、Azure CLI コマンドの az vm list-ip-addresses を使用して、もう一度取得します。

  4. このプロセスで SSH キーが作成され、応答に記載されている場所に保存されました。

  5. その場所に移動し、authorized_keys ファイルを作成します。

    cd <SSH-KEY-LOCATION> && cat id_rsa >> authorized_keys
    

仮想マシンのポートを開く

仮想マシンを最初に作成したときに、開いているポートは "ありません"。 続いて、Azure CLI コマンド az vm open-port を使用してポート 80 を開き、Web アプリが一般公開されるようにします。

az vm open-port \
  --port 80 \
  --resource-group rg-demo-vm-eastus \
  --name demo-vm

Web サイトの参照

  1. Web ブラウザーでパブリック IP アドレスを使用して、仮想マシンが使用可能で実行されていることを確認します。 publicIpAddress の値を使用するように URL を変更します。

    http://YOUR-VM-PUBLIC-IP-ADDRESS
    
  2. ゲートウェイ エラーが発生してリソースにアクセスできなかった場合は、しばらくしてからもう一度やり直してください。Web アプリが開始されるまでに 1 分ほどかかることがあります。

  3. 仮想マシンの Web アプリから次の情報が返されます。

    • VM 名
    • クライアント IP
    • 現在の日時

    Azure 上の Linus 仮想マシンから提供される単純なアプリを示す Web ブラウザーのスクリーンショット。

  4. Web アプリの最初のコード ファイルには、NGINX プロキシを経由したルートが 1 つあります。

    const os = require('os');
    const express = require('express')
    const app = express()
    
    app.use('/public', express.static('public'))
    app.get('/', function (req, res) {
    
        const clientIP = req.headers['x-forwarded-for'];
        const msg = `HostName: ${os.hostname()}<br>ClientIP: ${clientIP}<br>DateTime: ${new Date()}<br><img width='200' height='200' src='/public/leaves.jpg' alt='flowers'>`
        console.log(msg)
    
        res.send(msg)
    })
    app.listen(3000, function () {
        console.log(`Hello world app listening on port 3000! ${Date.now()}`)
    })
    

3. SSH を使用して Linux 仮想マシンに接続する

チュートリアルのこのセクションでは、ターミナルで SSH を使用して仮想マシンに接続します。 SSH は、Azure Cloud Shell を含む多くの最新シェルに用意されている一般的なツールです。

SSH を使用して接続して Web アプリを変更する

  1. 以下のコマンドを使用して、リモート仮想マシンに接続します。

    YOUR-VM-PUBLIC-IP を、お使いの仮想マシンのパブリック IP に置き換えます。

    ssh azureuser@YOUR-VM-PUBLIC-IP
    

    このプロセスでは、お使いの SSH クライアントが SSH キーを検出でき、VM 作成の一環として作成され、ローカル コンピューター上に配置されていることを前提としています。

  2. 接続を確認するメッセージが表示されたら、y または yes と回答して続行します。

  3. 次のコマンドを使用して、仮想マシン上の自分の場所を把握します。 azureuser のルート /home/azureuser にいるはずです。

    pwd
    
  4. 接続が完了すると、ターミナル プロンプトはリモート仮想マシンのユーザー名とリソースを示すように変更されます。

    azureuser@demo-vm:
    
  5. Web アプリはサブ ディレクトリ myapp にあります。 myapp ディレクトリに移動し、内容を一覧表示します。

    cd myapp && ls -l
    
  6. 仮想マシンに複製された GitHub リポジトリと npm パッケージ ファイルを表す内容が表示されます。

    -rw-r--r--   1 root root   891 Nov 11 20:23 cloud-init-github.txt
    -rw-r--r--   1 root root  1347 Nov 11 20:23 index-logging.js
    -rw-r--r--   1 root root   282 Nov 11 20:23 index.js
    drwxr-xr-x 190 root root  4096 Nov 11 20:23 node_modules
    -rw-r--r--   1 root root 84115 Nov 11 20:23 package-lock.json
    -rw-r--r--   1 root root   329 Nov 11 20:23 package.json
    -rw-r--r--   1 root root   697 Nov 11 20:23 readme.md
    

Monitoring SDK のインストール

  1. 仮想マシンに接続されている SSH ターミナルで、Application Insights 用の Azure SDK クライアント ライブラリをインストールします。

    sudo npm install --save applicationinsights
    
  2. コマンドが完了するまで待ってから続行します。

監視インストルメンテーション キーの追加

  1. 仮想マシンに接続されている SSH ターミナルで、Nano エディターを使用して package.json ファイルを開きます。

    sudo nano package.json
    
  2. APPINSIGHTS_INSTRUMENTATIONKEY 環境変数を Start スクリプトの先頭に追加します。 次の例では、REPLACE-WITH-YOUR-KEY をインストルメンテーション キーの値に置き換えてください。

    "start": "APPINSIGHTS_INSTRUMENTATIONKEY=REPLACE-WITH-YOUR-KEY pm2 start index.js --watch --log /var/log/pm2.log"
    
  3. 引き続き SSH ターミナルで、Ctrl + X を使用して Nano エディターでファイルを保存します。

  4. Nano エディターでダイアログが表示されたら、「Y」と入力して保存します。

  5. Nano エディターでダイアログが表示されたら、表示されたときにファイル名を受け入れます。

VM を停止してアプリケーションを変更する

これで Azure クライアント ライブラリは node_modules に配置され、キーは環境変数としてアプリに渡されました。 次の手順では、プログラムで Application Insights を使用します。

  1. 次のコマンドを使用して、PM2 を停止します。これは、Node.js アプリケーション用の実稼働プロセス マネージャーです。

    sudo npm run-script stop 
    
  2. Application Insights を使用して元の index.js をファイルに置き換えます。

    sudo npm run-script appinsights
    
  3. クライアント ライブラリとログ コードが指定されます。

    const express = require('express')
    const app = express()
    const os = require('os');
    
    console.log(JSON.stringify(process.env));
    
    const AppInsights = require('applicationinsights');
    
    if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {
        console.log(`AppInsights configured with key ${process.env.APPINSIGHTS_INSTRUMENTATIONKEY}`);
    } else{
        console.log(`AppInsights not configured`);
    }
    
    AppInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY)
        .setAutoDependencyCorrelation(true)
        .setAutoCollectRequests(true)
        .setAutoCollectPerformance(true, true)
        .setAutoCollectExceptions(true)
        .setAutoCollectDependencies(true)
        .setAutoCollectConsole(true)
        .setUseDiskRetryCaching(true)
        .setSendLiveMetrics(false)
        .setDistributedTracingMode(AppInsights.DistributedTracingModes.AI)
        .start();
    
    const AppInsightsClient = AppInsights.defaultClient;
    
    
    app.get('/trace', (req, res) => {
    
        const clientIP = req.headers['x-forwarded-for'];
        const msg = `trace route ${os.hostname()} ${clientIP} ${new Date()}`;
    
        console.log(msg)
    
        if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {
            AppInsightsClient.trackPageView();
            AppInsightsClient.trackTrace({ message: msg })
            AppInsightsClient.flush();
        } else {
            msg += ' AppInsights not configured';
        }
    
        res.send(`${msg}`)
    })
    
    app.get('/', function (req, res) {
    
        const clientIP = req.headers['x-forwarded-for'];
        const msg = `root route ${os.hostname()} ${clientIP} ${new Date()}`
    
        console.log(msg)
    
        res.send(msg)
    
    })
    app.listen(3000, function () {
        console.log(`Hello world app listening on port 3000! ${os.hostname()}`)
    })
    
  4. PM2 を使用してアプリを再起動し、次の環境変数を取得します。

    sudo npm start
    

アプリを使用してログ記録を確認する

  1. Web ブラウザーで、新しい trace ルートを使用してアプリをテストします。

    http://YOUR-VM-PUBLIC-IP-ADDRESS/trace
    

    ブラウザーに応答が表示されます。trace route demo-vm YOUR-CLIENT-IP VM-DATE-TIME とお使いの IP アドレスです。

NGINX のログの表示

仮想マシン (VM) で収集される NGINX のログを表示できます。

サービス ログの場所
NGINX /var/log/nginx/access.log
  1. 引き続き SSH ターミナルで、次のコマンドを使用して NGINX プロキシ サービスの VM ログを表示します。
cat /var/log/nginx/access.log
  1. ログには、お使いのローカル コンピューターからの呼び出しが含まれています。
"GET /trace HTTP/1.1" 200 10 "-"

PM2 のログの表示

仮想マシン (VM) で収集される PM2 のログを表示できます。

サービス ログの場所
PM2 /var/log/pm2.log
  1. Express.js Node Web アプリである PM2 サービスの VM ログを表示します。 同じ bash シェルで、次のコマンドを使用してログを表示します。

    cat /var/log/pm2.log
    
  2. ログには、お使いのローカル コンピューターからの呼び出しが含まれています。

    grep "Hello world app listening on port 3000!" /var/log/pm2.log
    
  3. ログには、npm start スクリプトで渡された、ApplicationInsights キーを含む環境変数も含まれています。 次の grep コマンドを使用して、お使いのキーが環境変数に含まれていることを確認します。

    grep APPINSIGHTS_INSTRUMENTATIONKEY /var/log/pm2.log
    

    これにより、APPINSIGHTS_INSTRUMENTATIONKEY が別の色で強調表示された PM2 ログが表示されます。

VM ログとクラウド ログ

このアプリケーションでは、console.log を使用して、VM でのみ検出される PM2 ログにメッセージを書き込んでいます。 ログまたは VM を削除すると、その情報は失われます。

仮想マシンの使用期間を超えてログを保持する場合は、Application Insights を使用します。

5.リソースをクリーンアップする

このチュートリアルを完了したら、リソース グループを削除する必要があります。リソース グループにはすべてのリソースが含まれているため、削除することで、それ以上の使用に対して課金されないようにします。

同じターミナルで、Azure CLI コマンドの az group delete を使用してリソース グループを削除します。

az group delete --name rg-demo-vm-eastus -y

このコマンドには数分かかります。

トラブルシューティング

問題がある場合は、次の表を使用して問題を解決する方法を確認してください。

問題 解決方法
502 ゲートウェイ エラー これは、index.js または package.js にエラーがあることを示している可能性があります。 詳細については、/var/log/pm2.log の PM2 ログを参照してください。 最新のエラーは、ファイルの下部にあります。 これらのファイルが正しい場合は、package.json の npm スクリプトを使用して PM2 を停止して起動します。

サンプル コード

次のステップ