はじめに:リバースプロキシはなぜ必要か

現代のWebサービスが単一サーバーで運営されるケースはほとんどありません。フロントエンドはReactやVueでビルドされ静的ファイルとして配信され、バックエンドはNode.js、Python、Java、Goなどで作成されたアプリケーションサーバーが担当します。そこにデータベース、キャッシュ、メッセージキューまで組み合わさると、サービスは数十のコンポーネントで構成される複雑なシステムとなります。

このときNginxリバースプロキシは、これらすべてのコンポーネントの前面でトラフィックを指揮する役割を果たします。ユーザーはhttps://example.comという1つのエントリポイントで接続しますが、Nginxはリクエストのパスやホスト名に応じて適切なバックエンドへトラフィックをルーティングします。これによりSSL終端、ロードバランシング、キャッシング、セキュリティ、圧縮、モニタリングなどを中央で一貫して管理することができます。

本ガイドでは、Nginxリバースプロキシの概念から実践構成、最適化、トラブルシューティングまで、実務に必要なすべての内容を取り扱います。Node.js、Python、Javaなど多様なバックエンド連携の例、WebSocketやgRPCなど特殊なプロトコル処理、そして運用中によく遭遇する問題の解決方法まで、実際の設定ファイルとともに詳しく解説します。

1. リバースプロキシ vs フォワードプロキシ

1.1 概念の違い

フォワードプロキシ(Forward Proxy)はクライアント側に位置し、クライアントに代わって外部サーバーへリクエストを転送します。会社のファイアウォール、VPN、学校のインターネットフィルタリングなどが代表例です。クライアントはプロキシを認識しますが、サーバー側はプロキシの存在を知りません。

リバースプロキシ(Reverse Proxy)はサーバー側に位置し、サーバーに代わってクライアントのリクエストを受け付けます。クライアントはプロキシを実際のサーバーと認識し、プロキシの背後に隠された実サーバー(バックエンド)の存在を知りません。

区分 フォワードプロキシ リバースプロキシ
位置 クライアント側 サーバー側
代理対象 クライアントを代理 サーバーを代理
主な用途 アクセス制御、キャッシング、匿名化 ロードバランシング、SSL終端、キャッシング
代表例 Squid、Privoxy Nginx、HAProxy、Traefik

1.2 リバースプロキシの主な利点

  • 単一エントリポイント:複数のバックエンドサーバーを1つのドメイン/IPに統合
  • SSL終端:HTTPS処理をプロキシで中央管理、バックエンドはHTTPを使用可能
  • ロードバランシング:複数のバックエンドへトラフィックを分散
  • キャッシング:バックエンドの負荷軽減、応答速度向上
  • 圧縮:Gzip/Brotli圧縮をプロキシで処理
  • セキュリティ:バックエンドサーバーの直接露出防止、WAF適用可能
  • レート制限:中央でリクエスト制限を管理
  • ログの中央化:すべてのリクエストを1箇所でロギング

2. proxy_passの基本的な使い方

2.1 最も基本的なプロキシ設定

server {
    listen 80;
    server_name example.com;

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

これだけでも基本的なリバースプロキシは動作します。ただし実務では、少なくとも次のヘッダーを必ず設定する必要があります:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;

        # 元のホスト情報を伝達
        proxy_set_header Host $host;

        # クライアントの実IP (バックエンドでロギングする際に使用)
        proxy_set_header X-Real-IP $remote_addr;

        # プロキシチェーン情報
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # 元のプロトコル (http/https)
        proxy_set_header X-Forwarded-Proto $scheme;

        # 元のポート
        proxy_set_header X-Forwarded-Port $server_port;

        # 元のホスト
        proxy_set_header X-Forwarded-Host $host;
    }
}
重要: proxy_set_header Host $host;を設定しないと、Nginxはデフォルトでproxy_passに指定されたホスト(ここでは127.0.0.1:3000)をHostヘッダーとして転送します。これはバーチャルホストルーティングを使用するバックエンドで問題を引き起こします。

2.2 proxy_pass URLのスラッシュの違い

proxy_passのURLの末尾にスラッシュ(/)があるかないかによって動作が完全に変わります。これはNginx初心者が最も混同しやすい部分です:

# ケース1: proxy_passにスラッシュなし
# /api/users → http://backend/api/users (パスをそのまま転送)
location /api/ {
    proxy_pass http://backend;
}

# ケース2: proxy_passにスラッシュあり
# /api/users → http://backend/users (locationパスを削除)
location /api/ {
    proxy_pass http://backend/;
}

# ケース3: パス置換
# /api/users → http://backend/v1/users (/api/が/v1/に置換)
location /api/ {
    proxy_pass http://backend/v1/;
}
覚え方:
スラッシュなし = パスをそのまま転送
スラッシュあり = locationパスを切り捨て、残り部分のみ転送
この違いを明確に理解していないと、404エラーや誤ったルーティングが発生します。

3. バックエンド別プロキシ設定

3.1 Node.js (Express、Next.js)

# Node.js アプリ (デフォルトポート3000)
upstream nodejs_backend {
    server 127.0.0.1:3000;
    keepalive 32;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://nodejs_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";    # keepaliveを使用

        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;

        # Node.jsのreq.ipを利用するためtrust proxyの設定が必要
        # app.set('trust proxy', true);

        proxy_read_timeout 300;
        proxy_connect_timeout 75;
    }
}

Next.js特化設定

server {
    listen 80;
    server_name next.example.com;

    # Next.js 静的ファイル (ビルド時に生成)
    location /_next/static/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_cache_valid 200 60m;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }

    # 画像最適化API
    location /_next/image {
        proxy_pass http://127.0.0.1:3000;
        proxy_cache_valid 200 60m;
    }

    # その他のリクエスト
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

3.2 Python (Django、Flask、FastAPI)

# Gunicornで実行中のDjango/Flask/FastAPI
upstream python_backend {
    server 127.0.0.1:8000 fail_timeout=30s;
}

server {
    listen 80;
    server_name py.example.com;

    # 静的ファイルはNginxが直接配信 (Django collectstatic等)
    location /static/ {
        alias /var/www/example/static/;
        expires 30d;
        access_log off;
    }

    location /media/ {
        alias /var/www/example/media/;
        expires 7d;
    }

    location / {
        proxy_pass http://python_backend;
        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;

        # Pythonアプリは応答時間が長くなる場合がある
        proxy_read_timeout 120;
        proxy_connect_timeout 75;

        # Django: SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
        # Flask: app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
    }
}

Unixソケット使用 (パフォーマンス向上)

# GunicornをUnixソケットで実行した場合
# gunicorn app:app --bind unix:/tmp/gunicorn.sock
upstream python_backend {
    server unix:/tmp/gunicorn.sock;
}

server {
    listen 80;
    server_name py.example.com;

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

3.3 Java (Spring Boot、Tomcat)

# Spring Boot アプリ (デフォルトポート8080)
upstream spring_backend {
    server 127.0.0.1:8080;
    keepalive 32;
}

server {
    listen 80;
    server_name java.example.com;

    client_max_body_size 50M;    # Javaアプリは大きなペイロードが一般的

    location / {
        proxy_pass http://spring_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        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 application.properties:
        # server.forward-headers-strategy=native
        # server.tomcat.remote-ip-header=X-Forwarded-For
        # server.tomcat.protocol-header=X-Forwarded-Proto

        proxy_read_timeout 300;
        proxy_buffer_size 16k;
        proxy_buffers 8 16k;
    }
}

3.4 PHP-FPM (別セクション)

PHPはproxy_passではなくfastcgi_passを使用します。厳密に言うとリバースプロキシではなく、FastCGIプロキシです:

server {
    listen 80;
    server_name php.example.com;
    root /var/www/php-app/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

4. WebSocketプロキシ

WebSocketはHTTP 1.1のUpgradeメカニズムを使用します。通常のHTTPプロキシ設定ではWebSocketは動作せず、次のような特殊な設定が必要です:

# WebSocket プロキシ 基本設定
server {
    listen 80;
    server_name ws.example.com;

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

        # WebSocket 必須設定
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # WebSocketは長時間接続を維持
        proxy_read_timeout 86400s;    # 24時間
        proxy_send_timeout 86400s;

        # バッファリング無効化 (リアルタイム双方向通信)
        proxy_buffering off;
    }
}

4.1 HTTPとWebSocketの同時処理

# Socket.IOのようにHTTPとWebSocketを同じポートで処理する場合
# $connection_upgrade マップの定義 (httpブロック)
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name chat.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 86400s;
    }

    # WebSocketのみを別パスに分離する場合
    location /socket.io/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}

5. マイクロサービスのルーティング

複数のバックエンドサービスを単一ドメインに統合することは、リバースプロキシの最も強力な活用例です。

5.1 パスベースのルーティング

# upstream 定義
upstream frontend { server 127.0.0.1:3000; }
upstream api_service { server 127.0.0.1:4000; }
upstream auth_service { server 127.0.0.1:5000; }
upstream upload_service { server 127.0.0.1:6000; }

server {
    listen 80;
    server_name example.com;

    # フロントエンド (SPA)
    location / {
        proxy_pass http://frontend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # APIサービス
    location /api/ {
        proxy_pass http://api_service/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 認証サービス
    location /auth/ {
        proxy_pass http://auth_service/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # 認証サービスにはレート制限を厳しく
        limit_req zone=auth_limit burst=5 nodelay;
    }

    # アップロードサービス (大容量ファイル処理)
    location /upload/ {
        proxy_pass http://upload_service/;
        proxy_set_header Host $host;

        # アップロードは大きなbodyを許可
        client_max_body_size 500M;

        # タイムアウトを長めに
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;

        # バッファリング無効化 (ストリーミングアップロード)
        proxy_request_buffering off;
    }
}

5.2 ホスト名ベースのルーティング (サブドメイン)

# 各サブドメインを異なるサービスにルーティング
server {
    listen 80;
    server_name app.example.com;
    location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; }
}

server {
    listen 80;
    server_name api.example.com;
    location / { proxy_pass http://127.0.0.1:4000; proxy_set_header Host $host; }
}

server {
    listen 80;
    server_name admin.example.com;
    location / {
        allow 10.0.0.0/8;
        deny all;
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
    }
}

6. ロードバランシング統合

複数のバックエンドインスタンスを運用する際、リバースプロキシで自然にロードバランシングを実施できます。

# 複数のバックエンドインスタンス
upstream api_cluster {
    # ロードバランシング方式 (未指定時はround-robin)
    least_conn;

    server 10.0.0.10:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.0.11:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.0.12:8080 weight=1 max_fails=3 fail_timeout=30s;

    server 10.0.0.13:8080 backup;   # バックアップサーバー
    server 10.0.0.14:8080 down;     # メンテナンス中

    keepalive 32;    # 各ワーカーごとに維持する遊休接続数
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://api_cluster;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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_next_upstream error timeout http_500 http_502 http_503 http_504;
        proxy_next_upstream_tries 3;
        proxy_next_upstream_timeout 10s;
    }
}

7. プロキシキャッシング

リバースプロキシのキャッシング機能を活用すれば、バックエンドの負荷を大きく減らすことができます。

# http ブロックでキャッシュ領域を定義
http {
    proxy_cache_path /var/cache/nginx/api
                     levels=1:2
                     keys_zone=api_cache:10m
                     max_size=1g
                     inactive=60m
                     use_temp_path=off;

    server {
        listen 80;
        server_name api.example.com;

        location / {
            proxy_pass http://api_backend;
            proxy_set_header Host $host;

            # キャッシュ有効化
            proxy_cache api_cache;
            proxy_cache_key "$scheme$request_method$host$request_uri";

            # キャッシュ有効期間
            proxy_cache_valid 200 302 10m;   # 成功レスポンスは10分
            proxy_cache_valid 404 1m;        # 404は1分
            proxy_cache_valid any 30s;       # その他は30秒

            # キャッシュロック (同時リクエストから1度だけバックエンド呼び出し)
            proxy_cache_lock on;
            proxy_cache_lock_timeout 5s;

            # キャッシュ使用条件
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            proxy_cache_background_update on;

            # キャッシュ状態ヘッダー (デバッグ用)
            add_header X-Cache-Status $upstream_cache_status;

            # キャッシュバイパス条件
            proxy_cache_bypass $cookie_nocache $arg_nocache;
            proxy_no_cache $cookie_nocache $arg_nocache;
        }
    }
}
キャッシュ状態の確認: X-Cache-Statusヘッダーの値でキャッシュ動作を確認できます。
HIT - キャッシュからの応答
MISS - キャッシュになくバックエンドを呼び出し
EXPIRED - キャッシュ期限切れ
BYPASS - キャッシュバイパス条件
UPDATING - キャッシュ更新中 (stale応答)

8. バッファリングとタイムアウトのチューニング

8.1 バッファリングの理解

Nginxは基本的にバックエンドの応答をバッファリングします。バックエンドの応答をメモリ(またはディスク)に集めた後にクライアントへ送信する方式です。これは遅いクライアントのためにバックエンド接続が長時間占有されるのを防ぐ重要な役割を果たします。

location / {
    proxy_pass http://backend;

    # レスポンスバッファリング設定
    proxy_buffering on;              # デフォルト値
    proxy_buffer_size 4k;            # レスポンスヘッダー用バッファ
    proxy_buffers 8 4k;              # レスポンスボディ用バッファ (個数 x サイズ)
    proxy_busy_buffers_size 8k;      # クライアントへ送信中のバッファ
    proxy_max_temp_file_size 1024m;  # 一時ファイルの最大サイズ
    proxy_temp_file_write_size 8k;

    # リクエストバッファリング
    proxy_request_buffering on;      # デフォルト値
    client_body_buffer_size 16k;
    client_max_body_size 10m;
}

8.2 ストリーミング応答 (バッファリング無効化)

# Server-Sent Events (SSE)、ストリーミングAPI、大容量ファイルダウンロード
location /stream/ {
    proxy_pass http://backend;

    # バッファリング無効化
    proxy_buffering off;
    proxy_request_buffering off;

    # チャンク転送サポート
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    # 即時転送
    proxy_cache off;

    # 長いタイムアウト
    proxy_read_timeout 24h;
}

8.3 タイムアウト設定

location / {
    proxy_pass http://backend;

    # バックエンド接続タイムアウト (TCPハンドシェイク)
    proxy_connect_timeout 60s;

    # バックエンドへのリクエスト送信タイムアウト
    proxy_send_timeout 60s;

    # バックエンド応答待機タイムアウト
    proxy_read_timeout 60s;
}

9. セキュリティヘッダーとクライアント保護

server {
    listen 443 ssl http2;
    server_name example.com;

    # セキュリティヘッダー (すべてのlocationに適用)
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    location / {
        proxy_pass http://backend;
        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;

        # バックエンドから機密ヘッダーが返却されないよう隠蔽
        proxy_hide_header X-Powered-By;
        proxy_hide_header X-AspNet-Version;
        proxy_hide_header Server;
    }
}

9.1 レート制限と接続制限

# http ブロックで zone を定義
http {
    # IPごとの秒間リクエスト数制限
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;

    # IPごとの同時接続数制限
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        location / {
            limit_req zone=general burst=20 nodelay;
            limit_conn conn_limit 10;
            proxy_pass http://backend;
        }

        location /login {
            limit_req zone=login burst=3 nodelay;
            proxy_pass http://auth_backend;
        }

        location /api/ {
            limit_req zone=api burst=50 nodelay;
            proxy_pass http://api_backend;
        }
    }
}

10. 実践トラブルシューティング

10.1 504 Gateway Timeout

原因:バックエンドの応答がproxy_read_timeout(デフォルト60秒)を超過
解決

location / {
    proxy_pass http://backend;
    proxy_connect_timeout 75s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;   # 必要に応じて増加
}

10.2 502 Bad Gateway

原因:バックエンドサーバーがダウンまたはアクセス不可
解決

# バックエンドプロセスの確認
ps aux | grep node    # または python, java 等

# ポート確認
ss -tlnp | grep 3000

# Nginxエラーログの確認
tail -f /var/log/nginx/error.log | grep upstream

# バックエンドサーバーへの直接呼び出しテスト
curl -v http://127.0.0.1:3000/

10.3 413 Request Entity Too Large

原因:アップロードファイルサイズがclient_max_body_size(デフォルト1MB)を超過
解決

# グローバル設定 (httpブロック)
client_max_body_size 100M;

# または特定locationだけに
location /upload/ {
    client_max_body_size 500M;
    proxy_pass http://upload_backend;
}

10.4 バックエンドアプリがHTTPにリダイレクト

症状:HTTPSで接続したのにバックエンドリダイレクト後HTTPに落ちる
原因:バックエンドが元のスキームを知らない
解決

location / {
    proxy_pass http://backend;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;

    # またはNginxレベルでリダイレクトを書き換え
    proxy_redirect http:// https://;
}
フレームワーク別設定:
Express: app.set('trust proxy', true)
Django: SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
Flask: ProxyFix(app.wsgi_app, x_proto=1)
Spring Boot: server.forward-headers-strategy=native

10.5 CORSプリフライトの問題

location /api/ {
    # CORS プリフライトリクエストの処理
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '$http_origin' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept' always;
        add_header 'Access-Control-Max-Age' 1728000 always;
        add_header 'Content-Type' 'text/plain; charset=utf-8' always;
        add_header 'Content-Length' 0 always;
        return 204;
    }

    # 実際のリクエスト
    add_header 'Access-Control-Allow-Origin' '$http_origin' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;

    proxy_pass http://api_backend;
    proxy_set_header Host $host;
}

11. リバースプロキシ運用チェックリスト

  • プロキシヘッダー転送:Host、X-Real-IP、X-Forwarded-For、X-Forwarded-Protoの設定
  • バックエンドフレームワーク設定:trust proxy関連設定で元のIP/プロトコルを認識
  • タイムアウトの適切な設定:サービス特性に合わせた読み取り/接続/送信タイムアウト
  • アップロードサイズ制限client_max_body_sizeの適切な値
  • WebSocketサポート:必要に応じてUpgradeヘッダー設定
  • ロードバランシング障害対応:max_fails、fail_timeout、backupサーバー
  • セキュリティヘッダー:HSTS、X-Frame-Optionsなどの適用
  • レート制限:機密パス(ログイン、API)に制限を適用
  • ログ分離:プロキシログとエラーログをサービス別に分離
  • モニタリング:upstream_response_timeのログ収集
  • バックエンドヘルスチェック:定期的なヘルスチェックスクリプト
  • 設定のバージョン管理:Gitで設定ファイルを管理

結論:リバースプロキシは現代Webインフラの基本

Nginxリバースプロキシは単なる「リクエスト転送」機能を超えて、現代のWebインフラの中核コンポーネントです。SSL終端、ロードバランシング、キャッシング、セキュリティ、モニタリングなど運用に必要なほぼすべての機能を1箇所に集中させることができ、バックエンドアプリケーションはビジネスロジックだけに集中できるようになります。

本ガイドで取り扱った重要ポイント:

  • proxy_set_headerは必須 - Host、X-Real-IP、X-Forwarded-*ヘッダーを必ず設定しましょう。
  • proxy_passのスラッシュ - パスの動作が完全に変わるので正確に理解する必要があります。
  • バックエンド別の特性考慮 - Node.jsはkeepalive、PythonはUnixソケット、Javaは大きなバッファなど、それぞれの特性に合った設定が必要です。
  • WebSocketはUpgradeヘッダー - 通常のHTTPプロキシ設定では動作しません。
  • タイムアウトは慎重に - 短すぎると正常なリクエストも失敗、長すぎるとリソースの無駄。
  • キャッシングでバックエンド負荷を軽減 - GETリクエストの大部分はキャッシング対象になり得ます。
  • セキュリティも考慮 - プロキシはセキュリティ境界なので、レート制限とセキュリティヘッダーを必ず設定しましょう。

本ガイドの設定例を自身のサービス環境に合わせて調整して適用してみてください。リバースプロキシの設定は実戦経験が積まれるほどより洗練されていき、これを通じて安定的で拡張可能なWebインフラを構築することができます。