Nginxは静的配信・リバースプロキシ・ロードバランサ・API gatewayとして本番サーバーで圧倒的シェアを持つWebサーバーです。ローカル開発でDocker + Nginxを組み合わせれば、本番構成をそのまま手元で再現でき、「本番だけで出るバグ」を激減させられます。
多くの入門記事は「静的ファイルを配信するだけ」で終わっていますが、実戦ではSPA(React/Vue/Next.js)のHistory APIフォールバック、Node.js/Python/GoバックエンドへのリバースプロキシとWebSocket対応、ローカルHTTPS(mkcert)、gzip/brotli圧縮、複数プロジェクト自動ルーティング(nginx-proxy)、キャッシュ・レートリミット・セキュリティヘッダーまで幅広く必要になります。
この記事では、Docker × Nginxの基礎から6つの典型用途パターン別にnginx.confレシピを完全収録し、ローカルHTTPS対応・開発サーバー(Vite/webpack-dev-server)連携・パフォーマンス最適化・セキュリティヘッダー・マルチプロジェクト運用まで、2026年の現場で即使える完全ガイドとしてまとめます。Nginx + PHP-FPM特化の構築は【Docker】Nginx + PHP-FPMの環境をComposeで構築する手順、WordPress特化は【Docker】WordPress環境構築完全ガイドで別途扱っています。
この記事で学べること
- Nginx × Dockerの6用途マトリクス(静的/SPA/リバプロ/WebSocket/ロードバランサ/API gateway)
- 30秒で動く最小compose.yml+nginx.conf
- SPAのHistory APIフォールバック(React/Vue/Nuxt等)
- Node.js/Python/Go バックエンドへのリバースプロキシ
- WebSocket対応(Upgrade/Connectionヘッダー)
- upstreamでロードバランシング(複数インスタンス)
- ローカルHTTPS(mkcertでTLS証明書)とHTTP/2有効化
- 開発サーバー(Vite・webpack-dev-server)のHMR透過プロキシ
- gzip/brotli圧縮と
proxy_cacheレスポンスキャッシュ - セキュリティヘッダー(CSP/X-Frame-Options/HSTS)
- 複数プロジェクト自動ルーティング(nginx-proxy)
- Nginx vs Caddy vs Traefik の選定フレーム
- 30秒クイックスタート:最小構成
- Nginxの6用途マトリクス:どのパターンで使うか
- パターン①:静的ファイル配信+パフォーマンス最適化
- パターン②:SPA(React/Vue/Nuxt)のHistory APIフォールバック
- パターン③:Node.js/Python/GoバックエンドへのリバースプロキシとDocker Compose連携
- パターン④:WebSocket対応(Socket.IO / GraphQL Subscriptions)
- パターン⑤:upstreamでロードバランシング
- パターン⑥:API gateway構成(マイクロサービス統合)
- Vite/webpack-dev-serverとNginxのHMR連携
- ローカルHTTPS:mkcertでHTTP/2 + SSL
- nginx-proxyで複数プロジェクト自動ルーティング
- セキュリティヘッダーの基本セット
- Nginx vs Caddy vs Traefik:ローカル開発での選定
- よくあるトラブルと対処
- よくある質問
- 関連記事
- まとめ
30秒クイックスタート:最小構成
project/
├─ compose.yml
├─ nginx/
│ └─ default.conf
└─ src/
└─ index.html
services:
nginx:
image: nginx:1.27-alpine
ports: ["8080:80"]
volumes:
- ./src:/usr/share/nginx/html:ro
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
restart: unless-stopped
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
docker compose up -d # http://localhost:8080 で確認 docker compose down
2026年の推奨イメージ:nginx:1.27-alpine(軽量で高速、脆弱性対応も迅速)。nginx:latestは意図せずバージョン変更されるため、本番でも使うならマイナー固定が安全。version:キーは不要(ComposeV2以降)。
Nginxの6用途マトリクス:どのパターンで使うか
Nginxは単なる静的Webサーバーではなく、用途によって設定が大きく変わります。まず「自分の使い方」を特定することが最速の入り口です。
複数用途を混ぜるのが現代の典型
実案件では①静的(CDN的)+②SPA+③APIリバプロ+④WebSocketを1つのNginxで同時に扱うことが普通です。後述の完全版nginx.confではこれをlocationごとに切り分けて実装します。
パターン①:静的ファイル配信+パフォーマンス最適化
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# 文字コード明示(日本語サイトで重要)
charset utf-8;
# gzip圧縮(全レスポンス高速化)
gzip on;
gzip_vary on;
gzip_types text/plain text/css text/javascript application/json application/javascript application/xml+rss image/svg+xml;
gzip_min_length 1024;
gzip_comp_level 6;
# 長期キャッシュ(ハッシュ付きアセットにおすすめ)
location ~* \.(?:css|js|woff2?|ttf|otf|eot|ico|png|jpg|jpeg|gif|webp|avif|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
# HTMLは毎回fetch(誤キャッシュ対策)
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
try_files $uri =404;
}
location / {
try_files $uri $uri/ =404;
}
}
gzipとbrotliの使い分け
2026年時点ではbrotliがgzipより10〜20%小さくなるためモダンブラウザ向けに推奨。公式nginxイメージはbrotli未対応のため、nginx:mainline-otelやghcr.io/nginxinc/nginx-unprivileged、または自前ビルドDockerfileでngx_brotliモジュールを組み込むか、CDN側で圧縮(CloudFront/Cloudflare)する方が現実的です。
パターン②:SPA(React/Vue/Nuxt)のHistory APIフォールバック
SPAでブラウザの直接リロードや/users/42のような深いURLへ直アクセスすると404エラーが出るのがNginxでの定番つまづき。try_filesでindex.htmlにフォールバックさせるのが解決策です。
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# アセットは長期キャッシュ
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPAフォールバック:存在しないパスはindex.htmlに返す
location / {
try_files $uri $uri/ /index.html;
}
# HTMLはキャッシュさせない(新バージョン即反映)
location = /index.html {
expires -1;
add_header Cache-Control "no-store, must-revalidate";
}
}
Vite/React/Nuxtビルド出力をNginxに載せる
# ビルドステージ FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 配信ステージ FROM nginx:1.27-alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx/default.conf /etc/nginx/conf.d/default.conf EXPOSE 80
Vite/Reactはdist/、Nuxt 3 SSGは.output/public/、Next.js SSGはout/が成果物。npm run buildした出力をCOPY --from=builder /app/<出力先>でNginx配信用ディレクトリに置くのが定石です。
パターン③:Node.js/Python/GoバックエンドへのリバースプロキシとDocker Compose連携
実開発で最も使用頻度が高いのがこのパターン。フロント(静的/SPA)とバックエンド(API)を1つのNginxで束ね、CORS問題も同一オリジンで解決します。
services:
nginx:
image: nginx:1.27-alpine
ports: ["8080:80"]
volumes:
- ./frontend/dist:/usr/share/nginx/html:ro
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- api
networks: [app-net]
api:
build: ./backend
expose: ["3000"] # 外部公開しない、nginx経由のみ
environment:
NODE_ENV: development
volumes:
- ./backend:/app
- /app/node_modules
command: npm run dev
networks: [app-net]
networks:
app-net:
upstream api_backend {
server api:3000; # Docker内部DNSで解決
keepalive 32; # 接続再利用で高速化
}
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
# /api/ パスはNode.jsへ転送
location /api/ {
proxy_pass http://api_backend/; # 末尾/で/api/を剥がす
proxy_http_version 1.1;
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_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# keepalive
proxy_set_header Connection "";
}
# その他はSPAフォールバック
location / {
try_files $uri $uri/ /index.html;
}
}
proxy_passの末尾スラッシュに注意:proxy_pass http://api_backend/;(末尾/あり)は/api/を剥がして転送。proxy_pass http://api_backend;(なし)は/api/のまま転送。この違いでバックエンド側のルート定義と一致しなくて404、という罠がよく起きます。
パターン④:WebSocket対応(Socket.IO / GraphQL Subscriptions)
WebSocketはHTTP/1.1のUpgradeヘッダーで接続を昇格させる仕組みです。Nginxを素通りさせるためにはConnection/Upgradeヘッダーを明示的に転送する必要があります。
# http {} または server {} の外でも定義可能
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream ws_backend {
server api:3000;
}
server {
listen 80;
# WebSocketエンドポイント
location /ws/ {
proxy_pass http://ws_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# WebSocket特有の長時間接続
proxy_read_timeout 86400s; # 1日
proxy_send_timeout 86400s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Socket.IOのfallback(long polling)
location /socket.io/ {
proxy_pass http://ws_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
}
WebSocket疎通確認
ブラウザDevToolsのNetworkタブで“WS”フィルタし、ステータスが101 Switching Protocolsになっていれば成功。426 Upgrade Requiredや502が出るのはUpgradeヘッダー転送漏れが典型的。
パターン⑤:upstreamでロードバランシング
Nginxのupstreamディレクティブで複数バックエンドへの負荷分散が可能です。ローカル開発でも同時起動で水平スケールを試すのに使えます。
services:
nginx:
image: nginx:1.27-alpine
ports: ["8080:80"]
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
networks: [app-net]
api:
build: ./backend
deploy:
replicas: 3 # 3インスタンス
expose: ["3000"]
networks: [app-net]
networks:
app-net:
# ラウンドロビン(デフォルト)
upstream api_backend {
server api:3000; # Compose内部DNSで3インスタンスに自動分散
}
# 重み付け
upstream api_backend {
server api1:3000 weight=3;
server api2:3000 weight=1;
server api3:3000 backup; # 他全滅時のみ使用
}
# IPハッシュ(セッション固定)
upstream api_backend {
ip_hash;
server api1:3000;
server api2:3000;
}
# 最小接続数
upstream api_backend {
least_conn;
server api1:3000;
server api2:3000;
}
# ヘルスチェック付き(passive)
upstream api_backend {
server api1:3000 max_fails=3 fail_timeout=30s;
server api2:3000 max_fails=3 fail_timeout=30s;
}
パターン⑥:API gateway構成(マイクロサービス統合)
複数のマイクロサービスをlocationごとにproxy_passすることで統合エンドポイントを作れます。CORSを気にせず同一オリジンでアクセス可能。
upstream auth_service { server auth:4000; }
upstream user_service { server users:5000; }
upstream order_service { server orders:6000; }
upstream frontend { server web:3000; }
server {
listen 80;
# 認証API
location /api/auth/ {
proxy_pass http://auth_service/;
include /etc/nginx/snippets/proxy.conf;
}
# ユーザーAPI
location /api/users/ {
proxy_pass http://user_service/;
include /etc/nginx/snippets/proxy.conf;
}
# 注文API
location /api/orders/ {
proxy_pass http://order_service/;
include /etc/nginx/snippets/proxy.conf;
}
# フロント(Next.jsなど、SSR前提)
location / {
proxy_pass http://frontend;
include /etc/nginx/snippets/proxy.conf;
}
}
proxy_http_version 1.1; 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_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_connect_timeout 30s; proxy_read_timeout 60s;
snippetsパターン:共通のproxy設定を別ファイルに切り出してincludeで読み込むと、設定の重複を避けられます。新規serviceを足すたびに5〜10行コピペしていた人はぜひ。
Vite/webpack-dev-serverとNginxのHMR連携
開発サーバーのホットリロード(HMR)はWebSocket経由のため、NginxでSPA構成するときはHMR配信をそのまま透過転送するだけで動きます。本番ビルドと同じ構成をローカルで試せるのが最大のメリット。
services:
nginx:
image: nginx:1.27-alpine
ports: ["8080:80"]
volumes:
- ./nginx/dev.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- web
networks: [app-net]
web:
image: node:20-alpine
working_dir: /app
volumes:
- .:/app
command: npm run dev -- --host 0.0.0.0
expose: ["5173"] # Viteの既定
networks: [app-net]
api:
build: ./backend
expose: ["3000"]
networks: [app-net]
networks:
app-net:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream vite_dev { server web:5173; }
upstream api_dev { server api:3000; }
server {
listen 80;
location /api/ {
proxy_pass http://api_dev/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# Viteのdev serverへ全て転送(HMR WebSocket含む)
location / {
proxy_pass http://vite_dev;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
}
Viteはvite.config.tsでserver.hmr.clientPort: 8080の設定が必要になる場合があります。HMRが効かない時はDevToolsのWSタブで接続先ポートを確認し、Vite側のhmr設定を調整してください。
ローカルHTTPS:mkcertでHTTP/2 + SSL
OAuth認証/Stripe/Service Worker/セキュアCookie(SameSite=None)などはHTTPS必須。mkcertで信頼済み証明書を作ってNginxに載せると数分で対応できます。
# mkcertインストール(macOS) brew install mkcert mkcert -install # ローカルCAインストール(初回のみ) # 証明書発行 mkdir -p certs mkcert -key-file ./certs/local.key -cert-file ./certs/local.crt \ local.dev app.local.dev localhost 127.0.0.1
services:
nginx:
image: nginx:1.27-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/https.conf:/etc/nginx/conf.d/default.conf:ro
- ./certs:/etc/nginx/certs:ro
# HTTPはリダイレクト
server {
listen 80;
server_name local.dev;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on; # Nginx 1.25.1+はhttp2 on;構文
server_name local.dev;
ssl_certificate /etc/nginx/certs/local.crt;
ssl_certificate_key /etc/nginx/certs/local.key;
# モダンなTLS設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
# 静的/SPAなど既存locationをここに
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html;
}
}
# /etc/hosts (macOS/Linux) or C:\Windows\System32\drivers\etc\hosts 127.0.0.1 local.dev app.local.dev # 起動後 # → https://local.dev/ に鍵マーク付きでアクセス成功
Nginx 1.25.1以降のhttp2構文変更
旧来のlisten 443 ssl http2;は非推奨になり、http2 on;ディレクティブが推奨に。警告が出る場合は新構文に書き換えを。
nginx-proxyで複数プロジェクト自動ルーティング
フリーランスや複数案件を並行管理する人にはnginx-proxyが神機能。Docker Socketを監視してVIRTUAL_HOST環境変数を持つコンテナを自動で配信対象に追加します。
# proxy/compose.yml
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:latest
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs:/etc/nginx/certs:ro
networks: [proxy-net]
networks:
proxy-net:
# projects/siteA/compose.yml
services:
web:
image: nginx:1.27-alpine
environment:
VIRTUAL_HOST: sitea.localhost
VIRTUAL_PORT: 80
HTTPS_METHOD: noredirect
volumes:
- ./dist:/usr/share/nginx/html:ro
networks: [proxy-net]
networks:
proxy-net:
external: true
name: proxy_proxy-net
# 共通プロキシを1回だけ起動 docker compose -f proxy/compose.yml up -d # 各プロジェクト追加 docker compose -f projects/siteA/compose.yml up -d docker compose -f projects/siteB/compose.yml up -d # hostsに追加すればブラウザでアクセス可能 # 127.0.0.1 sitea.localhost siteb.localhost
nginxproxy/acme-companionを追加すれば、VIRTUAL_HOSTに応じてLet’s Encrypt証明書を自動取得・更新してくれます。本番でも使える構成で、ステージング/本番の切替がほぼ同じ設定で完結。
セキュリティヘッダーの基本セット
ローカル開発でも本番と同じセキュリティヘッダーを付けておくと、「本番で急に動かなくなる」を防げます。
# /etc/nginx/snippets/security-headers.conf # XSS対策(モダンブラウザはCSPを使う) add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always; # HTTPS運用時 add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; # 最低限のCSP(実際はプロジェクト固有に) add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self';" always;
server {
listen 443 ssl;
http2 on;
# ... 他の設定
include /etc/nginx/snippets/security-headers.conf;
location / {
try_files $uri $uri/ /index.html;
}
}
Content-Security-Policyは本番リリース前に必ずプロジェクト固有に調整。広告SDK・アナリティクス・外部フォント(Google Fonts)などがscript-srcやstyle-srcに追加必要です。ブラウザDevToolsのConsoleでCSP違反が警告として出るので確認しながら調整。
Nginx vs Caddy vs Traefik:ローカル開発での選定
まずNginxを学ぶべき理由
2026年の時点でもWebサーバーシェア&案件需要でNginxが圧倒的。Caddyは個人開発で便利、TraefikはK8sで真価を発揮しますが、企業Web開発の現場ではNginxの設定が書けるかどうかがそのまま開発力の差になります。「最初の1本」はNginxを推奨。
よくあるトラブルと対処
①設定変更が反映されない
# 設定テスト(構文エラーチェック) docker compose exec nginx nginx -t # リロード(ゼロダウンタイム) docker compose exec nginx nginx -s reload # 完全再起動(reloadで反映されない場合) docker compose restart nginx
②502 Bad Gateway
バックエンドに接続できないエラー。原因の定番は①upstreamのホスト名/ポートがcomposeのservice名と一致していない、②バックエンドがまだ起動完了していない、③Docker networkが別(networksセクションの設定漏れ)。docker compose logs nginxでconnect() failedの詳細を確認。
③413 Request Entity Too Large
http {
client_max_body_size 128M; # アップロードサイズ上限
}
# serverまたはlocationでも設定可能
server {
client_max_body_size 128M;
...
}
④Windowsでファイルマウントが遅い
Windows(Docker Desktop)でbind mount経由のファイル読み込みは遅い場合があります。対処:①WSL2側のファイルシステムに置く(\\wsl$\Ubuntu\home\以下)、②named volumeにビルド成果物を置く、③OrbStack(Mac)/Rancher Desktopなど代替へ乗り換え。
⑤ログが見たい
# リアルタイム追跡
docker compose logs -f nginx
# access.log/error.logを詳細化(nginx.conf)
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
}
⑥CORSエラー
リバースプロキシ経由(/apiを同一オリジンで提供)ならCORSは発生しません。それでも必要ならlocation内にadd_header "Access-Control-Allow-Origin" "https://example.com";等を追加。プリフライト対応はOPTIONSメソッドでreturn 204する必要があります。
よくある質問
1.27)にするとセキュリティパッチはビルド時に自動更新されて安全です。try_files $uri $uri/ /index.html;をlocation /に書けば解決。本記事「パターン②:SPA」セクション参照。proxy_passのホスト名は何を書く?proxy_pass http://api:3000;のように書けばOK。IPアドレス直書きは不要かつアンチパターンです。Upgrade/Connectionヘッダーの転送漏れが99%。proxy_set_header Upgrade $http_upgrade;とproxy_set_header Connection $connection_upgrade;を必ず設定し、mapディレクティブで$connection_upgradeを定義してください。本記事「パターン④」参照。docker compose exec nginx nginx -s reloadでゼロダウンタイムリロード可能。Nginxはマスタープロセスが古いworkerを安全に終了させ、新workerに引き継ぐ仕組み。本番でも使えるテクニック。リロード前はnginx -tで構文チェックを忘れずに。upstreamはバックエンドサーバーのグループ定義(複数サーバー、重み、ip_hash等)、serverは受信するHTTPサーバーの定義(ポート、server_name、location)。upstreamで定義したグループ名をproxy_pass http://api_backend;のようにserverブロック内のlocationで参照するのが典型パターンです。docker compose exec nginx nginx -tで構文チェック。VS Codeならshanoor.vscode-nginx拡張、JetBrainsなら内蔵Nginxサポートでリアルタイム警告が出ます。reload前に必ずnginx -tを実行する習慣がベスト。compose.yml(共通)+compose.dev.yml/compose.prod.ymlでオーバーライドするパターンが主流。docker compose -f compose.yml -f compose.prod.yml up -dで本番設定を適用。nginx.confもdev.conf/prod.confを別ファイルで用意し、マウント先を切替えれば同じイメージで両対応できます。関連記事
- 【Docker】Nginx + PHP-FPMの環境をComposeで構築する手順 — PHP動的サイト特化
- 【Docker】WordPress環境構築完全ガイド — WP特化のNginxリバプロ運用
- 【Docker】Composeで複数コンテナを連携させる方法 — サービス間通信の基礎
- 【Docker】volumeの使い方とデータ永続化の基本 — マウント戦略の前提
- 【Docker】bind mountとvolumeの違いと使い分け — 設定ファイル配置の判断
- 【Docker】phpMyAdminを使わずにMySQLを操作する方法 — バックエンドDB操作
- 【保存版】Docker Desktopが「Docker Desktop stopped」で起動できない時の完全解決ガイド — Docker起動不能時
- 【GitHub】Actions完全ガイド — NginxイメージのCI/CDビルド
まとめ
- 推奨イメージは
nginx:1.27-alpine、version:キーは不要 - Nginxの6用途:静的/SPA/リバプロ/WebSocket/LB/API gateway
- SPAは
try_files $uri $uri/ /index.html;でHistory APIフォールバック - リバプロは
upstream+proxy_pass、末尾/の有無でパス剥がしに注意 - WebSocketは
map $http_upgrade $connection_upgrade+Upgrade/Connection転送 - 開発サーバー(Vite/webpack)はHMR WSをそのまま透過プロキシ
- ローカルHTTPSはmkcert+
http2 on;(Nginx 1.25.1+新構文) - 複数プロジェクト管理はnginx-proxy+
VIRTUAL_HOSTで自動ルーティング - セキュリティヘッダー(HSTS/X-Frame-Options/CSP)はsnippetsに切り出してinclude
- gzip圧縮+長期キャッシュでパフォーマンス最適化
- 設定変更は
nginx -t→nginx -s reloadでゼロダウンタイム - 502の典型:
upstreamホスト名/depends_on/Docker networkの食い違い
Nginx × Dockerは、本番と同じ構成をローカルで再現するための最も実用的な組み合わせです。本記事の6パターン(静的/SPA/リバプロ/WebSocket/LB/gateway)とHTTPS・nginx-proxy・セキュリティヘッダーを押さえれば、個人開発から大規模マイクロサービスまで幅広いユースケースに対応できます。PHP特化はNginx + PHP-FPM、WordPress特化はWordPress Docker、Compose基礎は複数コンテナ連携の各記事と併せてご活用ください。

