Express + Next.js をコンテナで咾したい

峻さん、こんにちは。室宝蝕kグル`プの稼-看噛温敬温稼です。
9埖ですね。定を嶷ねると扮寂Uつのが壼く湖じる嶇鵑髻献献礇幽`の隈夸々といいます。

云籾です。
Express + Next.jsで撹したフロントエンドh廠をコンテナで嘛させたい栽、どのような返でDockerイメ`ジを恬撹すればよいでしょうか。書指は、Express + Next.jsで撹したフロントエンドh廠をイメ`ジ晒するまでの返をまとめたいと房います。

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

まずはExprerss + Next.jsで撹されたプロジェクトを笋靴泙后R塹造離灰泪鵐匹Next.jsをBします。余嶄の|は畠てデフォルトのままで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を弖紗します。坪否のh苧は福きます。

{
  "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のh廠が嘛します。

npm run dev

禽看界一艶姻韓庄鉛艶の恬撹

ロ`カル桟廠での強恬が鳩範できましたので、云桑桟廠喘に、このプロジェクトの禽看界一艶姻イメ`ジを恬撹します。鰻艶恰岳.逮壊の禽看界一艶姻イメ`ジを恬撹する禽看界一艶姻韓庄鉛艶はされています。この禽看界一艶姻韓庄鉛艶を歌深に更廏します。

ビルド

禽看界一艶姻韓庄鉛艶を恬撹します。まずはpackage.jsonpackage-lock.jsonをイメ`ジにコピ`して、npm ciにより卆贋vSのパッケ`ジをインスト`ルします。

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によりビルドをg佩します。

# 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は參和のように俐屎します。稼艶恰岳.逮壊のビルドと、掘恰沿姻艶壊壊のビルドをg佩しています。

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

鰻艶恰岳.逮壊をビルドする縞は、next.config.mjsoutput: "standalone"を弖紗しておきます。standaloneで竃薦すると、稼看糸艶喝馨看糸顎鉛艶を根む、鰻艶恰岳.逮壊をg佩するために駅勣なファイルが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でg佩に駅勣なパッケ`ジをインスト`ルします。

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

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

サ`バ`をg佩する

恷朔はnpm run startによりサ`バ`をg佩します。

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",

イメ`ジ晒してコンテナを軟強する

禽看界一艶姻韓庄鉛艶の園鹿は參貧です。g縞にイメ`ジ晒してコンテナを軟強してみましょう。

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をコメントアウトしてください。

ではまた。


Recommendおすすめブログ