はじめに
とある案件の Deploy 先が Azure でした。ググると、静的な Next.js アプリを Azure Static App Service に Deploy する方法は出てきたけど、API Route を持つ Next.js アプリの Azure App Service への Deploy 方法は、あんまり見つかりませんでした。少なくとも条件がぴったり一致するようなものはなかったので、やってみました。そのまま Deploy しても動きません。
Deploy Next.JS App on for Azure App Service
Windows OS のサーバにペライチの静的な Next-App を Deploy する手順ですが、こちらを参考にしました。今回は、Linux サーバに、最終的に TypeScript で API Route も追加した Next App を Deploy します。
Local 実行環境など
OS: MacOS Monterey Version 12.1
node.js: v16.13.1
yarn: 1.22.17
VSCode: 1.63.2
next: 12.0.8
手順
- Azure 管理画面で、App Service のインスタンスを作る
- 適当な Next-App を作る
- server.js を追加する
- VS Code から Deploy する
最初は、github と接続してやってたんですが、あまりにも時間がかかるので、やめました。今回は Deploy して動くことを確認するのが目的なので、VS Code からやります。
Azure 管理画面で App Service を立ち上げる
こちらは特に注意点はないので、割愛。Node.js のバージョンを使ってるものにしてください。今回は 16。
適当な Next-App を作る
まずは、参考にした記事と同じものをつくります。記事にある example の URL は移動していました。
$ npx create-next-app next-app-js --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
npm run dev
, npm run build
などして問題なく動くことを確認します。
server.js を追加する
ドキュメントルートに以下を追加します。
const { createServer } = require("http");
const next = require("next");
const port = process.env.PORT || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
createServer((req, res) => {
handle(req, res);
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
});
記事では、web.config も設定していますが、IIS は使わないので必要ないです。環境変数の Node のバージョンもいらないです。
VS Code から Deploy する
Azure App Service の Extension をインストールし、リソースが確認できるようにセットアップしてください。後は、Deploy to Web App を選ぶだけです。
1〜2分で反映されます。
Azure Portal のデプロイセンターのログからも成功したか失敗したか確認できます。
これだけか…というくらいアッサリ Deploy できました!
TypeScript にして API Route も追加してみる
前述のサンプルは Static なので、API Route もちゃんと動くか確認します。
いつも yarn なので、yarn にて。
$ yarn create next-app next-app-ts --typescript
これで出来上がったものに、先程の server.js
を放り込みます。
ここで出来上がる pages/api/hello.ts
は、John Doe って固定のテキストを返すだけなので、JavaScript になんかさせる API を適当に作って入れたいと思います。
今回は、乱数を発生させて返すだけの簡単なものにしました。
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
number: number
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const mathrand = Math.random();
res.status(200).json({ number: mathrand })
}
この状態で build すると、
$ yarn build
yarn run v1.22.17
$ next build
info - Checking validity of types
info - Creating an optimized production build
info - Compiled successfully
info - Collecting page data
info - Generating static pages (3/3)
info - Finalizing page optimization
Page Size First Load JS
┌ ○ / 5.45 kB 76.5 kB
├ └ css/149b18973e5508c7.css 655 B
├ ○ /404 194 B 71.3 kB
├ λ /api/hello 0 B 71.1 kB
└ λ /api/mathrand 0 B 71.1 kB
+ First Load JS shared by all 71.1 kB
├ chunks/framework-6e4ba497ae0c8a3f.js 42 kB
├ chunks/main-a56127814584ab09.js 26.9 kB
├ chunks/pages/_app-ba0d1cdf43a37972.js 1.37 kB
└ chunks/webpack-69bfa6990bb9e155.js 769 B
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
○ (Static) automatically rendered as static HTML (uses no initial props)
こんな感じになります。server-side と static の両方が含まれた Next App の完成。先程と同様に VS Code から Deploy します。
ちゃんと動きました。
一点注意としては、.env
がアップロードされてしまうので、嫌な場合は、Deploy 作業中にできる .vscode/settings.json
を編集しましょう。通常は、環境変数を使うので、.env
がアップロードされる必要はないです。
{
"appService.zipIgnorePattern": [
"node_modules{,/**}",
".vscode{,/**}",
".env{,/**}"
],
"appService.defaultWebAppToDeploy": "None"
}
なくなりました。他にも必要ないものは、同様にして settings.json
に追加。
あとは、Pipeline の設定をしたりなどすると良いかも知れません。
なお、Next.js + TypeScript + Prisma2 + Azure MySQL + Azure Storage のアプリケーションを Deploy してみましたが、特に変更なく Deploy できました。
以上。おしまい。