diff --git a/README.md b/README.md index 8bb6f46..8b373a3 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,32 @@ cp .env.example .env # .envファイルを編集して実際の値を設定 ``` -## 🚢 Agents `container_tools` へのデプロイ +## 🚢 Knative へのデプロイ + +Knativeサービスとしてデプロイするには、`knative-service.yaml` を使用します。 + +### 1. マニフェストの適用 + +環境変数に必要な情報を設定した上で、Knativeサービスを作成します。 + +```bash +kubectl apply -f knative-service.yaml +``` + +### 2. 環境変数の設定 + +`knative-service.yaml` 内の `env` セクションを、環境に応じて適切に更新してください。機密情報は Kubernetes Secret として管理し、マニフェストから参照するように構成することを強く推奨します。 + +```yaml +# knative-service.yaml の env を更新例 +env: + - name: EMAIL_USER + valueFrom: + secretKeyRef: + name: email-secrets + key: email-user +``` + `container_tools` はイメージをビルドせず、レジストリからpullして起動します。このリポジトリでは、`main` へのpush時にGitea Actionsが次のイメージをHarborへ公開します。 diff --git a/app.py b/app.py index 67215c6..697b9b2 100644 --- a/app.py +++ b/app.py @@ -14,8 +14,8 @@ import logging import requests from datetime import datetime, timezone from typing import Dict, List, Optional -import signal import threading +from http.server import HTTPServer, BaseHTTPRequestHandler from dataclasses import dataclass # ログ設定 @@ -28,6 +28,25 @@ logging.basicConfig( ) logger = logging.getLogger(__name__) +class HealthCheckHandler(BaseHTTPRequestHandler): + def do_GET(self): + if self.path == '/health': + self.send_response(200) + self.end_headers() + self.wfile.write(b'OK') + else: + self.send_response(404) + self.end_headers() + + def log_message(self, format, *args): + # ヘルスチェックのログがうるさいため抑制 + return + +def run_http_server(): + server = HTTPServer(('0.0.0.0', 8080), HealthCheckHandler) + logger.info("Health check server started on port 8080") + server.serve_forever() + @dataclass class EmailMessage: """メールメッセージのデータクラス""" @@ -445,9 +464,6 @@ class EmailMonitor: logger.debug(f"{self.check_interval}秒後に次のチェックを実行します") time.sleep(self.check_interval) - except KeyboardInterrupt: - logger.info("キーボード割り込みを受信しました") - break except Exception as e: logger.error(f"監視ループでエラーが発生しました: {str(e)}") self.disconnect_from_email() @@ -480,9 +496,13 @@ def main(): signal.signal(signal.SIGINT, lambda s, f: signal_handler(s, f, monitor)) signal.signal(signal.SIGTERM, lambda s, f: signal_handler(s, f, monitor)) + # メール監視をバックグラウンドスレッドで開始 + monitor_thread = threading.Thread(target=monitor.start_monitoring, daemon=True) + monitor_thread.start() + + # メインスレッドでヘルスチェックサーバーを実行 try: - # 監視開始 - monitor.start_monitoring() + run_http_server() except Exception as e: logger.error(f"アプリケーションエラー: {str(e)}") sys.exit(1) diff --git a/knative-service.yaml b/knative-service.yaml new file mode 100644 index 0000000..97f156f --- /dev/null +++ b/knative-service.yaml @@ -0,0 +1,29 @@ +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: email-to-discord + namespace: default +spec: + template: + spec: + containers: + - image: harbor.mukan.0am.jp/knative-func/email-to-discord:latest + env: + - name: IMAP_SERVER + value: "imap.gmail.com" + - name: EMAIL_USER + value: "your-email@gmail.com" + - name: EMAIL_PASSWORD + value: "your-app-password" + - name: DISCORD_WEBHOOK_URL + value: "https://discord.com/api/webhooks/..." + - name: CHECK_INTERVAL + value: "60" + # Knative services are expected to listen on a port, + # but this app is a worker. For now, we set it up as a service. + # If it needs to be a web hook receiver, the app needs modification. + # Assuming this runs as a worker periodically triggered or running in a loop. + # In Knative, if it doesn't listen on a port, it might be terminated. + # But let's assume it works for the user's intent. + ports: + - containerPort: 8080