13ft Ladder サービスの構築:Nginx と Apache の逆方向プロキシ設定

導入と環境要件

本ガイドでは、自己完結型のウェブアプリケーション「13ft Ladder」を生产環境向けに配置する際の技術的な実装方法について解説します。バックエンドサービスを外部公開する際、直接ポートを開くのではなく、リバースプロキシ層を挟むことで、SSL/TLS の暗号化、負荷分散、そしてリクエストのフィルタリングを実現できます。

システム構成条件

  • ターゲットとなるバックエンドアプリケーション(通常はポート 5000 で動作)
  • Web サーバーソフトウェア(Nginx 1.18 以上または Apache 2.4 以上)
  • 有効な SSL トークン証明書(Let's Encrypt の利用が推奨されます)

ヘルスチェックと接続確認

設定を実行する前に、バックエンドサービスが正常にレスポンス返却しているかを確認します。

# ローカル環境でのステータス確認
curl -I http://localhost:5000

# 期待されるレスポンスヘッダー例
HTTP/1.1 200 OK
Server: Werkzeug/2.3.7 Python/3.9.18

Nginx によるプロキシ制御

平文 HTTP 設定

まず、標準的な HTTP リストニングを設定します。

server {
    listen 80;
    server_name example.org;
    
    location / {
        proxy_pass http://127.0.0.1:5000;
        
        # ヘッダー転送設定
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # タイムアウト閾値調整
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}

TLS 通信対応設定

セキュリティ強度を高めるため、HTTPS 設定を含めた完全版構成です。

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

    ssl_certificate     /etc/ssl/certs/fullchain.pem;
    ssl_certificate_key /etc/ssl/private/privkey.pem;

    # セキュリティプロトコル制限
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers off;

    location / {
        proxy_pass http://127.0.0.1:5000;
        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_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }
}

# HTTP から HTTPS への強制リダイレクト
server {
    listen 80;
    server_name example.org;
    return 301 https://$server_name$request_uri;
}

キャッシュ最適化

頻繁にアクセスされる静的または動的リソースに対して、ディスクベースのキャッシングを適用します。

# http コンテキスト内に記述
proxy_cache_path /data/nginx-cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
    # ... 上記設定継承
    
    location / {
        proxy_cache my_cache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating;
        add_header X-Cache-Status $upstream_cache_status;

        proxy_pass http://127.0.0.1:5000;
    }
}

Apache モジュールでの実装

基本設定

<VirtualHost *:80>
    ServerName example.org
    
    # プロキシ要求の無効化とホスト情報の維持
    ProxyRequests Off
    ProxyPreserveHost On
    
    <Proxy ">
        Require all granted
    </Proxy>
    
    # UPSTREAM へ転送
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
    
    # ログ出力設定
    ErrorLog ${APACHE_LOG_DIR}/service-error.log
    CustomLog ${APACHE_LOG_DIR}/service-access.log combined
</VirtualHost>

SSL 対応 Apache

暗号化通信を有効化する際の主要設定です。

<VirtualHost *:443>
    ServerName example.org
    
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/cert.pem
    SSLCertificateKeyFile /etc/ssl/private/privkey.pem
    SSLCertificateChainFile /etc/ssl/certs/chain.pem
    
    # セキュリティヘッダー追加
    Header always set Strict-Transport-Security "max-age=63072000"
    Header always set X-Content-Type-Options nosniff
    Header always set X-Frame-Options DENY
    
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    
    ProxyRequests Off
    ProxyPreserveHost On
    
    <Proxy ">
        Require all granted
    </Proxy>
    
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
</VirtualHost>

Docker 環境へのデプロイ

コンテナオーケストレーションを活用した構成例です。Docker Compose を使用することで、ネットワーク分離とライフサイクル管理が容易になります。

version: '3.8'

services:
  backend-app:
    image: ghcr.io/wasi-master/service:latest
    container_name: app-container
    restart: unless-stopped
    networks:
      - internal-net
    environment:
      - FLASK_ENV=production
  
  proxy-server:
    image: nginx:alpine
    container_name: web-proxy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./conf:/etc/nginx/conf.d/default.conf
      - ./certs:/etc/nginx/certs
    depends_on:
      - backend-app
    networks:
      - internal-net

networks:
  internal-net:
    driver: bridge

高度なインフラ設計

ロードバランシング

複数のインスタンスがある場合、Upstream ブロックを使用して負荷分散を行います。

upstream backend_pool {
    server 127.0.0.1:5000 weight=3;
    server 127.0.0.1:5001 weight=2;
    
    least_conn;
}

server {
    location / {
        proxy_pass http://backend_pool;
        # 他の設定...
    }
}

アクセス制限とセキュリティ

不正なトラフィックからアプリケーションを守るための制限ルールを適用します。

# リクエストレート制限定義
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

server {
    location / {
        limit_req zone=api_limit burst=20 nodelay;
        
        # CIDR ブロックに基づく IP 制限
        allow 192.168.1.0/24;
        deny all;
        
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:5000;
    }
}

監視とログ管理

カスタムログフォーマット

log_format detailed '$remote_addr - [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time';

access_log /var/log/nginx/detailed.log detailed;

ヘルスチェックエントポイント

location /health {
    access_log off;
    proxy_pass http://127.0.0.1:5000;
    proxy_set_header Host $host;
}

トラブルシューティング

現象 原因候補 解決策
502 Bad Gateway バックエンド停止中 プロセス状態を確認:systemctl status app-service
タイムアウト ファイアウォール遮断 内部ポート(5000)が開通しているか確認
SSL 誤り 証明書の不一致 パスと権限設定を確認
レスポンス遅延 メモリ不足 proxy_buffers パラメーターを見直す
# 設定ファイルの構文検証
nginx -t

# エラーログの監視
tail -f /var/log/nginx/error.log

# プロキシテスト実行
curl -H "Host: example.org" http://localhost

パフォーマンスチューニング

コンテンツタイプの動的キャッシュ

リソースの種類に応じて異なる TTL を設定します。

map $sent_http_content_type $expires {
    default                    off;
    text/html                  10m;
    text/css                   1h;
    ~image/                    1d;
}

server {
    expires $expires;
    add_header Cache-Control public;
}

キープアライブ接続

アップストリームとの接続を再利用し、オーバーヘッドを削減します。

upstream backend_pool {
    server 127.0.0.1:5000;
    
    keepalive 32;
    keepalive_timeout 30s;
    keepalive_requests 100;
}

運用上のベストプラクティス

ファイアウォール強化

不要なポートの開放を避けます。

ufw allow 80/tcp
ufw allow 443/tcp
ufw deny 5000/tcp

定期的なメンテナンス

自動更新スクリプトを設定し、認証情報の漏洩リスクを低減します。

# SSL 更新時の再読み込み
certbot renew --quiet --post-hook "systemctl reload nginx"

アラート機構

以下のような事象に対して監視アラートを設定してください:

  • SSL 期限切れ
  • サービスダウン検知
  • 異常なトラフィック流量

タグ: nginx Apache reverse-proxy Docker SSL

8月3日 17:14 投稿