7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【EKS✖️Helmチャート】Next.jsアプリを公開しよう!

Posted at

概要

Next.jsで作成したアプリを AWS EKS上にデプロイする方法を紹介します!
以前はGoで実装したAPIをk8s環境にデプロイする記事も書きました!

ローカルのk8sではなく、EKSにデプロイする記事もということで
今回はNext.jsにて試します!

前提条件

  • node.jsの開発環境が整っていること
  • Docker と Kubernetes(k8s)がインストールされていること
  • AWS ECR(Elastic Container Registry)へのアクセス権限があること

また今回はHelm Chartを使用して、k8sリソース作成を
簡略化します!

Helmについては以下記事で入門編として解説してます!

1. Next.js プロジェクトを作成

Next.jsアプリを作成し、ウェルカムページを表示します!
今回はこの状態でEKSにデプロイしようと思います。

npx create-next-app@latest nextjs-app
cd nextjs-app

# 動作確認
npm run dev

注意

今回はEKSにデプロイすることがメインなので、
Next.jsの実装はあまり触れないです!

2. Dockerfile の作成

次に、アプリケーションを Docker コンテナにパッケージングするための Dockerfile を作成します。

FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm install

FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app

# 本番に必要なものだけコピー
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./

EXPOSE 3000
CMD ["npm", "start"]

今回は実装少ないですが、ライブラリをインストールしたりすると重くなるので
マルチステージビルド等で工夫すると尚良いかと!

3. Docker イメージをビルド

次に、Docker イメージをビルドします。

$ docker build -t nextjs-app .

一応ローカルでも動作確認してみよう!

1. Docker イメージをビルド

docker build -t nextjs-app .

-t nextjs-app はタグ名の指定です(任意)

2. コンテナを起動

docker run -p 3000:3000 nextjs-app

-p 3000:3000 でローカルのポート3000にバインドします。

3. ブラウザでアクセス

http://localhost:3000

Next.js のトップページが表示されれば成功です ✅

4. AWS ECR に Docker イメージをプッシュ

AWS ECR を使用して、作成した Docker イメージをアップロードします。

ECR にリポジトリを作成

AWSマネジメントコンソールにログインし、ECRにリポジトリを作成しましょう。
名称は任意で大丈夫です!

スクリーンショット 2025-04-29 15.22.17.png

作成したら、画面右上に「プッシュコマンドを表示」ボタンがあります。
これを押下すると、何とECRにPushするところまで方法を案内してくれます!

スクリーンショット 2025-04-29 15.22.35.png

5. Kubernetes クラスタの準備

kubectl コマンドで Kubernetes クラスタに接続していることを確認します。
今回は、kind でクラスタを作成する方法を記載します。

$ kind create cluster

6. Helm を使ってデプロイ

helm を使って、Kubernetes 上に Next.jsアプリをデプロイします。
まずは、Helm チャートのテンプレートを作成し、values.yaml を編集します。

Helm Chartを作成する

$ helm create nextjs-chart

これで go-api/ ディレクトリができ、k8sリソースを作成するための
基本構成が入っています。

ディレクトリ構成例

nextjs-chart/
  Chart.yaml          # Chartの基本情報
  values.yaml         # デフォルトの変数
  templates/          # K8sマニフェスト(Helmテンプレート)
    deployment.yaml   # デプロイメント定義
    service.yaml      # サービス定義
    ingress.yaml      # ingress
    ...

values.yaml

values.yaml
replicaCount: 1

image:
  repository: {作成したECRのURI}
  tag: {作成したECRのタグ}

service:
  name: nextjs-chart
  type: ClusterIP
  port: 3000

readinessProbe:
  httpGet:
    path: /test
    port: 3000
  initialDelaySeconds: 3
  periodSeconds: 10

ingress:
  enabled: true # falseになるとIngress リソースが作成されないので注意!
  className: "alb" # ingress.yamlのingressClassNameに該当
  annotations: {}
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []

deployment.yaml

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextjs-chart
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: nextjs-chart
  template:
    metadata:
      labels:
        app: nextjs-chart
    spec:
      containers:
        - name: nextjs-chart
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: 3000
          livenessProbe:
            httpGet:
              path: {{ .Values.livenessProbe.httpGet.path }}
              port: {{ .Values.livenessProbe.httpGet.port }}
          readinessProbe:
            httpGet:
              path: {{ .Values.readinessProbe.httpGet.path }}
              port: {{ .Values.readinessProbe.httpGet.port }}

ingress.yaml

ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nextjs-ingress
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nextjs-chart
                port:
                  number: 3000
                  

7. ingressの説明

改めてingressの説明!

Kubernetes の Ingress リソースは、
クラスター外部からの HTTP/HTTPS トラフィックを
Service にルーティングするためのエントリポイントです!

特に複数のアプリケーション(Next.js✖️go)のように、ドメインを集約し、
パスベースで振り分ける場合に非常に有効です。

  • 「/」とか「/api」みたいに
  • ingressを介して、ルーティングするためにALB Ingress Controllerをインストールします(8番で手順を説明します)

8. ALB Ingress Controllerをインストール(初回のみ)

① [IAM OIDC provider の有効化](初回のみ)

eksctl utils associate-iam-oidc-provider --region ap-northeast-1 --cluster <CLUSTER_NAME> --approve

② IAM Policy の作成

curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json

aws iam create-policy \
  --policy-name AWSLoadBalancerControllerIAMPolicy \
  --policy-document file://iam_policy.json

③ Service Account 作成(--cluster はあなたのEKS名に)

eksctl create iamserviceaccount \
  --cluster <CLUSTER_NAME> \
  --namespace kube-system \
  --name aws-load-balancer-controller \
  --attach-policy-arn arn:aws:iam::<AWS_ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
  --approve

④ Helm を使って Controller をインストール

helm repo add eks https://aws.github.io/eks-charts
helm repo update

helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=<CLUSTER_NAME> \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set region=ap-northeast-1 \
  --set vpcId=<VPC_ID> \
  --set image.repository=602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon/aws-load-balancer-controller

vpcId は aws eks describe-cluster --name で取得できます。

⑤ 確認!

kubectl get pods -n kube-system | grep aws-load

Pod が Running になればOKです!

9. Kubernetes にデプロイ

次に、Helm を使って Kubernetes クラスタにデプロイします。

#「nextjs-chart」は任意で変えて大丈夫です
$ helm install nextjs-chart ./nextjs-chart

# Ingress確認(ALBのDNSが表示されるまで少し待ちます)
kubectl get ingress

これで、Next.jsアプリが Kubernetes 上でデプロイされ、サービスが公開されます。

10. 動作確認

デプロイ後、以下のコマンドでリソースが正常にデプロイされているか確認します。
まずはPodが起動しているかをチェック。

動作確認

$ kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
nextjs-chart-cd454c75-jk6wv   1/1     Running   0     2s
$ kubectl get ingress
NAME             CLASS   HOSTS                 ADDRESS                                                               PORTS   AGE
app-nextjs       alb     chart-example.local                                                                         80      44s
nextjs-ingress   alb     *                     k8s-frontend-63afaf69ef-1598947954.ap-northeast-1.elb.amazonaws.com   80      44s

アクセス確認

  • 表示されたALBのDNSにブラウザでアクセス(http://<ALB-DNS>/
  • Next.jsトップページが表示されれば成功!

スクリーンショット 2025-05-03 2.45.14.png

Next.jsのウェルカムページの表示が
確認できればOKです!

まとめ

今回は Next.jsアプリをEKSにデプロイする方法を紹介しました!
k8sを個人開発で使用するための入門として、お役に立てれば幸いです!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?