アーキテクチャ
Dewyは、異なるユースケースに対応する2つのデプロイメントモードを提供します:
- Supervisor型(
server/assetsコマンド): Dewyがプロセススーパーバイザーとして動作し、アプリケーションを子プロセスとして管理。グレースフルリスタート機能を備えています。 - プロキシ型(
containerコマンド): Dewyが内蔵TCPリバースプロキシを実行し、Docker/Podmanコンテナをローリングアップデートでデプロイします。
インターフェース
Dewyは、プラグガブルな抽象化として、Registry, Artifact, Cache, Notifierの4つのインターフェースから構成されています。
- Registry: バージョン管理(GitHub Releases, S3, GCS, OCI Registry, gRPC)
- Artifact: バイナリ/イメージ取得(対応するRegistry形式)
- Cache: ダウンロード済みファイル管理(File, Memory, Consul, Redis)
- Notifier: デプロイ通知(Slack, Mail)
デプロイプロセス
以下はDewyのデプロイプロセスと構成を図にしたものです。
- Registryは、指定したレジストリをポーリングし、アプリケーションの最新バージョンを検知する
- Artifactは、指定したアーティファクトストアからアーティファクトをダウンロードし展開する
- Cacheは、最新のバージョンとアーティファクトを保存する
- Dewyは、新しいバージョンのアプリケーションの子プロセスを作り、リクエストを新しいアプリケーションでの処理を開始する
- Registryは、何時どこで何をデプロイした情報をファイルとして保存する
- Notifierは、指定した通知先に通知を行う
Supervisor型 (server / assets)
Supervisor型では、Dewyがメインプロセスとなり、アプリケーションを子プロセスとして起動します。このモードは、VMやベアメタルサーバー上でバイナリアプリケーションを直接デプロイする場合に最適です。
グレースフルリスタート
server コマンドでは、Dewyはserver-starterを使用してグレースフルリスタートを実現します。新しいバージョンが検出されると:
- DewyがSIGHUPを送信してグレースフルリスタートをトリガー
- 新しいアプリケーションプロセスが起動し、リスニングソケットを継承
- 古いプロセスは既存のリクエスト処理を完了して終了
- ゼロダウンタイムデプロイが実現
プロキシ型 (container)
プロキシ型では、DewyがDockerまたはPodmanを使用してコンテナ化されたアプリケーションを管理します。内蔵のTCPリバースプロキシがコンテナバックエンドにトラフィックをルーティングし、ゼロダウンタイムのローリングアップデートを可能にします。
コンポーネント
- TCPリバースプロキシ: 設定されたポートでリッスンし、ラウンドロビンでコンテナバックエンドにトラフィックを分散
- コンテナランタイム: DockerまたはPodmanコンテナを管理(pull, run, stop, remove)
- ヘルスチェッカー: プロキシバックエンドに追加する前にコンテナの正常性を検証
- Admin API: 監視と管理用のHTTPエンドポイントを提供(例:
dewy container list)
デプロイプロセス
- レジストリチェック: OCIレジストリ(GitHub Container Registry, Docker Hub等)をポーリングして新しいイメージバージョンを検出
- イメージPull: 新しいコンテナイメージをダウンロード
- ローリングアップデート: 各レプリカに対して:
- ランダムなlocalhostポートマッピングで新しいコンテナを起動
- ヘルスチェック(設定されている場合)の完了を待機
- 新しいコンテナをプロキシバックエンドに追加
- トラフィック切り替え: 新しいコンテナがプロキシ経由でトラフィックを受信開始
- 古いコンテナのクリーンアップ: 各古いコンテナに対して:
- プロキシバックエンドから削除
- 処理中のリクエストが完了するまでドレイン時間を待機
- 古いコンテナを停止・削除
- イメージクリーンアップ: 最新のバージョンのみを保持し、古いイメージを削除
ゼロダウンタイムアップデート
ローリングアップデート戦略によりゼロダウンタイムデプロイを保証:
- 新しいコンテナはトラフィックを受け取る前に完全に正常な状態
- 古いコンテナはドレインされるまでリクエストを処理し続ける
- TCPプロキシがトラフィック切り替えをシームレスに処理
- 新しいコンテナがヘルスチェックに失敗した場合、自動的にロールバック
ポートマッピング
コンテナはlocalhostのみのポートバインディング(127.0.0.1::containerPort)で起動され、ランダムなエフェメラルポートが割り当てられます。このアプローチにより:
- 複数レプリカ間のポート競合を回避
- コンテナトラフィックをlocalhostに分離(プロキシ経由でのみアクセス可能)
- プロキシがすべての外部アクセスを管理
比較
| 機能 | Supervisor型 | プロキシ型 |
|---|---|---|
| 対象 | バイナリアプリケーション | コンテナイメージ |
| デプロイ単位 | アーカイブ(tar.gz, zip) | OCIイメージ |
| プロセス管理 | 子プロセス | コンテナランタイム |
| ロードバランシング | 外部(または単一プロセス) | 内蔵TCPプロキシ |
| グレースフルリスタート | SIGHUP + server-starter | ローリングアップデート |
| レプリカ | 単一プロセス | 複数コンテナ |
| ヘルスチェック | なし | HTTPエンドポイント |
このように、Dewyは中央のレジストリと通信し、バイナリアプリケーションとコンテナ化されたワークロードの両方に対して、いわゆるプル型のデプロイを実現します。