0
0

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】Next.js SSR→Rails API pod間のAPIリクエスト

Last updated at Posted at 2025-08-08

Next.jsのサーバーサイドレンダリング (SSR) と、同じEKSクラスター内で稼働するバックエンド(Rails)のpod間の通信でハマってしまったので、備忘録で解決策とハマったポイントを書いてみます。

課題:Next.jsのSSRからRails APIへのリクエストがうまくいかない

Next.jsで構築されたフロントエンドと、Railsで構築されたバックエンドが同じEKSクラスター内にあり、それぞれが独立したPodとして稼働している状態でした。

フロントエンド: Next.js (Pages Router)
バックエンド: Ruby on Rails

このような環境で、Next.jsのSSR (getServerSideProps) 内でRailsのAPIを叩いて、データを取得しようとしたところ、APIリクエストがなぜか失敗してしまうという問題に直面しました。

// pages/index.js (例)
export async function getServerSideProps() {
  // このfetchがうまくいかない...
  const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/v1/posts`);
  const posts = await res.json();
  return { props: { posts } };
}

ローカル環境では.envファイルにNEXT_PUBLIC_BASE_URL='http://localhost:0000'と指定してDockerで接続していたため問題なく動いていたのですが、EKS環境にデプロイするとfetchが出来ずエラーとなってしまいました。

原因:SSRとクライアントサイド通信の違い

Next.jsのSSRは処理がクライアントではなくサーバーサイドで実行されるということは理解していましたが、APIをリクエストする際の通信の違いをきちんと理解できていなかった為、かなりハマってしまいました。

  • クライアントサイドでの通信:
    • ブラウザからRails API Podに対して、外部のロードバランサーやIngressを経由してHTTPSリクエストが送信される
    • fetchのURLは、外部からアクセス可能なドメイン名やIPアドレスになる
       
  • SSR (Node.js) での通信:
    • SSRはサーバーサイド (Node.js) で実行されるため、Next.jsのpodからRailsのPodへ直接リクエストを送信する
    • これはクラスター内部の通信であり、外部のドメイン名やIPアドレスは利用できない

SSR内のfetchlocalhostや外部のドメインを指定しても、Next.jsのpodから見ると通信先が正しくないため、リクエストが失敗してしまっていたようでした。

ポイント1:SSRのfetchは絶対パスにする

SSRでfetchを使用する場合、相対パスではなく、完全なURL (絶対パス) を指定する必要がありました。
環境変数で登録していたNEXT_PUBLIC_BASE_URLは、空文字の場合相対パスとなりますので、クライアントサイドの場合は自動で現在のオリジンを利用してリクエストを送信します。
が、SSRはサーバーサイドで実行されるので、絶対パスを指定する必要があるそうです。

ポイント2:クラスター内部通信にはService名を利用する

前述した通り、今回のパターンでは外部のドメイン名やIPアドレスは利用できないので、podのservice名を指定する必要がありました。

解決策:Service名を利用した内部通信

解決策としては、以下の2つの設定を行うことで、Next.js SSRからRailsのAPIへの通信ができるようになりました。

1. Railsの設定ファイルでService名を許可する

もしconfig.hostsの設定がある場合は、ここにpodのservice名を追記します。
これにより、Railsはクラスター内部からのリクエストを受け付けるようになります。

# config/environments/production.rb (例)
Rails.application.configure do
  # ...
  # RailsのService名を指定
  config.hosts << "rails-api-service-name" 
  # ...
end

config.hosts.clearの設定がある場合は、すべてのリクエストを受け付ける状態(非推奨)なので、この設定は不要です。

2. Next.js SSRのfetchURLを変更する

SSR内のfetchのURLを、RailsのpodのService名とポート番号を使った内部通信用の形式に変更します。

// pages/index.js (例)
export async function getServerSideProps() {
  const serviceName = process.env.SERVICE_NAME; // http://rails-api-service-name:3000
  
  // Service名とポート番号を指定して内部通信
  const res = await fetch(`${serviceName}/api/v1/posts'`);
  const posts = await res.json();
  return { props: { posts } };
}

この修正で、バックエンドのAPIを叩けるようになりました!

まとめ

ローカルでは発生しないエラーでしたのでデバッグが少し大変だったのと、
SSR側でエラーの内容をconsole.logで出力してみたところ 今回の原因とは全く違う部分(エラーログ出力時のエラー)が出たのもあって、原因特定まで時間を要してしまいましたが、理解を深めることができてよかったです!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?