Add HTTP health check server for Knative
Validate and publish container image / build (push) Successful in 3m58s

This commit is contained in:
Agents AI
2026-07-18 00:25:30 +00:00
parent 29904df87b
commit 62dc0a0cd5
3 changed files with 81 additions and 7 deletions
+26 -1
View File
@@ -80,7 +80,32 @@ cp .env.example .env
# .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へ公開します。 `container_tools` はイメージをビルドせず、レジストリからpullして起動します。このリポジトリでは、`main` へのpush時にGitea Actionsが次のイメージをHarborへ公開します。
+26 -6
View File
@@ -14,8 +14,8 @@ import logging
import requests import requests
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Dict, List, Optional from typing import Dict, List, Optional
import signal
import threading import threading
from http.server import HTTPServer, BaseHTTPRequestHandler
from dataclasses import dataclass from dataclasses import dataclass
# ログ設定 # ログ設定
@@ -28,6 +28,25 @@ logging.basicConfig(
) )
logger = logging.getLogger(__name__) 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 @dataclass
class EmailMessage: class EmailMessage:
"""メールメッセージのデータクラス""" """メールメッセージのデータクラス"""
@@ -445,9 +464,6 @@ class EmailMonitor:
logger.debug(f"{self.check_interval}秒後に次のチェックを実行します") logger.debug(f"{self.check_interval}秒後に次のチェックを実行します")
time.sleep(self.check_interval) time.sleep(self.check_interval)
except KeyboardInterrupt:
logger.info("キーボード割り込みを受信しました")
break
except Exception as e: except Exception as e:
logger.error(f"監視ループでエラーが発生しました: {str(e)}") logger.error(f"監視ループでエラーが発生しました: {str(e)}")
self.disconnect_from_email() 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.SIGINT, lambda s, f: signal_handler(s, f, monitor))
signal.signal(signal.SIGTERM, 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: try:
# 監視開始 run_http_server()
monitor.start_monitoring()
except Exception as e: except Exception as e:
logger.error(f"アプリケーションエラー: {str(e)}") logger.error(f"アプリケーションエラー: {str(e)}")
sys.exit(1) sys.exit(1)
+29
View File
@@ -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