【CI/CD】Next.jsをCloudRunにデプロイするまで

# 前提条件
- create-next-appでNextのアプリを作成済み
- GCPのプロジェクト作成済み

# Nextの設定
作成または編集が必要なのは以下のファイルです。
- next.config.mjs
- Dockerfile
- .dockerignore

## next.config.mjs

```next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "standalone",
};

export default nextConfig;
```

上記のようにoutput: "standalone"と追加します。
standaloneを有効にすることで、ビルドすると時に`.next`ディレクトリ下に`standalone`フォルダが作成されます。
`standalone`フォルダ内には動作に必要最小限のファイル群がコピーされ、ビルドサイズを小さくすることができます。

## Dockerfile

```Dockerfile
FROM node:22.4.0-slim AS base

# Install dependencies only when needed
FROM base AS deps
WORKDIR /app

COPY package.json yarn.lock* ./
RUN yarn --frozen-lockfile; 

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

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN yarn run build;

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

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

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

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD HOSTNAME="0.0.0.0" node server.js
```

ほとんど`npx create-next-app --example with-docker nextjs-on-cloudrun`を実行したときのDockerfileと同じです。
編集した箇所としては、ベースイメージをalpineから変更していることと、パッケージマネージャーに`yarn`を使用していることくらいです。

### .dockerignore

```.dockerignore
# デフォルトで指定されていた
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git

# 開発環境にあればよい
.vscode
.husky

# ログファイル
yarn-error.log*
```

こちらは特に特筆することは無いと思います。
コンテナに含める必要のないファイルを指定しておきましょう。

## GitHubにプッシュ

最後にNextアプリをGitHubにプッシュしておきましょう。
GCPで設定を行うことによって、`main`ブランチにプッシュされた時、自動でビルド/デプロイすることが可能です。

ローカルからリモートリポジトリにpushする必要があるならば、以下の記事を参照してください。
https://qiita.com/SBS_Takumi/items/c5103820ecdfcd0386b7

# GCPの設定

## サービスの作成

GCPのプロジェクトページ、左のメニューから`Cloud Run`のページに移動します。
画面上部の検索窓からもページを探すことができます。

`Cloud Run`のページに移動できたら、画面上部の`サービスを作成`をクリックします。

![Screenshot from 2024-07-04 13-31-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/ecc2c078-4424-8dab-f139-03354739d242.png)

今回はGitHubからデプロイするので、GitHubを選択します。
次に`CLOUD BUILDを設定`をクリックします。

### CLOUD BUILDの設定

![Screenshot from 2024-07-04 13-32-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/7d165035-7222-7ea9-fc0a-6c8342f57f80.png)

上の画像のようなメニューが開きます。
初めてCloud Runを使用するときは、必要なAPIがダウンロードされるので待ちます。

ダウンロードが終わったら、使用するリポジトリを選択します。
`次へ`をクリックすると下の画像の状態になると思います。

![Screenshot from 2024-07-04 13-32-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/6a3d60ab-5073-3537-6266-22146a7c2700.png)

mainブランチにpushされたときに自動でビルド/デプロイが実行されます。
ビルドタイプは先程Dockerfileを作成したので、`Dockerfile`を選び、保存しておきます。

### その他の設定

この後、サービス名やリージョンなど設定を行いますが、プロジェクトによって異なるので割愛したいと思います。
サービスの自動スケーリングは、インスタンスの数が増えると料金が跳ね上がる原因になるので必要に応じて大きくしていくといいと思います。
はじめは少なくいきましょう。

すべての設定を終わらせて、`作成`をクリックするとサービスの作成が始まります。

作成が終わると、自動的にビルドが実行されます。

ビルドが成功すると、サービスが公開されます。
サービスのページにあるURLから見に行ってみましょう。