Agent-almanac configure-reverse-proxy
install
source · Clone the upstream repo
git clone https://github.com/pjt222/agent-almanac
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/ja/skills/configure-reverse-proxy" ~/.claude/skills/pjt222-agent-almanac-configure-reverse-proxy-c33031 && rm -rf "$T"
manifest:
i18n/ja/skills/configure-reverse-proxy/SKILL.mdsource content
リバースプロキシの設定
Nginx、Traefik、またはShinyProxyを使用してバックエンドサービスへのトラフィックルーティング用リバースプロキシパターンをセットアップする。
使用タイミング
- 単一エントリポイント背後の複数サービスのルーティング
- WebSocket接続(Shiny、Socket.IO、ライブリロード)のプロキシ
- Traefikラベルによるコンテナサービスの自動検出
- 異なるバックエンドへのパスベースまたはホストベースルーティング
- TLSを処理しないサービスへのSSL終端追加
入力
- 必須: プロキシ先のバックエンドサービス(host:port)
- 必須: ルーティング戦略(パスベース、ホストベース、または両方)
- 任意: プロキシツールの優先(Nginx、Traefik)
- 任意: ホストベースルーティング用ドメイン名
- 任意: プロキシするWebSocketエンドポイント
手順
ステップ1: プロキシツールの選択
| 機能 | Nginx | Traefik |
|---|---|---|
| 設定 | 静的ファイル | Dockerラベル / 動的 |
| 自動検出 | なし(手動) | あり(Dockerプロバイダー) |
| Let's Encrypt | certbot経由 | 組み込みACME |
| ダッシュボード | なし(サードパーティ) | 組み込み |
| WebSocket | 手動設定 | 自動 |
| 最適な用途 | 静的設定、高トラフィック | 動的Docker環境 |
ステップ2: Nginx — パスベースルーティング
server { listen 80; location /api/ { proxy_pass http://api:8000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /app/ { proxy_pass http://webapp:3000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } }
注意:
proxy_passの末尾の/はlocationプレフィックスを削除する。location /api/でproxy_pass http://api:8000/;とすると、/api/usersは/usersとして転送される。
ステップ3: Nginx — ホストベースルーティング
server { listen 80; server_name api.example.com; location / { proxy_pass http://api:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } server { listen 80; server_name app.example.com; location / { proxy_pass http://webapp:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
ステップ4: Nginx — WebSocketプロキシ
WebSocketにはアップグレードヘッダーが必要。Shiny、Socket.IO、ライブリロードに不可欠:
location /ws/ { proxy_pass http://app:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400; }
Shinyアプリ専用:
map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { location / { proxy_pass http://shiny:3838; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_read_timeout 86400; proxy_buffering off; } }
期待結果: WebSocket接続が確立され永続化される。
失敗時:
proxy_http_version 1.1が設定されていることを確認する。UpgradeとConnectionヘッダーを確認する。
ステップ5: Traefik — Dockerラベル自動検出
docker-compose.yml:
services: traefik: image: traefik:v3.2 command: - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - letsencrypt:/letsencrypt api: image: myapi:latest labels: - "traefik.enable=true" - "traefik.http.routers.api.rule=Host(`api.example.com`)" - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.api.tls.certresolver=letsencrypt" - "traefik.http.services.api.loadbalancer.server.port=8000" webapp: image: myapp:latest labels: - "traefik.enable=true" - "traefik.http.routers.webapp.rule=Host(`app.example.com`)" - "traefik.http.routers.webapp.entrypoints=websecure" - "traefik.http.routers.webapp.tls.certresolver=letsencrypt" - "traefik.http.services.webapp.loadbalancer.server.port=3000" volumes: letsencrypt:
期待結果: Traefikがラベル経由でサービスを自動検出し、SSL証明書をプロビジョニングする。
ステップ6: Traefik — ラベルによるパスベースルーティング
services: api: labels: - "traefik.enable=true" - "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)" - "traefik.http.routers.api.middlewares=strip-api" - "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api" - "traefik.http.services.api.loadbalancer.server.port=8000"
ステップ7: Traefik — レート制限とヘッダー
labels: - "traefik.http.middlewares.ratelimit.ratelimit.average=100" - "traefik.http.middlewares.ratelimit.ratelimit.burst=50" - "traefik.http.middlewares.security.headers.stsSeconds=63072000" - "traefik.http.middlewares.security.headers.contentTypeNosniff=true" - "traefik.http.middlewares.security.headers.frameDeny=true" - "traefik.http.routers.app.middlewares=ratelimit,security"
ステップ8: プロキシ設定の検証
# Nginx: 設定テスト docker compose exec nginx nginx -t # ルーティングの確認 curl -H "Host: api.example.com" http://localhost/health # WebSocketの確認(wscatが必要: npm install -g wscat) wscat -c ws://localhost/ws/ # Traefikダッシュボード(有効な場合) # http://localhost:8080/dashboard/
期待結果: リクエストが正しいバックエンドにルーティングされる。WebSocketアップグレードが成功する。
バリデーション
- HTTPリクエストがパスまたはホストに基づいて正しいバックエンドにルーティングされる
- WebSocket接続が確立され維持される
- SSL終端が動作する(設定時)
- バックエンドサービスが正しい
、Host
、X-Real-IP
ヘッダーを受信するX-Forwarded-For - Traefikがラベル経由で新しいサービスを自動検出する(Traefik使用時)
- 設定が
で維持されるdocker compose restart
よくある落とし穴
- 末尾スラッシュの不一致: Nginxで
とproxy_pass http://app/
はパスストリッピングの動作が異なるhttp://app - WebSocketタイムアウト: デフォルトの
は60秒。長期間のWebSocket接続にはproxy_read_timeout
(24時間)が必要86400 - Dockerソケットのセキュリティ: Traefikで
をマウントするとフルDockerアクセスを与える。/var/run/docker.sock
マウントを使用し、ソケットプロキシを検討するro - DNS解決: Nginxは起動時にアップストリームを解決する。動的サービスにはDockerの内部DNS用に
を使用するresolver 127.0.0.11
の不足: ShinyおよびSSEエンドポイントにはリアルタイムストリーミングのためにproxy_buffering off
が必要proxy_buffering off
関連スキル
- SSLとセキュリティヘッダーを含む詳細なNginx設定configure-nginx
- コンテナ化されたShinyアプリホスティング用ShinyProxydeploy-shinyproxy
- リバースプロキシを使用するcomposeスタックsetup-compose-stack
- KongとTraefikによるAPIゲートウェイパターンconfigure-api-gateway