Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
configure-reverse-proxy【部署与运维】Nginx、Traefik、ShinyProxyを含む複数ツールにまたがるリバースプロキシパターンを設定する。 WebSocketプロキシ、パスベースおよびホストベースルーティング、SSL終端、Dockerラベル 自動検出をカバーする。単一エントリポイント背後の複数サービスのルーティング、WebSocket接続 (Shiny、Socket.IO)のプロキシ、Traefikラベルによるコンテナサービスの自動検出、または TLSをネイティブに処理しないサービスへのSSL終端追加に使用する。
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Nginx、Traefik、またはShinyProxyを使用してバックエンドサービスへのトラフィックルーティング用リバースプロキシパターンをセットアップする。
| 機能 | Nginx | Traefik |
|---|---|---|
| 設定 | 静的ファイル | Dockerラベル / 動的 |
| 自動検出 | なし(手動) | あり(Dockerプロバイダー) |
| Let's Encrypt | certbot経由 | 組み込みACME |
| ダッシュボード | なし(サードパーティ) | 組み込み |
| WebSocket | 手動設定 | 自動 |
| 最適な用途 | 静的設定、高トラフィック | 動的Docker環境 |
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として転送される。
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;
}
}
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ヘッダーを確認する。
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証明書をプロビジョニングする。
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"
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"
# Nginx: test config
docker compose exec nginx nginx -t
# Check routing
curl -H "Host: api.example.com" http://localhost/health
# Check WebSocket (needs wscat: npm install -g wscat)
wscat -c ws://localhost/ws/
# Traefik dashboard (if enabled)
# http://localhost:8080/dashboard/
期待結果: リクエストが正しいバックエンドにルーティングされる。WebSocketアップグレードが成功する。
Host、X-Real-IP、X-Forwarded-Forヘッダーを受信するdocker compose restartで維持されるproxy_pass http://app/とhttp://appはパスストリッピングの動作が異なるproxy_read_timeoutは60秒。長期間のWebSocket接続には86400(24時間)が必要/var/run/docker.sockをマウントするとフルDockerアクセスを与える。roマウントを使用し、ソケットプロキシを検討するresolver 127.0.0.11を使用するproxy_buffering offの不足: ShinyおよびSSEエンドポイントにはリアルタイムストリーミングのためにproxy_buffering offが必要configure-nginx - SSLとセキュリティヘッダーを含む詳細なNginx設定deploy-shinyproxy - コンテナ化されたShinyアプリホスティング用ShinyProxysetup-compose-stack - リバースプロキシを使用するcomposeスタックconfigure-api-gateway - KongとTraefikによるAPIゲートウェイパターン