Express | 株式会社麻豆原创 Wed, 04 Sep 2024 03:18:42 +0000 ja hourly 1 https://wordpress.org/?v=6.9.4 Express + Next.js をコンテナで動かしたい /blog/20240904-3308/ Wed, 04 Sep 2024 03:18:41 +0000 /?post_type=blog&p=3308 皆さん、こんにちは。技术开発グループの苍-辞锄补飞补苍です。9月ですね。年を重ねると时间経つのが早く感じる现象を「ジャネーの法则」といいます。 本题です。Express + Next.jsで構成したフロントエンド環境をコ […]

The post Express + Next.js をコンテナで動かしたい first appeared on 株式会社麻豆原创.

]]>
皆さん、こんにちは。技术开発グループの苍-辞锄补飞补苍です。
9月ですね。年を重ねると时间経つのが早く感じる现象を「ジャネーの法则」といいます。

本题です。
Express + Next.jsで構成したフロントエンド環境をコンテナで動作させたい場合、どのような手順でDockerイメージを作成すればよいでしょうか。今回は、Express + Next.jsで構成したフロントエンド環境をイメージ化するまでの手順をまとめたいと思います。

Express + Next.js プロジェクトの準備

まずはExprerss + Next.jsで構成されたプロジェクトを準備します。以下のコマンドでNext.jsを構築します。途中の質問は全てデフォルトのままでOKです。

npx create-next-app@latest express-server-app

次に贰虫辫谤别蝉蝉をインストールします。

cd express-server-app
npm i express
npm i -D ts-node @types/express

プロジェクトのルート直下にserver.tsを追加します。内容は以下の通りです。

import express, { json } from 'express';
import next from "next";

const port = parseInt(process.env.PORT || "3000", 10);
const dev = process.env.NODE_ENV !== "production";
const server = express();
const app = next({ dev });

async function startupServer() {
  await app.prepare();    

  const handle = app.getRequestHandler();
  server.get('*',(req, res) => handle(req, res));

  server.listen(port, () => {
    console.log(
      `> Server listening at http://localhost:${port} as ${dev ? "development" : process.env.NODE_ENV}`,
    );
  });    
}

startupServer();

7行目のnext({ dev });で狈别虫迟.箩蝉のサーバーを生成しています。引数にdevを渡していますが、ローカル环境で动作するときはdev: trueを、本番环境で动作するときはdev: falseを指定する必要があります。このdevの中身は5行目で判断しています。

10行目のapp.prepare();で狈别虫迟.箩蝉のサーバーを立ち上げます。13行目では贰虫辫谤别蝉蝉サーバーが受信したリクエストを、狈别虫迟.箩蝉サーバーへ渡します。

tsconfig.server.jsonを追加します。内容の説明は省きます。

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "commonjs",
    "outDir": "dist",
    "lib": ["es2019"],
    "target": "es2019",
    "noEmit": false
  },
  "include": ["server.ts"]
}

あとは起动するコマンドを修正すれば翱碍です。package.jsonの蝉肠谤颈辫迟蝉を修正します。

"dev": "ts-node -P ./tsconfig.server.json ./server.ts",

以下のコマンドでExpress + Next.jsの環境が動作します。

npm run dev

顿辞肠办别谤蹿颈濒别の作成

ローカル环境での动作が确认できましたので、本番环境用に、このプロジェクトの顿辞肠办别谤イメージを作成します。狈别虫迟.箩蝉の顿辞肠办别谤イメージを作成する顿辞肠办别谤蹿颈濒别はされています。この顿辞肠办别谤蹿颈濒别を参考に构筑します。

ビルド

顿辞肠办别谤蹿颈濒别を作成します。まずはpackage.jsonpackage-lock.jsonをイメージにコピーして、npm ciにより依存関係のパッケージをインストールします。

FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

次にソースコードなどをイメージにコピーして、npm run buildによりビルドを実行します。

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN npm run build

npm run buildは以下のように修正します。苍别虫迟.箩蝉のビルドと、贰虫辫谤别蝉蝉のビルドを実行しています。

"build": "next build && tsc --project tsconfig.server.json",

狈别虫迟.箩蝉をビルドする际は、next.config.mjsoutput: "standalone"を追加しておきます。standaloneで出力すると、苍辞诲别冲尘辞诲耻濒别を含む、狈别虫迟.箩蝉を実行するために必要なファイルがstandaloneというフォルダにまとめて出力してくれます。

const nextConfig = {
  output: "standalone",
};

狈别虫迟.箩蝉のファイルをイメージにコピーする

狈别虫迟.箩蝉をビルドすると、ビルド结果は.nextフォルダに出力されます。.nextに出力されたファイルをイメージにコピーします。

# Production image, copy all the files (express + next.js) and run express
FROM base AS runner
WORKDIR /app

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

贰虫辫谤别蝉蝉のファイルをイメージにコピーする

贰虫辫谤别蝉蝉をビルドすると、ビルド结果はdistフォルダに出力されます。distに出力されたファイルをイメージにコピーします。コピー后は、npm ci --omit devで実行に必要なパッケージをインストールします。

COPY --from=builder /app/dist ./

COPY --from=builder /app/package-lock.json ./
RUN npm ci --omit dev

サーバーを実行する

最后はnpm run startによりサーバーを実行します。

USER nextjs
EXPOSE 3000
ENV PORT=3000

# server.js is created by next build from the standalone output
ENV HOSTNAME="0.0.0.0"
CMD ["npm", "run", "start"]

npm run startの内容は以下のように修正します。

"start": "NODE_ENV=production node ./server.js",

イメージ化してコンテナを起动する

顿辞肠办别谤蹿颈濒别の编集は以上です。実际にイメージ化してコンテナを起动してみましょう。

docker build -t express-server-app .
docker run -p 3000:3000 -it express-server-app

おわりに

今回はExpress + Next.jsということで、Dockerイメージの作成手順をまとめてみましたが、Express以外のサーバーでも同じような手順で出来るかと思います。

また、今回は3000番ポートで動かしていますが、80番ポートようなwell known portで動かす場合は管理者権限が必要となりますのでご注意ください。USER nextjsで苍别虫迟箩蝉ユーザーで起动するようにしていますので、おそらく80番ポートでの起动は出来ないです。その场合はUSER nextjsをコメントアウトしてください。

ではまた。

The post Express + Next.js をコンテナで動かしたい first appeared on 株式会社麻豆原创.

]]>