本ページはプロモーションが含まれています

Java入門

JavaとNginxの連携方法|Spring Boot向けproxy_pass設定を解説

CATEGORY
REV.
DRAWN BY
TOM
SHEETS
10枚
proxy_pass(JavaとNginxの連携)

トム

SESで約8年、環境を変えられないもどかしさの中にいました。32歳で自社開発企業に転職し、今はClaude Codeと自動化で、仕事も時間も組み直している途中です。
・Javaバックエンドエンジニア(Java歴12年以上)
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎
詳細なプロフィール

𝕏

「Spring Bootだけで本番運用してはいけないのか」と一度は疑問に思ったはずです。動かせなくはない、というのが正直なところです。

ただしSSL証明書の更新のたびにアプリ側での差し替え対応(再起動、またはSSLバンドルのreload-on-update設定)が必要になり、静的ファイル配信までアプリ側に背負わせるとスレッドプールを無駄に消費します。

Nginxを前段に置けば、この二つの負担はまるごと切り離せます。

proxy_pass設定自体は最短1行、location / { proxy_pass http://127.0.0.1:8080; } を追記するだけで動き始めます。

この記事では、この最短設定から一歩進んで、HTTPS化したときに必要になるX-Forwarded-*ヘッダーとSpring Boot側のserver.forward-headers-strategy設定、SSL終端・ロードバランシング・Docker Compose構築までの3つの実装パターンを、設定例付きで解説します。

私はJava歴12年のバックエンドエンジニアとして、Webシステムを構築してきました。

その経験から、502 Bad Gatewayの8割はJavaアプリの起動失敗が原因であるなど、現場で実際につまずくポイントも合わせて紹介します。

JavaとNginxそれぞれの役割の違いを理解したうえで、すぐに使える設定まで一気に把握できる内容です。

Nginxとは、大量の同時接続を高速にさばけるWebサーバー/リバースプロキシソフトウェアで、Javaアプリの前段に置くことでSSL終端や静的ファイル配信を肩代わりする役割を持ちます。

この記事でわかること

  • NginxとJavaの役割の違いと連携の仕組み
  • proxy_pass設定など、すぐ使える具体的な実装手順
  • HTTPS化で必要なX-Forwarded-*ヘッダーとSpring Boot側の設定
  • SSL終端・タイムアウト・トラブルシューティングの実務ポイント

PARTS LIST /目次

JavaとNginxの違いとは?役割と連携の全体像

JavaとNginxはそもそも役割が異なります。

Javaはビジネスロジックを処理する「アプリケーションサーバー」、Nginxはリクエストを受け付けて振り分ける「Webサーバー/リバースプロキシ」です。

この2つを組み合わせる最大の目的は、それぞれの得意分野を活かしてシステムの安定性と性能を高める点にあります。

スレッドベースのJavaアプリ(従来のSpring MVCやTomcat)は接続ごとにスレッドを使うため、大量の同時接続時にメモリ使用量が増大しやすい傾向があります。

一方でNginxは、ノンブロッキングI/Oにより軽量で大量の同時接続を処理することに特化しています。

NginxとJavaアプリを連携させるのは、システム構築における定石といえます。

Nginxの役割(リバースプロキシ・LB)

Nginxは、ユーザーからのアクセスを最初に受け取る「受付係」の役割を果たします。

この仕組みを「リバースプロキシ」と呼びます。

ユーザーが直接Javaアプリにアクセスするのではなく、Nginxが一度リクエストを受け取り、それを後ろにいるJavaアプリに渡す仕組みです。

また、アクセスが増えた場合に複数のJavaアプリへ処理を振り分ける「ロードバランサ」としての役割も担います。

リバースプロキシの仕組みにより、Javaアプリは重い通信処理から解放され、ロジックの実行のみに集中できます。

JavaアプリとNginxの連携構図

基本的な連携の構図は、Nginxが前段(フロント)に立ち、Javaアプリが後段(バックエンド)に控える形です。

具体的には、Nginxが80番ポート(HTTP)や443番ポート(HTTPS)で待機します。

Javaアプリ(例えばTomcatやJettyを内蔵したSpring Boot)は、外部からアクセスできない8080番ポートなどで起動しておきます。

Nginxは受け取ったリクエストを、内部ネットワークを通じてJavaアプリのポートへ転送します。

ユーザーからはNginxだけが見えており、裏側でJavaが動いていることは分かりません。この隠蔽がセキュリティ向上につながります。

JavaとNginxの連携構図
CLIENT / 利用者クライアントHTTPSでアクセス
FRONT / 前段NginxSSL終端・静的配信・振り分け
BACKEND / 後段Spring Bootアプリ本体(例:8080番。外部からは直接アクセスできない)
NOTEレスポンスも同じ経路を戻ります。利用者からはNginxだけが見え、裏側のJavaは見えません。

NginxとSpring Bootの違い

「NginxとSpring Bootは何が違うのか」という疑問は、Java開発者なら一度は持つものです。

結論から言えば、両者は競合関係ではなく補完関係にあります。

Nginxは、HTTPリクエストの受付・静的ファイルの配信・リバースプロキシに特化したWebサーバーです。

一方、Spring BootはビジネスロジックやAPI処理を担うJavaアプリケーションフレームワークであり、内蔵Tomcatでリクエストを受け取ります。

Spring Boot単体でも本番運用は可能です。

ただしNginxを前段に配置すれば、SSL終端・静的ファイル配信・ロードバランシングを分離でき、Spring Boot側はビジネスロジックの処理に集中できます。

この役割分担が、本番環境でNginxとSpring Bootを組み合わせる最大の理由です。

なお、Spring Bootが内部で使うTomcatも、NginxとはWebサーバーとアプリケーションサーバーという同じ役割分担の関係にあります。

Tomcatも静的ファイル配信やSSL終端に対応していますが、これらをNginxに任せるとアプリ側の設定と負荷を減らせるため、この点でもNginxを前段に置く構成が有効です。

あわせて読む

Nginx連携がJavaにもたらすメリット

この連携構成を採用するメリットは、主にセキュリティ、パフォーマンス、運用性の3点です。

  • セキュリティ:Javaアプリを直接インターネットに晒さないため、攻撃を受けるリスクが減ります。
  • パフォーマンス:画像やCSSなどの静的ファイルをNginxが高速に配信することで、Java側の負荷を大幅に下げられます。
  • 運用性:SSL/TLS処理をNginxに集約することで証明書管理が一元化され、更新作業もNginx側だけで完結するため、運用が楽になります。

NginxとJavaの基本的な連携設定

連携を実現するための設定は、決して難しくありません。基本的にはNginxの設定ファイルに数行追記するだけで完了します。

ここでは、Linux環境(Ubuntu 24.04 LTS/26.04 LTSやRHEL 9系・10系など)を想定して、インストールから設定ファイルの記述までを順を追って解説します。

Nginxのインストールと起動

まずはサーバーにNginxをインストールしましょう。パッケージ管理ツールを使えばすぐに導入できます。

この記事は執筆時点(2026年8月)のnginx安定版1.30系をもとにしています。

step
1
Nginxをインストールする

Ubuntuであればapt install nginx、RHEL 9系・RHEL 10系(AlmaLinux / Rocky Linux含む)であればdnf install nginxを実行します。

旧CentOS 7系(2024年6月EOL)を使っている場合はyum install nginxですが、サポート終了済みのため移行を推奨します。

step
2
サービスを起動し自動起動を有効にする

インストールが完了したら、以下のコマンドでサービスを起動して自動起動設定も有効にしましょう。

sudo systemctl start nginx
sudo systemctl enable nginx

これでサーバー再起動時にも自動的にNginxが立ち上がります。なお、設定ファイルを変更した際は nginx -t で構文チェックを行い、systemctl reload nginx で設定を反映してください。

設定ファイルは通常 /etc/nginx/nginx.conf または /etc/nginx/conf.d/ 配下にあります。

これらを編集して連携設定を行います。

Javaアプリ側のポート設定

Javaアプリ側は、ローカルからのアクセスだけを受け付けるように設定するのが理想です。

Spring Bootを使用している場合、application.propertiesファイルでポートを指定します。

通常はデフォルトの8080番ポートで問題ありませんが、複数のアプリを動かす場合はポートが被らないように8081、8082とずらす必要があります。

Javaアプリ自体を「0.0.0.0(全公開)」ではなく「127.0.0.1(ローカルホストのみ)」でリッスンさせる構成も検討してください。

これにより、Nginxを経由しない直接アクセスを物理的に遮断できます。

あわせて読む

Javaへのproxy_pass設定

proxy_passとは、Nginxが受け取ったリクエストを指定した別サーバー(この場合はJavaアプリ)へそのまま転送するディレクティブです。

設定ファイルの location ブロック内に、転送先のURLを記述します。

例えば、ローカルの8080番ポートで動いているJavaアプリに転送する場合は、以下のように記述します。

location / {
    proxy_pass http://127.0.0.1:8080;
}

この一行があるだけで、Nginxに来たアクセスは全てJavaアプリへと流れます。これが連携の最も基本的な形です。

実運用では proxy_http_version 1.1; を明示しておくと安心です。

なお、nginx 1.30以降はproxy_http_versionのデフォルト値がHTTP/1.1(Keep-Alive有効)に変更されています。

最新版を使っていれば明示しなくても動作しますが、バージョンに依存しない書き方として明記しておくことをおすすめします。

JavaとNginx連携でよく使われる構成パターン

結論から言うと、迷ったらまず「Nginxをフロントに置くリバースプロキシ構成」を選べば失敗しません。

アクセス数やシステム規模が大きくなった段階で、ロードバランシング構成やハイブリッド構成へ移行を検討すれば十分です。

システムの規模や要件によって、連携のパターンはいくつか存在します。ここでは代表的な3つの構成を紹介します。

ご自身のプロジェクトに最適な構成を選ぶための参考にしてください。

Nginxを前段に置くリバースプロキシ構成

最もシンプルで一般的なのが、1台のサーバー内にNginxとJavaアプリを同居させる構成です。

小規模なWebサービスや社内ツールであれば、この構成で十分です。Nginxが静的ファイルの配信とSSL終端を行い、動的な処理だけをJavaに投げます。

サーバーのリソースを効率よく使えるため、コストパフォーマンスに優れています。

まずはこの構成から始めて、アクセスが増えてきたらサーバーを分けるステップアップが可能です。

複数Javaアプリのロードバランシング構成

Nginxの upstream ブロックを使用することで、複数の転送先をグループ化できます。

例えば、Javaアプリを3つ起動しておき、Nginxが順番にリクエストを振り分ける設定が可能です。

これにより、1つのJavaアプリがダウンしても、他のアプリが処理を継続できるため、サービスの可用性が飛躍的に向上します。

upstreamで複数のJavaアプリに振り分ける
CLIENT / 利用者リクエスト
FRONT / upstreamNginx3つの転送先を1つのグループにまとめる
転送先
① 通常時
② アプリ2が停止
アプリ1
稼働中・受ける
稼働中・受ける
アプリ2
稼働中・受ける
✗ 停止
アプリ3
稼働中・受ける
稼働中・受ける
NOTEアプリ2が停止しても、残り2つで処理を継続できます。アプリの数は本文の例(3つ)に合わせています。

静的と動的を分けるハイブリッド構成

Webページの表示速度を極限まで高めたい場合、静的コンテンツと動的コンテンツの処理を明確に分離します。

画像、CSS、JavaScriptファイルは、Javaを経由させずにNginxから直接返却します。

Nginxは静的ファイルの配信速度に優れているためです。Javaアプリにはデータベースアクセスが必要な処理だけを依頼します。

設定例としては、拡張子が .jpg や .css のリクエストはローカルのディレクトリを参照させ、それ以外を proxy_pass でJavaに送るように記述します。

Spring Boot以外のJavaでも同じ構成

ここまでの構成はSpring Bootを前提に説明してきましたが、Nginxが見ているのはHTTPリクエストとレスポンスだけであり、背後のJavaアプリが何で書かれているかは関知しません。

Tomcatに直接デプロイした素のServlet/JSPアプリでも、application.propertiesの代わりにserver.xmlのConnector設定でポートを固定すれば、proxy_passの書き方はこの記事と同じです。

フレームワークの違いはリバースプロキシ層には影響しません。

Spring BootとNginxの連携実装例

ここでは、具体的なコードや設定値を交えて実装例を解説します。実際に手を動かしながら確認してみてください。

Javaフレームワークとして人気の高いSpring Bootを例に挙げますが、他のフレームワークでも基本的な考え方は同じです。

Spring Bootのポートを固定する

Spring Bootアプリの起動ポートを明示的に指定します。

server.port=8080

もしサーバー内で複数のJavaアプリを動かすなら、2つ目のアプリは8081にするなどして重複を避けます。

開発環境と本番環境でポートを変えたい場合は、Spring Bootのプロファイル機能を使いましょう。

application-dev.properties / application-prod.propertiesのように設定ファイルを分けると管理しやすくなります。

/apiだけJavaに送るserver設定

Webサイトの画面(HTML/JS)とAPIサーバーを分ける構成の例です。/api で始まるURLだけをJavaに転送する設定です。

server {
    listen 80;
    server_name example.com;

    # 静的ファイル(ReactやVueのビルドファイルなど)
    location / {
        root /var/www/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    # APIリクエストはJavaへ転送
    location /api {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

このようにパスごとに処理を分けることで、フロントエンドとバックエンドをきれいに分離できます。

NginxでCORSとヘッダーを制御する

フロントエンドとバックエンドを分離する構成が一般的になった2026年8月時点、別オリジン(ドメインやポートが異なる)のフロントエンドからAPIを呼ぶ場合は、CORS(Cross-Origin Resource Sharing)の設定が必要です。

Java側でCORS設定を行うことも可能ですが、Nginx側で一括管理したほうがコードの変更が不要になり、運用の手間が減ります。

add_header ディレクティブを使って、許可するドメインやメソッドを指定します。

また、proxy_set_header を使って、クライアントの本来のIPアドレスをJava側に伝える設定も必要です。

これがないと、Java側では全てのアクセスがNginx(ローカルホスト)から来ているように見えてしまい、ログ分析ができなくなります。

Docker ComposeでNginx連携環境を構築

2026年8月時点でも、Dockerを使った開発・デプロイが主流です。

NginxとSpring Bootの連携もDocker Composeで簡単に構築できます。

基本的な構成は、NginxコンテナとSpring Bootコンテナの2サービス構成です。

Nginxの設定ファイル(default.conf)をvolumesでマウントし、proxy_passでSpring Bootコンテナのサービス名を指定します。

# docker-compose.yml
services:
  nginx:
    image: nginx:1.30-alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app

  app:
    build: .
    expose:
      - "8080"

Nginxの設定ファイルでは、proxy_passのホスト名にDockerのサービス名(上記例ではapp)を指定します。

Docker内部のDNSが自動的に名前解決してくれるため、IPアドレスを意識する必要がありません。

docker compose up を実行するだけで、Nginx+Spring Bootの連携環境が立ち上がります。

あわせて読む

JavaとNginxを組み合わせる際の注意点

強力な連携ですが、タイムアウト・ファイルサイズ制限・SSL終端の3点で落とし穴があります。

これらを知らずに運用を始めると、思わぬトラブルに見舞われる可能性があります。

特にタイムアウト設定やファイルサイズの制限は、初期設定のままだとエラーの原因になりやすいため注意が必要です。

proxy_read_timeoutのタイムアウト設定

Java側で重い処理(例えば帳票作成やバッチ処理)を行う場合、レスポンスが返ってくるまでに時間がかかることがあります。

Nginxのproxy_read_timeoutのデフォルト値は60秒です(Nginx公式ドキュメント準拠)。

もしJavaの処理が60秒を超えると、Nginxは「待ちきれない」と判断して接続を切断し、ユーザーにエラー画面を表示してしまいます。

これを防ぐには、proxy_read_timeout の値を長めに設定します。処理内容に応じて、300秒(5分)などに延ばす検討をしてください。

アップロード容量の上限を引き上げる

画像のアップロード機能などで、大きなファイルを送信しようとするとエラーになることがあります。

これはNginxの client_max_body_size という設定が、デフォルトで1MBに制限されているためです。

スマホで撮影した写真などは数MBになることが多いため、この制限に引っかかります。

必要に応じて client_max_body_size 10M; のように記述し、上限を引き上げておく必要があります。

Java側だけでなく、Nginx側の制限も確認するのがポイントです。

SSL終端はNginxとJavaのどちらで行うか

通信の暗号化(SSL化)をどこで行うかという問題です。

基本的には「NginxでSSLを終端(復号)し、NginxとJavaの間は平文(HTTP)で通信する」構成をおすすめします。

これにより、Javaアプリは暗号化の負荷から解放されます。

社内システムやBtoB SaaS、メディアサイトなど一般的なWebサービスであれば、Nginxで終端する構成で十分です。

ただし、金融系システムなど高いセキュリティ要件がある場合、内部ネットワークであっても暗号化が求められることがあります。

その場合はJava側でもSSL設定を行いますが、運用コストとCPU負荷は高くなります。

X-Forwarded-*ヘッダーとSpring Boot設定

NginxでSSLを終端する構成では、Spring Bootには平文のHTTPでリクエストが届きます。

そのままだとSpring Bootは「自分はHTTPで呼ばれた」と判断し、ログイン後のリダイレクト先などを http:// のURLで生成してしまいます。

これを防ぐには、Nginx側で元のプロトコルを X-Forwarded-Proto ヘッダーとして渡します。

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Spring Boot側では、受け取った X-Forwarded-* ヘッダーを解釈させる設定が必要です。

# application.properties
# Tomcat(RemoteIpValve)にX-Forwarded-*ヘッダーを解釈させる
server.forward-headers-strategy=native

Spring Boot公式ドキュメントによると、server.forward-headers-strategy の既定値は対応クラウド上では NATIVE、それ以外では NONE(ヘッダーを処理しない)です。自前のサーバーでNginxを前段に置く場合は明示的に設定します。

native は組み込みTomcatの機能で X-Forwarded-For と X-Forwarded-Proto を処理し、framework を指定するとSpring Frameworkの ForwardedHeaderFilter が処理します。

なお、NginxがTomcatの既定で信頼するプライベートIP帯の外にある場合は、server.tomcat.remoteip.internal-proxies で信頼するプロキシを指定します。全プロキシを信頼する設定は本番では使わないでください。

リクエストがSpring Bootに届くまでのヘッダーの受け渡しを図にすると、次のようになります。

Spring Bootに届くまでのヘッダーの受け渡し
1
ブラウザ → NGINX(443番)HTTPSでリクエスト
2
NGINXSSL終端(復号)
3
NGINX → SPRING BOOT(8080番)HTTPで転送X-Forwarded-Proto と X-Forwarded-For を付与
4
SPRING BOOT元のスキームとIPを復元forward-headers-strategy=native で処理
5
SPRING BOOT → NGINXhttps のURLでリダイレクト先を生成
6
NGINX → ブラウザ暗号化してレスポンスを返却

JavaとNginx連携で起きがちなトラブルと解決策

設定をしたはずなのに動かない、という事態はよく起こります。エラー画面を見て焦らないよう、代表的なトラブルとその対処法を知っておきましょう。

ログファイルをしっかり確認することが、解決への近道です。

502 Bad Gatewayの原因と解決方法

「502 Bad Gateway」は、Nginx連携で最も頻繁に見かけるエラーです。

これは「Nginxは動いているが、転送先のJavaアプリと通信できない」ことを意味します。

主な原因は、Javaアプリが起動していないか、起動ポートの設定が間違っていることです。

私の経験では、502エラーの約8割はJavaアプリの起動失敗が原因です。

特に多いのが、メモリ不足によるOOM Killerの発動と、ポート競合による起動失敗の2つです。

journalctl -u your-app でアプリのログを確認し、起動自体が成功しているかを最初にチェックしてください。

次に、Nginxの設定ファイルに書いたポート番号と、Javaアプリが使っているポート番号が一致しているかを見直します。

単純な数字のミスが原因であることが多いです。

よくあるのが、メモリ制限2GBのコンテナに-Xmx1.5gを指定したJavaアプリが、負荷が上がったときだけOOM Killerに落とされるケースです。

一見Nginx側の問題に見えますが、dmesg | grep -i killでカーネルログを確認すると、OOM Killerがプロセスを止めた記録が残っています。

JVMのヒープ以外にメタスペースやスレッドスタックの分もコンテナのメモリ上限に収める必要があり、目安としてコンテナ上限の7割程度に-Xmxを抑えるとこの種のOOMはほぼ再発しませんでした。

proxy_passの末尾スラッシュ問題

Nginxの設定で末尾にスラッシュ / を付けるかどうかで、転送されるパスが変わる挙動があります。

たとえば location /api { proxy_pass http://localhost:8080; } の場合、/api/users へのリクエストは http://localhost:8080/api/users に転送されます。

一方、proxy_pass http://localhost:8080/;(末尾にスラッシュあり)に変えると、/api/users は http://localhost:8080//users になり、パスが崩れます。

これが原因で「404 Not Found」になることがあります。

基本的には、proxy_pass のURLにパスを含めない形(ポート番号で終わる形)で設定し、パスの変換はNginxの location ブロックで制御するのが安全です。

この手のパス崩れは、ブラウザの開発者ツールだけだと見落としやすいです。

私はいつもcurl -v http://localhost/api/usersを叩き、レスポンスヘッダーとステータスコードを直接確認するようにしています。

Nginxが実際にどのURLへ転送しているかは、nginx -Vに--with-debugが含まれるデバッグ対応のビルドであれば、error_logにdebugレベルを一時的に設定するとupstream行に出力されるため、疑わしい時はそこまで見に行くと切り分けが早くなります。

ロードバランス時のセッション切れ対策

複数のJavaアプリでロードバランシングを行う際、セッション情報が引き継がれない問題が発生します。

ユーザーがログインした情報をサーバーAが持っている状態で、次のリクエストがサーバーBに飛ぶと、サーバーBはログイン情報を知らないため「ログインしてください」と返してしまいます。

これを防ぐには、同じユーザーからのアクセスを常に同じサーバーに飛ばす「Sticky Session(ip_hash)」の設定をNginxに入れるか、Redisなどの外部ストアでセッション情報を共有する仕組みを導入します。

2026年現在の実務では、ステートレスなJWT認証を採用し、セッション情報をサーバー側に持たない設計が主流です。

この方式であれば、Sticky Sessionの設定自体が不要になり、ロードバランシングの柔軟性が格段に高まります。

Java×Nginx連携を最適化するチューニング

基本設定で動くようになったら、次はパフォーマンスを最大限に引き出すチューニングを行いましょう。

ワーカー数やKeep-Aliveの設定を見直すだけでも、環境によっては処理能力が改善します。

Nginxのワーカー数・Keepalive調整

Nginxの性能を決める重要なパラメータに worker_processes と worker_connections があります。

worker_processes は通常 auto に設定し、CPUのコア数に合わせます。

worker_connections は一つのワーカーが扱える同時接続数で、アクセス数が多いサイトではこの値を増やします。

また、keepalive_timeout を調整してTCP接続を維持する時間を制御すれば、接続確立のオーバーヘッドを減らし、レスポンス速度を向上できます。

目安として、同時接続数が1,000程度のサービスなら worker_connections 1024; から始めるとよいです。

バックエンドへのKeep-Aliveは、upstreamブロック内の keepalive 32; を起点に(1.30より前のバージョンでは proxy_http_version 1.1; と proxy_set_header Connection ""; も必要です)、負荷テストをしながら調整するのが実用的です。

バックエンドへのkeepaliveを設定すると、リクエストのたびにTCP接続を張り直さなくて済むため、平均レスポンスタイムが短くなります。

効果の大きさは環境によって変わるため、abなどの負荷テストツールで設定の前後を比べて確認してください。

Java側(JVM・スレッド数)の調整

Nginxだけでなく、受け手であるJava側のチューニングも必要です。

特にJVM(Java仮想マシン)のヒープメモリ設定は重要です。

-Xms(初期メモリ)と -Xmx(最大メモリ)を適切に設定し、頻繁なガベージコレクション(GC)が発生しないようにします。

Spring Bootを使用している場合は、内蔵Tomcatのスレッド数も調整ポイントです。同時リクエスト数に合わせて最大スレッド数を設定しましょう。

あわせて読む

NginxログとJavaログをつなぐログ設計

障害発生時に迅速な調査を行うためには、ログの連携が鍵となります。

Nginxのアクセスログには「リクエストID」を付与し、それをヘッダーとしてJava側に渡す設定を行います。

Java側でもそのリクエストIDをログに出力するようにすれば、一つのリクエストがNginxに入ってからJavaで処理されるまでを一気通貫で追跡できるようになります。

これができていると、トラブルシューティングの時間が大幅に短縮されます。

JavaとNginx連携を採用すべきケース

最後に、どのような場面でこの連携構成を採用すべきかをまとめます。

結論としては、商用レベルのWebサービスであれば、多くのケースで採用を検討する価値があります。

アクセス急増に備えるスケール戦略

アクセス数が予測できない、あるいは急増する可能性があるサイトでは必須の構成です。

Nginxを挟んでおくことで、バックエンドのJavaサーバーを容易に追加・削除できるからです。

キャンペーンなどでアクセスが集中した際も、Nginxが交通整理を行い、システム全体のダウンを防いでくれます。

NginxをAPIゲートウェイとして使う

マイクロサービスアーキテクチャのように、裏側に多数のサービスが存在する場合、Nginxが入り口(ゲートウェイ)として機能します。

認証処理やルーティング、レートリミット(アクセス制限)などをNginxで一元管理することで、各マイクロサービスの実装をシンプルに保てます。

大規模システムになればなるほど、この恩恵は大きくなります。

クラウド環境(AWS/GCP)での構成例

AWSやGCPなどのクラウド環境でも、この構成は健在です。

クラウドロードバランサー(ELBなど)の下にNginxを配置し、その下でJavaを動かす構成がよく取られます。

または、DockerコンテナとしてNginxとJavaをセットでデプロイする構成も一般的です。

どのようなインフラ環境であっても、NginxとJavaの連携は、堅牢で拡張性の高いシステムを作るための定番の組み合わせです。

まとめ:JavaとNginx連携で押さえるポイント

Nginxはリクエストを受け付ける「Webサーバー/リバースプロキシ」、Javaはビジネスロジックを処理する「アプリケーションサーバー」という役割分担が、両者を組み合わせる出発点です。

最短ではNginxの設定ファイルにlocation / { proxy_pass http://127.0.0.1:8080; }の1行を追記するだけで連携が始まります。

ただし本番投入の前には、proxy_read_timeoutによるタイムアウト設定、client_max_body_sizeによるアップロード容量制限、SSLをどちらで終端するかの3点を必ず確認してください。

この3点を押さえておけば、502エラーなど運用開始後によくあるトラブルの多くを未然に防げます。

JavaとNginx連携でよくある質問

Q1. NginxなしでSpring Bootだけで本番運用できる?

A1. 技術的には可能です。Spring Bootには内蔵Tomcatがあり、単体で80番ポートや443番ポートで待ち受けることもできます。

ただし、本番環境ではNginxを前段に置くことを推奨します。

理由は次の3点です。

  • SSL証明書の管理が一元化できること
  • 静的ファイル配信をJavaから分離できること
  • 将来的なスケールアウト(サーバー追加)が容易になること

個人開発や社内ツール程度ならSpring Boot単体でも問題ありませんが、外部公開サービスではNginxとの連携を前提に考えるのがおすすめです。

Q2. ApacheとNginxどちらをJavaと組み合わせるべき?

A2. 2026年8月時点でも主流はNginxです。Apacheも長い歴史と実績がありますが、NginxはノンブロッキングI/Oによる高い同時接続処理性能と、設定ファイルのシンプルさで優位に立っています。

特にリバースプロキシとしての用途では、Nginxの方がメモリ消費が少なく、大量の同時接続を効率よく処理できます。

Apacheの .htaccess によるディレクトリ単位の設定が必要な場合を除き、新規構築ではNginxを選択するのが一般的です。

あわせて読む

Q3. NginxとTomcatの違いは何ですか?

A3. Nginxはリクエストを受け付けて振り分けるWebサーバー、Tomcatはそのリクエストを受けてJavaのサーブレット/JSPを実行するアプリケーションサーバーです。役割が異なるため競合ではなく、Nginxを前段、Tomcatを後段に置いて連携させるのが一般的です。

Q4. proxy_passで502 Bad Gatewayが出たときの対処法は?

A4. まずJavaアプリが起動しているかを確認してください。502エラーの約8割はJavaアプリの起動失敗が原因で、メモリ不足によるOOM Killerの発動やポート競合が典型的な原因です。

Q5. NginxとJavaを連携させるメリットは何ですか?

A5. セキュリティ・パフォーマンス・運用性の3点が主なメリットです。

  • セキュリティ:Javaアプリを直接インターネットに晒さずに済みます
  • パフォーマンス:静的ファイル配信をNginxに任せて負荷を下げられます
  • 運用性:SSL証明書の管理も一元化できます

Q6. SSL証明書はNginxとJavaどちらで管理すべきですか?

A6. 基本的にはNginx側で終端して管理する構成を推奨します。証明書の更新作業がNginx側だけで完結し、Javaアプリは暗号化処理の負荷から解放されます。決済系などPCI DSS準拠が求められる場合は、Nginx〜Java間の通信も暗号化するかを要件に照らして検討してください。

Q7. Nginxのclient_max_body_sizeのデフォルト値はいくつですか?

A7. デフォルトは1MBです。画像アップロード機能などで大きなファイルを扱う場合は、client_max_body_size 10M; のように明示的に上限を引き上げる設定が必要です。

Q8. Spring Boot以外のJavaフレームワークでも設定は同じですか?

A8. 基本的には同じです。Nginxが転送先として意識するのはポート番号だけなので、Spring Boot・素のServlet/JSP・その他のJavaフレームワークのどれであっても、proxy_passの書き方は変わりません。ポート固定の設定方法(application.propertiesかserver.xmlか)だけがフレームワークによって異なります。

REVISIONS / 改訂履歴
REV.DATE内容
72026-10-16図解を描き直し(図面のデザインにそろえた)
62026-10-14一人称と言い回しの表記をそろえた。雰囲気だけの挿絵を外した
52026-10-04記載内容の事実確認と修正
42026-08-292026年8月時点の情報で全体を見直し
… ほか2回の改訂
12025-11-26初版
NEXT READ本棚から1本

AIで開発を組み直すなら、まずこの5冊から

入門・実践・設計まで、Claude Codeの本をレベル別に5冊選んで比べました。

→ おすすめ5冊を見る

  • この記事を書いた人
  • 最新記事

トム

SESで約8年、環境を変えられないもどかしさの中にいました。32歳で自社開発企業に転職し、今はClaude Codeと自動化で、仕事も時間も組み直している途中です。
・Javaバックエンドエンジニア(Java歴12年以上)
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎
詳細なプロフィール

𝕏

Java入門