導入と環境要件
本ガイドでは、自己完結型のウェブアプリケーション「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 期限切れ
- サービスダウン検知
- 異常なトラフィック流量