6
0

IP アドレス確認くんを作る!! powered by Node.js on Azure App Service

Last updated at Posted at 2024-02-26

こんにちは、アーキテクトのやまぱんです。
補足コメントや質問、いいね、拡散、是非お願いします🥺!
間違ってたら優しく教えてください!

node.js を触るのはこれが 5 回目ぐらいなんですけど、今回本来のメインの検証をするための下準備でハマってしまった。

きっかけ

・検証のため IP アドレス確認くんを作りたくなった
・作ってみるとつまった
ローカルでは動くのに、Azure App Service にデプロイすると動かないっていう状態にハマる、沼る
・他にも詰まってる人がいそうだった
 Stack over flow や Qiita でも同じようなエラーになってる人がいた
・今後も作ることありそうなのでメモしとこ

事前準備

node.js、Azure CLI ,Express Generator などはインストール済の Windows 環境で実施

手順

  • 1.管理者権限のターミナルにて express のひな形を作る
ターミナル
express ipshow(任意の名前で可)
  • 2.作成されたディレクトリに移動
ターミナル
cd ipshow
  • 3.依存関係のインストール
ターミナル
npm install
  • 4.routes/index.jsを以下のコードに書き換え <キーポイント:IP アドレスの取得>
routes/index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
  // クライアントのIPアドレスを取得する
  // x-forwarded-for ヘッダーがある場合はそれを使用し
  //ない場合は req.connection.remoteAddress を使用してクライアントのIPアドレスを取得
  const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  res.render('index', { title: `IPアドレス確認くん`, ip: ip});
});

module.exports = router;
  • 5.views/index.jadeを以下のコードに書き換え
views/index.js
extends layout

block content
  h1= title
  H2 your IP address and port No. is  ""#{ip}""
  • 6.bin/www を必要に応じてポート番号を変更
bin/www
var port = normalizePort(process.env.PORT || '8080');
  • 7.ローカルでデプロイ
npm run start

ローカルでの実行イメージ

ローカル IP なのでこんな感じになる、想定通り!!
image.png

  • 8.Azure App Service にデプロイ
Azure CLI 例
az webapp up --sku F1(またはB1など) --name <例:yamapaniptest> --resource-group <例:RG-IPCheck> --subscription <Subscription ID> --location japaneast --plan AppPlan
実際に打ったコマンド例(Azure CLI)
az webapp up --sku B1 --name demo-Webapp --resource-group demo-sukiyanen --subscription XXXXXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXX83 --location japaneast --plan yamapanAppService --launch-browser 

下記のような感じで URL が表示されます。(下記は別のアプリのデプロイ画面)
image.png

Azure App Service での 実行イメージ

無事クライアント端末のグローバル IP が返ってきていることが分かります。✨✨
image.png

うまくいかなかったことメモ

この画面飽きるほど見ました😢😢
:( Application Error
image.png

ひたすらデプロイに失敗した

ストリームログでは以下のような、Error Message が出ていた
Error: Cannot find module 'express' やら 'MODULE_NOT_FOUND'、やら requireStack: [ '/home/site/wwwroot/server.js' ] やら。

ストリームログ
2024-02-26T14:16:18.990816296Z Error: Cannot find module 'express'
2024-02-26T14:16:18.990819496Z Require stack:
2024-02-26T14:16:18.990822696Z - /home/site/wwwroot/server.js
2024-02-26T14:16:18.990825896Z     at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1028:15)
2024-02-26T14:16:18.990828996Z     at Function.Module._load (node:internal/modules/cjs/loader:873:27)
2024-02-26T14:16:18.990831996Z     at Module.require (node:internal/modules/cjs/loader:1100:19)
2024-02-26T14:16:18.990835397Z     at Module.patchedRequire [as require] (/usr/local/lib/node_modules/applicationinsights/node_modules/diagnostic-channel/dist/src/patchRequire.js:14:46)
2024-02-26T14:16:18.990838597Z     at require (node:internal/modules/cjs/helpers:119:18)
2024-02-26T14:16:18.990841797Z     at Object.<anonymous> (/home/site/wwwroot/server.js:3:17)
2024-02-26T14:16:18.990851097Z     at Module._compile (node:internal/modules/cjs/loader:1198:14)
2024-02-26T14:16:18.990854197Z     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
2024-02-26T14:16:18.990857197Z     at Module.load (node:internal/modules/cjs/loader:1076:32)
2024-02-26T14:16:18.990860097Z     at Function.Module._load (node:internal/modules/cjs/loader:911:12) {
2024-02-26T14:16:18.990863297Z   code: 'MODULE_NOT_FOUND',
2024-02-26T14:16:18.990866297Z   requireStack: [ '/home/site/wwwroot/server.js' ]
2024-02-26T14:16:18.990869297Z }

考察と疑問
恐らく、大きな違いは Express generetor を使ったのがよかったみたいで、Azure App Serviceへのデプロイでも正常に動くするようになった。
深追いはしてないけど、成功時と失敗時でディレクトリ構成が違うので、それが原因だと思う。
今度からExpressを使うときは Express generetor ( Express ディレクトリ名 コマンド) を使おう❣✨

以下コマンドで Express Generator はインストール可能(node.js が入っている前提)

npm install express-generator -g

~なんでローカルでは動いてたのかが少し謎~
image.png
いつかじっくりちゃんと考えてみたい。

HTTP モジュールを使用した方法

これは Azure App Service の作りの関係 (内部にプロキシの役割をするものがある) でクライアントの IP が返ってこない、正しく取得できない。

const http = require('http');

// サーバーを作成し、リクエストを処理する
const server = http.createServer((req, res) => {
  // クライアントのIPアドレスを取得する
  const ipAddress = req.connection.remoteAddress;
  
  // IPアドレスをレスポンスとして返す
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(`Your IP address is: "${ipAddress}"\n`);
});

// サーバーを指定のポートで待機させる
const port = 8080;
server.listen(port, () => {
  console.log(`Server running at http://localhost:${port}/`);
});
  • 実行結果
    下記のように予約された IP アドレスが表示される。
    表示したい本来のクライアントの IP アドレスではない。
    Your IP address is: "::ffff:169.254.129.1"
    image.png

参考?

  • Error: Cannot find module 'express' when running on Azure

参考

  • Node.jsでリクエストから接続元のIPアドレスを取得する方法

  • Express Generator で作成されたファイルを触って Express を理解したい1:生成, yarn start, express.static, path.join

謝辞

親愛なる仲間に助けていただきました。
ありがとうございました。

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0