diff --git a/debug_502_error.py b/debug_502_error.py index 1271d13..eb4063f 100644 --- a/debug_502_error.py +++ b/debug_502_error.py @@ -42,6 +42,36 @@ def test_checkin_endpoint(): print(f"🎯 テスト対象URL: {checkin_url}") print(f"📊 テストデータ: {json.dumps({k: v if k != 'image' else '[BASE64_DATA]' for k, v in test_data.items()}, indent=2, ensure_ascii=False)}") + # まず、GETリクエストでエンドポイントの存在確認 + print(f"\n🔍 エンドポイント存在確認(GETリクエスト)") + try: + get_response = requests.get(checkin_url, timeout=10) + print(f"GET レスポンス: {get_response.status_code}") + if get_response.status_code == 405: + print(f"✅ エンドポイントは存在するが、GETメソッドは許可されていない(正常)") + elif get_response.status_code == 404: + print(f"❌ エンドポイントが見つからない") + return False + except Exception as e: + print(f"❌ GET テストエラー: {e}") + + # 正しいURLパターンでもテスト + alternative_urls = [ + f"{base_url}/rog/checkin_from_rogapp", + f"{base_url}/api/checkin_from_rogapp", + f"{base_url}/checkin_from_rogapp" + ] + + print(f"\n🔍 代替URLパターンテスト") + for url in alternative_urls: + try: + resp = requests.get(url, timeout=5) + print(f" {url}: {resp.status_code}") + if resp.status_code in [200, 405]: + print(f" ✅ このURLが正しい可能性があります") + except: + print(f" {url}: 接続エラー") + try: print(f"\n🚀 POSTリクエスト送信中...") @@ -60,7 +90,13 @@ def test_checkin_endpoint(): print(f" ステータスコード: {response.status_code}") print(f" ヘッダー: {dict(response.headers)}") - if response.status_code == 502: + if response.status_code == 405: + print(f"❌ 405 Method Not Allowed エラー") + print(f" 💡 原因: エンドポイントが存在するが、POSTメソッドが許可されていない") + print(f" 📋 許可されているメソッドを確認が必要") + print(f" レスポンステキスト: {response.text}") + return False + elif response.status_code == 502: print(f"❌ 502 Bad Gateway エラーを確認しました") print(f" レスポンステキスト: {response.text}") return False @@ -94,7 +130,6 @@ def monitor_logs_during_test(): # アプリケーションログを監視 result = subprocess.run( ['docker', 'compose', 'logs', '--tail=20', '--follow', 'app'], - cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', capture_output=True, text=True, timeout=10 @@ -123,7 +158,6 @@ def check_docker_services(): # サービス状態確認 result = subprocess.run( ['docker', 'compose', 'ps'], - cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', capture_output=True, text=True, check=True @@ -135,7 +169,6 @@ def check_docker_services(): # ヘルスチェック health_result = subprocess.run( ['docker', 'compose', 'exec', 'app', 'python', 'manage.py', 'check'], - cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', capture_output=True, text=True ) @@ -164,7 +197,6 @@ def analyze_nginx_config(): # nginx設定テスト result = subprocess.run( ['docker', 'compose', 'exec', 'nginx', 'nginx', '-t'], - cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', capture_output=True, text=True ) @@ -179,7 +211,6 @@ def analyze_nginx_config(): # 最近のnginxエラーログ error_log_result = subprocess.run( ['docker', 'compose', 'logs', '--tail=10', 'nginx'], - cwd='/Volumes/PortableSSD1TB/main/GifuTabi/rogaining_srv_exdb-2/rogaining_srv', capture_output=True, text=True ) @@ -190,11 +221,57 @@ def analyze_nginx_config(): except Exception as e: print(f"❌ nginx確認エラー: {e}") +def check_django_configuration(): + """ + Django設定の確認 + """ + print(f"\n⚙️ Django設定確認") + print("-" * 40) + + try: + # Django URL設定の確認 + result = subprocess.run( + ['docker', 'compose', 'exec', 'app', 'python', 'manage.py', 'show_urls'], + capture_output=True, + text=True + ) + + if result.returncode == 0: + print(f"✅ URL確認コマンド実行成功") + # checkin_from_rogappが含まれているかチェック + if 'checkin_from_rogapp' in result.stdout: + print(f"✅ checkin_from_rogappエンドポイントがURL設定に存在") + else: + print(f"❌ checkin_from_rogappエンドポイントがURL設定に見つからない") + print(f"URL一覧(抜粋):") + for line in result.stdout.split('\n'): + if 'checkin' in line.lower() or 'rogapp' in line.lower(): + print(f" {line}") + else: + print(f"⚠️ show_urlsコマンドが利用できません") + + # CSRF設定確認 + csrf_result = subprocess.run( + ['docker', 'compose', 'exec', 'app', 'python', '-c', + "import django; django.setup(); from django.conf import settings; print(f'CSRF_COOKIE_SECURE: {settings.CSRF_COOKIE_SECURE}'); print(f'CSRF_TRUSTED_ORIGINS: {getattr(settings, \"CSRF_TRUSTED_ORIGINS\", \"Not set\")}')"], + capture_output=True, + text=True + ) + + if csrf_result.returncode == 0: + print(f"\n🔒 CSRF設定:") + print(csrf_result.stdout) + else: + print(f"⚠️ CSRF設定確認エラー: {csrf_result.stderr}") + + except Exception as e: + print(f"❌ Django設定確認エラー: {e}") + def main(): """ メイン実行関数 """ - print(f"🚨 502 Bad Gateway エラー調査ツール") + print(f"🚨 405 Method Not Allowed エラー調査ツール") print(f"時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print("=" * 60) @@ -204,13 +281,16 @@ def main(): # 2. nginx設定確認 analyze_nginx_config() - # 3. エンドポイントテスト + # 3. Django設定確認 + check_django_configuration() + + # 4. エンドポイントテスト print(f"\n🎯 エンドポイントテスト実行") print("-" * 40) success = test_checkin_endpoint() - # 4. ログ確認 + # 5. ログ確認 monitor_logs_during_test() # 結果まとめ @@ -221,12 +301,18 @@ def main(): print(f"✅ checkin_from_rogappエンドポイントは正常に動作しています") print(f"💡 502エラーは一時的な問題だった可能性があります") else: - print(f"❌ 502エラーを確認しました") - print(f"💡 次の対策が必要です:") - print(f" 1. アプリケーションのエラーログを詳細確認") - print(f" 2. データベース接続状態の確認") - print(f" 3. メモリ使用量やリソース状況の確認") - print(f" 4. 依存関係やモジュールの問題確認") + print(f"❌ 405 Method Not Allowed エラーを確認しました") + print(f"💡 問題の原因と対策:") + print(f" 🔧 考えられる原因:") + print(f" 1. CSRFトークンの問題") + print(f" 2. @api_viewデコレータの設定問題") + print(f" 3. URLパターンの不一致") + print(f" 4. nginx設定でPOSTメソッドがブロックされている") + print(f" 🛠️ 推奨対策:") + print(f" 1. views.pyで@api_view(['POST'])の設定確認") + print(f" 2. urls.pyでのルーティング確認") + print(f" 3. nginx設定でPOSTメソッド許可確認") + print(f" 4. CSRF設定の確認") if __name__ == "__main__": main() diff --git a/nginx.conf b/nginx.conf index 37a6191..a1bb6e2 100644 --- a/nginx.conf +++ b/nginx.conf @@ -34,11 +34,14 @@ http { alias /app/static/; } - # スーパーバイザー Web アプリケーション - location / { + # スーパーバイザー Web アプリケーション(特定パス) + location = / { root /usr/share/nginx/html; index index.html; - try_files $uri $uri/ /index.html; + } + + location = /index.html { + root /usr/share/nginx/html; } # スーパーバイザー専用の静的ファイル @@ -46,6 +49,44 @@ http { root /usr/share/nginx/html; try_files $uri $uri/ =404; } + + # Django ログアウト・ログイン系の処理 + location /accounts/ { + proxy_pass http://app:8000; + 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 60s; + proxy_send_timeout 60s; + proxy_read_timeout 300s; + client_max_body_size 50M; + } + + # ろげイニングアプリ専用API(重要!) + location /gifuroge/ { + proxy_pass http://app:8000; + 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; + + # タイムアウト設定(502エラー対策) + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 300s; + + # バッファ設定(大きなレスポンス対策) + proxy_buffering on; + proxy_buffer_size 8k; + proxy_buffers 8 8k; + proxy_busy_buffers_size 16k; + proxy_temp_file_write_size 16k; + + # クライアント設定(画像アップロード対応) + client_max_body_size 100M; + } # Django API プロキシ location /api/ { @@ -93,6 +134,29 @@ http { # クライアント設定 client_max_body_size 50M; } + + # Django メインアプリケーション(rog/以下) + location /rog/ { + proxy_pass http://app:8000; + 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 60s; + proxy_send_timeout 60s; + proxy_read_timeout 300s; + client_max_body_size 100M; + } + + # Django その他のパス(デフォルト) + location ~ ^/(media|favicon\.ico|robots\.txt) { + proxy_pass http://app:8000; + 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; + } error_page 500 502 503 504 /50x.html; location = /50x.html {