Nginx は、高性能の Web Server および Reverse Proxy (リバース プロキシ サーバー) です。
主な用途:
- 静的リソース (HTML、JS、CSS、写真) を提供します。
- リバース プロキシ Django、FastAPI、およびその他のバックエンド。
- HTTPS / TLS は終了しました。
- HTTP 圧縮とキャッシュ。
- 負荷分散と電流制限。
- WebSocket、SSE、およびその他の長時間持続する接続またはストリーミング応答プロキシ。
React + Django + Docker プロジェクトの場合:
Browser
↓
Cloudflare(オプション)
↓
Nginx
├── / → React SPA
├── /assets/ → JS / CSS
├── /api/ → Django DRF
├── /admin/ → Django Admin
└── /static/ → Django Static Files
1. nginx.confの構成構造
Nginx は、別の構成コンテキスト (Context) を使用して構成を編成します。
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name example.com;
location / {
# ...
}
location /api/ {
# ...
}
}
}
主なレベル:
nginx.conf
├── Main Context
├── events
└── http
├── upstream
├── server
│ ├── location /
│ └── location /api/
└── server
| Context | 機能 |
|---|---|
| main | グローバル設定 (worker_processes など) |
| events | 接続イベントの処理 |
| http | HTTP サービスのパブリック構成 |
| upstream | バックエンドサーバーグループの定義 |
| server | 仮想ホスト、指定されたポートとドメイン名を処理します |
| location | URI によるリクエストを照合して処理します |
worker_processes および worker_connections
worker_processes auto;
events {
worker_connections 1024;
}
worker_processes: Nginx Worker プロセスの数。autoは通常、利用可能な CPU リソースに基づいて決定されます。worker_connections: リクエストの最大数ではなく、Worker ごとに許可される接続の最大数。
理論上の接続容量は、この 2 つの積によっておおよそ制限されます。ただし、リバース プロキシ中は、クライアント リクエストがクライアント接続とアップストリーム接続の両方を占有する可能性があるため、製品を直接最大同時ユーザー数と見なすことはできません。
Docker の構成ファイル
公式 Nginx 画像は通常、以下を使用します。
/etc/nginx/nginx.conf
/etc/nginx/conf.d/default.conf
一般的に言えば:
nginx.conf:eventsやhttpなどの最上位構造が含まれます。conf.d/default.conf: 通常、serverBlock のみが定義され、includeを介してメイン構成によって導入されます。
したがって、conf.d/default.conf にマウントされる設定ファイルには、通常、http {} および events {} を記述する必要はありません。
2.Server BlockとHTTPS
HTTP リダイレクト HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
たとえば:
http://example.com/blog?id=1
↓ 301
https://example.com/blog?id=1
listen 80: HTTP のポート 80 を監視します。server_name: 要求されたドメイン名と一致します。return 301: 永続的なリダイレクト。$host: Nginx によって解析された、要求されたホスト名。$request_uri: Query String を含む元のリクエスト URI。
HTTPS Server
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
client_max_body_size 10M;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
}
Nginx は、TLS ハンドシェイク、証明書、および暗号化された HTTP 接続を担当します。
Cloudflare を使用する場合は、以下を使用できます。
Browser
↓ HTTPS
Cloudflare
↓ HTTPS
Nginx
↓ HTTP(内部ネットワーク)
Django
通常、Cloudflare Full (strict) を使用し、発信元サイトに有効な証明書を構成して、Cloudflare から Nginx への接続も認証されるようにする必要があります。
3. Location: URI のマッチング
location は、リクエスト URI に基づいて処理方法を選択するために使用されます。
location / {
# ...
}
location /api/ {
# ...
}
一般的なマッチング方法
| 文法 | 意味 |
|---|---|
location = /api | 完全一致 |
location /api/ | プレフィックスマッチング |
location ^~ /assets/ | 接頭辞の一致と定期的な一致チェックのスキップ |
location ~ \.css$ | 大文字と小文字を区別する正規一致 |
location ~* \.(png|jpg)$ | 大文字と小文字を区別しない正規の一致 |
一致の優先順位
基本的なルール:
- 完全一致
=が優先されます。 - 最長のプレフィックス一致を検索します。
- 最長のプレフィックスが
^~を使用している場合は、それを直接選択します。 - それ以外の場合、通常のルール Location が構成順序でチェックされ、最初に一致した通常のルールが有効になります。
- 正規の一致がない場合は、以前に見つかった最長のプレフィックスが使用されます。
注: URI の一致には Query String は含まれません。
4. Reverse Proxy: リバースプロキシ
Django が Docker でリッスンしていると仮定します。
backend:8000
Nginx:
location /api/ {
proxy_pass http://backend:8000;
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;
}
リクエスト:
GET https://example.com/api/v1/users/me/
↓
Nginx
↓
GET http://backend:8000/api/v1/users/me/
ここで、backend は Docker Compose のサービス名です。
proxy_pass の末尾のスラッシュ
ここで物事がうまくいかない可能性があります。
location /api/ {
proxy_pass http://backend:8000;
}
パス接頭辞を保持します:
/api/v1/users/ → /api/v1/users/
ただし:
location /api/ {
proxy_pass http://backend:8000/;
}
一致する /api/ プレフィックスを / に置き換えます。
/api/v1/users/ → /v1/users/
その理由は、2 番目の proxy_pass には URI / が含まれており、Nginx が対応するパスの置換を実行するためです。
Django にすでに /api/v1/ プレフィックスが定義されているプロジェクトの場合は、末尾のスラッシュなしで proxy_pass http://backend:8000; を使用するのが一般的です。
5. proxy_set_header: パス要求情報
| Header | 機能 |
|---|---|
| Host | 元のリクエストされたドメイン名 |
| X-Real-IP | バックエンドクライアントに IP を伝えます |
| X-Forwarded-For | プロキシ チェーンに IP を記録します |
| X-Forwarded-Proto | 元のリクエスト プロトコルをバックエンドに伝えます |
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;
共通の変数:
| 変数 | 意味 |
|---|---|
$host | 解決されたリクエストのホスト名 |
$remote_addr | Nginx が現在認識しているクライアント アドレス |
$proxy_add_x_forwarded_for | 現在のクライアント アドレスに元の X-Forwarded-For が追加される |
$scheme | 現在の接続は HTTP または HTTPS を使用しています |
$request_uri | オリジナルの URI、Query String を含む |
$uri | 現在は Query String を除く URI に正規化されています |
$http_upgrade | Upgrade Header リクエスト中 |
Cloudflare と実際のクライアント IP
Cloudflare プロキシを使用する場合:
Browser IP
↓
Cloudflare IP
↓
Nginx
Nginx がデフォルトで認識する $remote_addr は、Cloudflare ノード IP である可能性があります。
ゲスト IP は、Real IP モジュールを通じて復元できます。
# 説明のために、次のように置き換えます。 Cloudflare 完全な公式発表 IP セグメント
set_real_ip_from <trusted_cloudflare_cidr>;
real_ip_header CF-Connecting-IP;
本物の Cloudflare プロキシ アドレスのみを信頼し、偽造の可能性がある信頼できないプロキシからのリクエストをオリジンが受け入れないようにする必要があります。
回復後、$remote_addr は、信頼されたプロキシ情報によって識別されるクライアント アドレスを表します。
Cloudflare IP リストは定期的なメンテナンスが必要です。 Cloudflare公式ドキュメントを参照してください。
6. Static Files および SPA ルーティング
Vite ビルド結果:
dist/
├── index.html
└── assets/
├── index-Ab12.js
└── index-Cd34.css
Nginx:
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
処理の流れ:
GET /profile
↓
チェックする /usr/share/nginx/html/profile
↓
存在しません
↓
戻る index.html
↓
React Router プロセス /profile
root および alias
root スプライスは URI を静的ファイルのルート ディレクトリにリクエストします。
location /assets/ {
root /usr/share/nginx/html;
}
リクエスト:
/assets/app.js
→ /usr/share/nginx/html/assets/app.js
alias は、一致する Location プレフィックスを指定されたファイル システム パスに置き換えます。
location /media/ {
alias /data/media/;
}
リクエスト:
/media/avatar/a.jpg
→ /data/media/avatar/a.jpg
ディレクトリ タイプ Location の場合、alias パスは通常、プレフィックスに対応する末尾の / を保持する必要があります。
7. HTTP キャッシュ
Hash を使用して Vite によって生成された静的ファイルの場合:
location /assets/ {
try_files $uri =404;
expires 1y;
add_header Cache-Control "public, immutable";
}
この方法:
index-A1b2.js
1 年間キャッシュできます。
更新後にビルドすると次のものが生成されます。
index-C3d4.js
ブラウザはそれを新しいリソースとして扱います。
index.html
location = /index.html {
add_header Cache-Control "no-cache";
}
no-cache は、キャッシュを完全に無効にするのではなく、キャッシュを使用する前に検証が必要であることを意味します。
注: SPA の /profile などのパスは、/index.html 内部リダイレクトを介して HTML に戻る場合があるため、最終的な HTML 応答に適切なキャッシュ Header があることの確認も必要です。
SPA のフォールバック HTML を長期間キャッシュしないでください。また、存在しない JS ファイルを HTML にフォールバックさせないでください。
8. gzip / Brotli 圧縮
Nginx は、テキスト HTTP 応答を圧縮して、ネットワーク送信量を削減できます。
gzip
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types
text/plain
text/css
application/javascript
application/json
image/svg+xml;
Brotli
互換性のある Brotli Nginx モジュールのインストールが必要です:
brotli on;
brotli_comp_level 5;
brotli_types
text/plain
text/css
application/javascript
application/json
image/svg+xml;
両方のアルゴリズムを同時に構成できます。
Browser
↓ Accept-Encoding: br, gzip
Nginx
↓ Content-Encoding: br
Compressed Response
通常は Brotli が優先され、gzip がフォールバックとなります。
注: 通常、公式 nginx:alpine イメージでは Brotli コマンドを直接有効にすることはできません。まず、対応するモジュールが存在し、正しくロードされていることを確認する必要があります。
9. リクエストのサイズとプロキシのタイムアウト
client_max_body_size
client_max_body_size 10M;
クライアントリクエストの本文サイズを制限します。
制限を超えると、通常は次のものが返されます。
413 Content Too Large
アバター、写真、その他のアップロードされたコンテンツを制限するのに適しています。
エージェントのタイムアウト
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
| 指示 | 機能 |
|---|---|
| proxy_connect_timeout | アップストリーム接続確立のタイムアウト |
| proxy_send_timeout | アップストリームへの 2 つの連続した書き込み操作の間に許可されるタイムアウト |
| proxy_read_timeout | アップストリームからの 2 つの連続した読み取り操作の間に許可されるタイムアウト |
proxy_read_timeout は、HTTP リクエスト全体の合計実行時間制限ではありません。
バックエンドがデータを送信し続ける場合、合計応答時間が 60 秒を超えても、このタイムアウトがトリガーされないことがあります。
10. Buffering: 応答バッファリング
Nginx は、デフォルトでプロキシ応答バッファリングを有効にします。
proxy_buffering on;
通常、API 応答はデフォルトのままで問題ありません。
仕組み:
Django
↓
Nginx Buffers
↓
Browser
Nginx はアップストリームの応答を読み取り、可能な限りバッファリングします。これにより、遅いクライアントによるバックエンドの占有が軽減されます。
ただし、データをすぐに送信する必要がある SSE などのインターフェイスの場合は、閉じることができます。
proxy_buffering off;
現時点では、応答はよりタイムリーにクライアントに配信されます。
proxy_request_buffering は別の構成で、リクエスト本文を最初に Nginx にバッファリングするかどうかを制御します。レスポンスのバッファリングと混同することはできません。
11. WebSocketエージェント
HTTP/1.1 接続をアップグレードする場合、WebSocket には特別な Header が必要です。
location /ws/ {
proxy_pass http://backend:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
基本的なプロセス:
Browser
↓ HTTP Upgrade
Nginx
↓
ASGI / WebSocket Server
↓
Persistent Connection
通常の HTTP と WebSocket を混在させる構成の場合、map を介して Connection Header を動的に設定することもできます。
注: Django 自体は、完全な WebSocket アプリケーション ルーティングを直接提供するわけではなく、通常は Django Channels またはその他の ASGI WebSocket 処理ソリューションを必要とします。
12. SSE / Streaming
SSE (Server-Sent Events) は、サーバーがイベントをクライアントに継続的に送信するために使用します。コミュニケーションの方向性は主に次のとおりです。
Server → Browser
典型的なシナリオ:
- AI Token ストリーミング出力。
- ミッションの進行状況の更新。
- リアルタイム通知。
- サーバーイベントのプッシュ。
Nginx構成
location /api/v1/stream/ {
proxy_pass http://backend:8000;
proxy_http_version 1.1;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
主要な構成:
proxy_buffering off: Nginx バッファ応答を回避し、イベント出力を遅延します。proxy_cache off: Nginx プロキシ キャッシュを使用しないでください。proxy_read_timeout 300s: アップストリーム読み取り間の待機時間を長くします。
バックエンドは通常、以下を返します。
Content-Type: text/event-stream
Cache-Control: no-cache
応答内容:
data: {"message":"Hello"}
data: {"message":"World"}
各イベントは空行で区切られます。
長期間新しいイベントがない接続の場合、サーバーはアイドル状態による接続のタイムアウトを避けるために定期的にハートビートを送信できます。
あるいは、バックエンドに以下を返すようにすることもできます。
X-Accel-Buffering: no
Nginx バッファリングは特定の応答に対して無効になりますが、proxy_ignore_headers によって無効になっていないことを確認する必要があります。
13. 負荷分散
複数のバックエンド インスタンスが存在する場合:
upstream django_backend {
server backend1:8000;
server backend2:8000;
server backend3:8000;
}
server {
location /api/ {
proxy_pass http://django_backend;
}
}
アーキテクチャ:
┌── Django 1
Browser │
↓ ├── Django 2
Nginx ───────┤
└── Django 3
リクエストの割り当てには、デフォルトの共通ポーリング方式が使用されます。
その他の戦略には次のようなものがあります。
least_conn: アクティブな接続が少ないバックエンドを優先します。ip_hash: クライアント IP に基づいて比較的固定された割り当て。
単一の Docker Compose VPS にデプロイされた小規模プロジェクトの場合、マルチインスタンスの負荷分散は必ずしも必要ではありません。
14. 電流制限 (Rate Limiting)
NginxはIPおよびその他の条件に応じてリクエスト頻度を制限できます。
http コンテキストで定義:
limit_req_zone
$binary_remote_addr
zone=api:10m
rate=10r/s;
Location では次を使用します。
location /api/ {
limit_req zone=api burst=20;
limit_req_status 429;
proxy_pass http://backend:8000;
}
主要なパラメータ:
| パラメータ | 機能 |
|---|---|
$binary_remote_addr | クライアント IP のバイナリ表現 |
zone=api:10m | 電流制限状態の共有メモリ領域 |
rate=10r/s | 平均して 1 秒あたり 10 リクエスト |
burst=20 | ある程度のリクエストのバーストを許容する |
limit_req_status 429 | 電流制限がトリガーされると 429 を返します |
nodelay が設定されていない場合、Burst 内の一部の超過リクエストは、すぐに渡されるのではなく遅延される可能性があります。
Cloudflare を使用する場合は、最初に実際のクライアント IP を正しく復元する必要があります。そうしないと、電流が Cloudflare ノード IP に従って制限され、複数の実際のユーザーが同じ電流制限された ID を共有する可能性があります。
さらに、Nginx 電流制限は、Django 内のユーザーレベルの電流制限とビジネス許可制御を置き換えることはできません。
15. ログとトラブルシューティング
Access Log
HTTP アクセス ステータスを記録します。
access_log /var/log/nginx/access.log;
通常、次のものが含まれます。
- IPをリクエストしてください。
- リクエストメソッドはURIです。
- HTTP ステータス コード。
- 応答サイズ。
- リクエスト時間 (ログ形式によって異なります)。
Error Log
error_log /var/log/nginx/error.log warn;
プロキシの失敗、接続エラー、部分的なアップストリーム エラー、および Nginx 自体のエラーをログに記録します。
Dockerログ
公式 Nginx Docker ミラーには、通常、stdout/stderr に接続されたアクセス ログとエラー ログがあります。
次のものが使用できます。
docker compose logs -f nginx
コンテナーのログを表示します。
構成テスト
nginx -t
構成構文と関連ファイルを確認してください。
実際にロードされた完全な構成を確認してください。
nginx -T
設定をリロードします。
nginx -s reload
Docker環境:
docker compose exec nginx nginx -t
docker compose exec nginx nginx -s reload
16. Nginx および Django の責任
| 機能 | Nginx | Django |
|---|---|---|
| HTTPS / TLS | 主に担当するのは、 | 通常、直接取引されることはありません |
| 静的ファイル | 提供責任者 | 構築または収集を担当する |
| リバースプロキシ | 責任のある | プロキシリクエストを受信する |
| HTTP圧縮 | 通常は責任のある | オプション |
| HTTP キャッシュ | 静的リソースとプロキシ キャッシュ | ビジネスキャッシュ |
| API ルーティング | 前へ | ビジネスルーティング |
| Authentication | 普通に無責任 | 責任のある |
| Authorization | 普通に無責任 | 責任のある |
| ファイルアップロードのサイズ制限 | 第一レベルの制限 | ビジネスレベルの検証 |
| 電流制限をリクエストする | IP/リクエストレベル電流制限 | ユーザー/ビジネスレベルの電流制限 |
| バックグラウンドタスク | 無責任な | Celery およびその他のタスク システム |
概要
Nginx 最も重要な知識は次のように要約できます。
| モジュール | コアコンセプト |
|---|---|
| 構成構造 | events、http、server、location |
| リクエストルーティング | server_name、location、proxy_pass |
| 静的ファイル | root、alias、try_files |
| ネットワークセキュリティ | TLS、Real IP、電流制限 |
| パフォーマンスの最適化 | gzip/Brotli、Cache-Control、Buffering |
| 長い接続 | WebSocket、SSE |
| 運用・保守 | Access Log、Error Log、nginx -t、Reload |
React + Django + Docker Compose プロジェクトの場合、マスターする価値があるのは次のとおりです。
locationマッチングとproxy_passパス処理。- Nginx と Django 間の Header パススルーおよびプロキシ信頼構成。
- React SPAの
try_files処理。 - HTML 再検証による静的リソースの長期キャッシュ。
- gzip/Brotli 圧縮。
- HTTP リクエストのタイムアウト、Buffering および SSE。
- Docker 環境でのログと構成のチェック。