{"id":15356834,"url":"https://github.com/linyows/dewy","last_synced_at":"2026-03-14T09:01:27.633Z","repository":{"id":51086404,"uuid":"117443343","full_name":"linyows/dewy","owner":"linyows","description":"Dewy enables declarative deployment of applications in non-Kubernetes environments.","archived":false,"fork":false,"pushed_at":"2025-02-18T09:46:44.000Z","size":3471,"stargazers_count":36,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-27T23:33:00.558Z","etag":null,"topics":["continuous-delivery","deployment","dewy","goapps","hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linyows.png","metadata":{"files":{"readme":"README.ja.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-14T15:44:41.000Z","updated_at":"2025-02-18T09:46:09.000Z","dependencies_parsed_at":"2024-03-04T00:34:28.388Z","dependency_job_id":"23e8ebe0-697c-47f5-966a-2fb94193b15d","html_url":"https://github.com/linyows/dewy","commit_stats":{"total_commits":413,"total_committers":3,"mean_commits":"137.66666666666666","dds":"0.10653753026634383","last_synced_commit":"2ef051ee9ffdcec2a765a51ece720c56df115d4e"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyows%2Fdewy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyows%2Fdewy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyows%2Fdewy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linyows%2Fdewy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linyows","download_url":"https://codeload.github.com/linyows/dewy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248860006,"owners_count":21173344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["continuous-delivery","deployment","dewy","goapps","hacktoberfest"],"created_at":"2024-10-01T12:30:10.134Z","updated_at":"2026-03-14T09:01:27.620Z","avatar_url":"https://github.com/linyows.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"right\"\u003e\u003ca href=\"https://github.com/linyows/dewy/blob/main/README.md\"\u003eEnglish\u003c/a\u003e | 日本語\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://dewy.linyo.ws\"\u003e\n    \u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/linyows/dewy/blob/main/misc/dewy-dark-bg.svg?raw=true\"\u003e\n      \u003cimg alt=\"Dewy\" src=\"https://github.com/linyows/dewy/blob/main/misc/dewy.svg?raw=true\" width=\"240\"\u003e\n    \u003c/picture\u003e\n    \u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eDewy\u003c/strong\u003e enables declarative deployment of applications in non-Kubernetes environments.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/linyows/dewy/actions/workflows/build.yml\"\u003e\n    \u003cimg alt=\"GitHub Workflow Status\" src=\"https://img.shields.io/github/actions/workflow/status/linyows/dewy/build.yml?branch=main\u0026style=for-the-badge\u0026labelColor=666666\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/linyows/dewy/releases\"\u003e\n    \u003cimg src=\"http://img.shields.io/github/release/linyows/dewy.svg?style=for-the-badge\u0026labelColor=666666\u0026color=DDDDDD\" alt=\"GitHub Release\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"http://godoc.org/github.com/linyows/dewy\"\u003e\n    \u003cimg src=\"http://img.shields.io/badge/go-docs-blue.svg?style=for-the-badge\u0026labelColor=666666\u0026color=DDDDDD\" alt=\"Go Documentation\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://deepwiki.com/linyows/dewy\"\u003e\n    \u003cimg src=\"http://img.shields.io/badge/deepwiki-docs-purple.svg?style=for-the-badge\u0026labelColor=666666\u0026color=DDDDDD\" alt=\"Deepwiki Documentation\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nDewyは、Kubernetes以外の環境でアプリケーションを宣言的にデプロイするソフトウェアです。\nバイナリアプリケーション（主にGo）、静的アセット、コンテナ化されたアプリケーションという複数のデプロイメントモードをサポートします。\nDewyは、指定する「レジストリ」をポーリングし、セマンティックバージョニングで管理された最新のバージョンを検知すると、指定する「アーティファクト」ストアまたはOCIレジストリから自動的にデプロイを行います。\nコンテナ化されたアプリケーションの場合、Dewyはヘルスチェック付きのゼロダウンタイムローリングアップデートデプロイメントを提供します。\nDewyは、レジストリ、アーティファクトストア、キャッシュストア、通知の４つのインターフェースから構成されています。\n以下はDewyのデプロイプロセスと構成を図にしたものです。\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Dewyのデプロイプロセスとアーキテクチャ\" src=\"https://github.com/linyows/dewy/blob/main/misc/dewy-architecture.svg?raw=true\" width=\"640\"/\u003e\n\u003c/p\u003e\n\n主な機能\n--\n\n- 宣言的プル型デプロイメント\n- 複数のデプロイメントモード（バイナリ、アセット、コンテナイメージ）\n- コンテナ向けゼロダウンタイムローリングアップデートデプロイメント\n- グレースフルリスタート\n- 選択可能なレジストリとアーティファクトストア\n- Docker Hub、GHCR、GAR、ECRなどのOCIレジストリをサポート\n- デプロイ状況の通知\n- JSON形式対応の構造化ログ\n- OpenTelemetryベースのオブザーバビリティ（Prometheusメトリクス + OTLPエクスポート）\n- オーディットログ\n\n使いかた\n--\n\n### Serverコマンド\n\n次のServerコマンドは、registryにgithub releasesを使い、8000番ポートでサーバ起動し、ログレベルをinfoに設定し、slackに通知する例です。\n\n```sh\n$ dewy server --registry ghr://linyows/myapp \\\n  --notifier slack://general?title=myapp -p 8000 -l info -- /opt/myapp/current/myapp\n```\n\n### Assetsコマンド\n\nHTMLやCSS、JavaScriptなどの静的ファイルをデプロイします：\n\n```sh\n$ dewy assets --registry ghr://linyows/frontend -d /var/www/html -l info\n```\n\n### Containerコマンド\n\nゼロダウンタイムローリングアップデートデプロイメントでコンテナ化されたアプリケーションをデプロイします：\n\n```sh\n$ dewy container --registry img://ghcr.io/linyows/myapp \\\n  --container-port 8080 --health-path /health --replicas 3 -l info\n```\n\nレジストリと通知の指定はurlを模擬した構成になっています。urlのschemeにあたる箇所はレジストリや通知の名前です。レジストリの項目で詳しく解説します。\n\nコマンド\n--\n\nDewyには、Server、Assets、Containerの3つの主要なコマンドがあります。\nServerはServer Application用でApplicationのプロセス管理を行い、Applicationのバージョンを最新に維持します。\nAssetsはhtmlやcssやjsなど、静的ファイルのバージョンを最新に維持します。\nContainerはコンテナ化されたアプリケーションのゼロダウンタイムデプロイメントを実現し、ローリングアップデートをサポートします。\n\n- server\n- assets\n- container\n\nインターフェース\n--\n\nDewyにはいくつかのインターフェースがあり、それぞれ選択可能な実装を持っています。以下、各インターフェースの説明をします。（もしインターフェースで欲しい実装があればissueを作ってください）\n\n- Registry\n- Artifact\n- Cache\n- Notifier\n\nRegistry\n--\n\nレジストリは、アプリケーションやファイルのバージョンを管理するインターフェースです。\nレジストリは、Github Releases、AWS S3、Google Cloud Storage、OCIレジストリ（Docker Hub、GHCR、GAR、ECR）、GRPCから選択できます。\n\n#### 共通オプション\n\n共通オプションは以下の2つです。\n\nOption　　　　　　　　　　 | Type   | Description\n---         | ---    | ---\npre-release | bool   | セマンティックバージョニングにおけるプレリリースバージョンを含める場合は `true` を設定します\nartifact    | string | アーティファクトのファイル名が `name_os_arch.ext` のようなフォーマットであれば Dewy パターンマッチすることができますが、そうでない場合は明示的に指定してください\n\n\u003e [!IMPORTANT]\n\u003e **アーティファクトパターンマッチング**: `artifact` オプションが指定されていない場合、Dewyはファイル名から現在のOSとアーキテクチャをマッチングして自動的にアーティファクトを選択します。OS（`linux`、`darwin`/`macos`、`windows`）とアーキテクチャ（`amd64`/`x86_64`、`arm64`など）に対して大文字小文字を区別しない部分文字列マッチングを行います。現在のOSとアーキテクチャの両方を含む最初のアーティファクトが選択されます。複数のアーティファクトがマッチする場合や特定のアーティファクトが必要な場合は、`artifact` パラメータで明示的に指定してください。\n\n### Github Releases\n\nGithub Releasesをレジストリに使う場合は以下の設定をします。また、Github APIを利用するために必要な環境変数の設定が必要です。\n\n```sh\n# 構造\nghr://\u003cowner-name\u003e/\u003crepo-name\u003e?\u003coptions: pre-release, artifact\u003e\n\n# 例\n$ export GITHUB_TOKEN=****.....\n$ dewy --registry ghr://linyows/myapp?pre-release=true\u0026artifact=dewy.tar ...\n```\n\n\u003e [!NOTE]\n\u003e CI/CDビルド中の誤ったアラートを防ぐため、Dewyは新しく作成されたリリースに対して「artifact not found」エラーを報告する前に自動的に30分間待機します。この猶予期間により、GitHub Actionsやその他のCIシステムがリリース作成後にアーティファクトをビルドしてアップロードする時間を確保できます。\n\n### AWS S3\n\nAWS S3をレジストリに使う場合は以下の設定をします。\nオプションとしては、regionの指定とendpointの指定があります。endpointは、S3互換サービスの場合に指定してください。\nまた、AWS APIを利用するために必要な環境変数の設定が必要です。\n\n```sh\n# 構造\ns3://\u003cregion-name\u003e/\u003cbucket-name\u003e/\u003cpath-prefix\u003e?\u003coptions: endpoint, pre-release, artifact\u003e\n\n# 例\n$ export AWS_ACCESS_KEY_ID=****.....\n$ export AWS_SECRET_ACCESS_KEY=****.....\n$ dewy --registry s3://jp-north-1/dewy/foo/bar/myapp?endpoint=https://s3.isk01.sakurastorage.jp ...\n```\n\nS3でのオブジェクトのパスは、`\u003cprefix\u003e/\u003csemver\u003e/\u003cartifact\u003e` の順になるようにしてください。例えば次の通り。\n\n```sh\n# \u003cprefix\u003e/\u003csemver\u003e/\u003cartifact\u003e\nfoo/bar/baz/v1.2.4-rc/dewy-testapp_linux_x86_64.tar.gz\n                   /dewy-testapp_linux_arm64.tar.gz\n                   /dewy-testapp_darwin_arm64.tar.gz\nfoo/bar/baz/v1.2.3/dewy-testapp_linux_x86_64.tar.gz\n                  /dewy-testapp_linux_arm64.tar.gz\n                  /dewy-testapp_darwin_arm64.tar.gz\nfoo/bar/baz/v1.2.2/dewy-testapp_linux_x86_64.tar.gz\n                  /dewy-testapp_linux_arm64.tar.gz\n                  /dewy-testapp_darwin_arm64.tar.gz\n```\n\nDewyは、 `aws-sdk-go-v2` を使っているので regionやendpointも環境変数で指定することもできます。\n\n```sh\n$ export AWS_ENDPOINT_URL=\"http://localhost:9000\"\n```\n\n### Google Cloud Storage\n\nGoogle Cloud Storageをレジストリに使う場合は以下の設定をします。Google Cloudの認証情報は、サービスアカウントキーやGoogle Cloud SDKでサポートされている他の認証方法で設定する必要があります。\n\n```sh\n# 書式\n# gs://\u003cproject-id\u003e/\u003cbucket-name\u003e/\u003cpath-prefix\u003e?\u003coptions: pre-release, artifact\u003e\n\n# 例\n$ export GOOGLE_APPLICATION_CREDENTIALS=\"/path/to/service-account.json\"\n$ dewy --registry gs://my-project/dewy-bucket/foo/bar/myapp ...\n```\n\nGoogle Cloud Storageでのオブジェクトパスは、S3と同じ順序に従ってください: `\u003cprefix\u003e/\u003csemver\u003e/\u003cartifact\u003e`。例：\n\n```sh\n# \u003cprefix\u003e/\u003csemver\u003e/\u003cartifact\u003e\nfoo/bar/baz/v1.2.4-rc/dewy-testapp_linux_x86_64.tar.gz\n                   /dewy-testapp_linux_arm64.tar.gz\n                   /dewy-testapp_darwin_arm64.tar.gz\nfoo/bar/baz/v1.2.3/dewy-testapp_linux_x86_64.tar.gz\n                  /dewy-testapp_linux_arm64.tar.gz\n                  /dewy-testapp_darwin_arm64.tar.gz\nfoo/bar/baz/v1.2.2/dewy-testapp_linux_x86_64.tar.gz\n                  /dewy-testapp_linux_arm64.tar.gz\n                  /dewy-testapp_darwin_arm64.tar.gz\n```\n\nDewyはGoogle Cloud Storage Go クライアントライブラリを使用するため、認証はサービスアカウントキー、ワークロードアイデンティティ、デフォルトアプリケーション認証情報など、標準的なGoogle Cloud認証方法に従います。\n\n### GRPC\n\nGRPCをレギストリに使う場合は以下の設定をします。GRPCを使う場合、アーティファクトのURLをユーザが用意するGRPCサーバ側が決めるので、pre-releaseやartifactを指定できません。\nGRPCは、インターフェースを満たすサーバを自作することができ、動的にアーティファクトのURLやレポートをコントロールしたい場合にこのレジストリを使います。\n\n```sh\n# 構造\ngrpc://\u003cserver-host\u003e?\u003coptions: no-tls\u003e\n\n# 例\n$ dewy grpc://localhost:9000?no-tls=true\n```\n\n### OCI Registry\n\nOCI準拠のコンテナレジストリは、`dewy container`コマンドでコンテナイメージのデプロイメントに使用できます。サポートされているレジストリには、Docker Hub、GitHub Container Registry（GHCR）、Google Artifact Registry（GAR）、AWS Elastic Container Registry（ECR）があります。\n\n\u003e [!IMPORTANT]\n\u003e **監査ログの制限**: OCIレジストリでは監査ログはサポートされていません。\n\n```sh\n# 構造\n# img://\u003cregistry-host\u003e/\u003cimage-name\u003e?\u003coptions: pre-release\u003e\n\n# 例\n$ dewy container --registry img://ghcr.io/owner/app --container-port 8080\n$ dewy container --registry img://docker.io/myuser/myapp --container-port 3000\n$ dewy container --registry img://gcr.io/my-project/myapp --container-port 8080\n```\n\nOCIレジストリの認証は、Dockerの認証システムを通じて設定します：\n\n```sh\n# docker loginを使用\n$ docker login ghcr.io\n$ dewy container --registry img://ghcr.io/myorg/private-app\n```\n\n`dewy container`コマンドは、ゼロダウンタイムローリングアップデートデプロイメントを提供します：\n\n1. Dewyは指定された間隔でレジストリの新しいタグをポーリングします\n2. セマンティックバージョニングに準拠した新しいタグが自動的に検出されます\n3. 新しいコンテナイメージがプルされ、新しいコンテナが起動されます\n4. ヘルスチェックが実行されます（`--health-path`が指定されている場合）\n5. ネットワークエイリアスを更新することで、トラフィックが新しいコンテナに切り替えられます\n6. 古いコンテナはドレイン期間中も稼働し続け、その後削除されます\n\nコンテナ固有のオプション：\n\nOption | Type | Description\n---    | ---  | ---\ncontainer-port | int | コンテナがリッスンするポート（必須）\nhealth-path | string | ヘルスチェック用のHTTPパス（例：/health）\nhealth-timeout | int | ヘルスチェックのタイムアウト秒数（デフォルト：30）\ndrain-time | int | 古いコンテナを削除する前のドレイン期間の秒数（デフォルト：30）\nreplicas | int | コンテナのレプリカ数（デフォルト：1）\n\nArtifact\n--\n\nアーティファクトは、アプリケーションやファイルそのものを管理するインターフェースです。\nアーティファクトの実装には、Github ReleaseとAWS S3とGoogle Cloud Storageがありますが、レジストリをGRPCに選択しなければ、自動的にレジストリと同じになります。\n\nCache\n--\n\nキャッシュは、現在のバージョンやアーティファクトをDewyが保持するためのインターフェースです。キャッシュの実装には、ファイルシステムとメモリとHashicorp ConsulとRedisがあります。\n\nNotifier\n--\n\n通知は、デプロイの状態を通知するインターフェースです。通知は、Slack、メール（SMTP）から選択できます。\n\n\u003e [!IMPORTANT]\n\u003e **エラー通知制限**: Dewyは継続的な障害時のスパム防止のため、エラー通知を自動的に制限します。3回のエラー通知後、正常に復旧するまで通知が抑制され、復旧時に通知制限は自動的にリセットされます。\n\n### Quiet Mode\n\n通知URLに `quiet=true` を追加すると、冗長な通知（開始、ダウンロード、フック成功）を抑制し、重要な通知（デプロイ成功、エラー、フック失敗）のみ送信します。\n\n```sh\n$ dewy --notifier \"slack://general?title=myapp\u0026quiet=true\" ...\n```\n\n### Slack\n\nSlackを通知に使う場合は以下の設定をします。オプションには、通知に付加する `title` と そのリンクである `url` が設定できます。リポジトリ名やそのURLを設定すると良いでしょう。\nまた、Slack APIを利用するために必要な環境変数の設定が必要です。\n[Slack Appを作成](https://api.slack.com/apps)し、 OAuth Tokenを発行して設定してください。OAuthのScopeは `chat:write` と `chat:write.customize` が必要です。また、通知先のチャンネルには事前にSlack Appをinviteしておく必要があります。\n\n```sh\n# 構造\nslack://\u003cchannel-name\u003e?\u003coptions: title, url, quiet\u003e\n\n# 例\n$ export SLACK_TOKEN=****.....\n$ dewy --notifier slack://dewy?title=myapp\u0026url=https://dewy.liny.ws ...\n```\n\n### Mail\n\nMailを通知に使う場合は以下の設定をします。SMTP設定はURLパラメータまたは環境変数で指定できます。Gmailを使用する場合は、アプリパスワードを使用する必要があります。\n\n```sh\n# 構造\nmail://\u003csmtp-host\u003e:\u003cport\u003e/\u003crecipient-mail\u003e?\u003coptions: username, password, from, subject, tls, quiet\u003e\nsmtp://\u003csmtp-host\u003e:\u003cport\u003e/\u003crecipient-mail\u003e?\u003coptions: username, password, from, subject, tls, quiet\u003e\n\n# URLパラメータを使用する例\n$ dewy --notifier mail://smtp.gmail.com:587/recipient@example.com?username=sender@gmail.com\u0026password=app-password\u0026from=sender@gmail.com\u0026subject=Dewy+Deployment ...\n\n# 環境変数を使用する例\n$ export MAIL_USERNAME=sender@gmail.com\n$ export MAIL_PASSWORD=app-password\n$ export MAIL_FROM=sender@gmail.com\n$ dewy --notifier mail://smtp.gmail.com:587/recipient@example.com ...\n```\n\n#### メール設定オプション\n\nオプション | タイプ | 説明                   | デフォルト値\n---        | ---    | ---                    | ---\nusername   | string | SMTP認証ユーザー名     | (MAIL_USERNAME環境変数から取得)\npassword   | string | SMTP認証パスワード     | (MAIL_PASSWORD環境変数から取得)\nfrom       | string | 送信者メールアドレス   | (MAIL_FROM環境変数から取得、または'username'と同じ値を使用)\nto         | string | 受信者メールアドレス   | (URLパスから抽出)\nsubject    | string | メール件名             | \"Dewy Notification\"\ntls        | bool   | TLS暗号化を使用        | true\nhost       | string | SMTPサーバーホスト名   | (URLから抽出)\nport       | int    | SMTPサーバーポート番号 | 587\n\nリリース管理\n--\n\nDewyはローカルファイルシステム内でリリースを自動管理します：\n\n- **リリース保存**: 各デプロイは`releases/\u003ctimestamp\u003e/`ディレクトリに保存されます\n- **現在リンク**: `current`シンボリックリンクが常に最新デプロイバージョンを指します\n- **自動クリーンアップ**: 最新7リリースのみ保持され、古いリリースは自動削除されます\n- **ディレクトリ構造**:\n  ```\n  /opt/myapp/\n  ├── current -\u003e releases/20240315T143022Z/\n  ├── releases/\n  │   ├── 20240315T143022Z/    # 最新\n  │   ├── 20240314T091534Z/\n  │   ├── 20240313T172145Z/\n  │   └── ...                  # 最大7リリース\n  ```\n\nセマンティックバージョニング\n--\n\nDewyは、セマンティックバージョニングに基づいてバージョンのアーティファクトの新しい古いを判別しています。\nそのため、ソフトウェアのバージョンをセマンティックバージョニングで管理しなければなりません。\n\n詳しくは https://semver.org/lang/ja/\n\n```txt\n# プレリリースバージョン：\nv1.2.3-rc\nv1.2.3-beta.2\n\n# ビルドメタデータ（デプロイメントスロット用）：\nv1.2.3+blue\nv1.2.3+green\nv1.2.3-rc.1+blue\n```\n\n### プレリリースとステージング\n\nセマンティックバージョニングには、プレリリースという考え方があります。バージョンに対してハイフンをつけてsuffixを付加したものがプレリリースバージョンになります。ステージング環境では、registryのオプションに `pre-release=true`を追加することで、プレリリースバージョンがデプロイされるようになります。\n\n```sh\n# プロダクション環境（安定版のみ）\n$ dewy --registry ghr://linyows/myapp ...\n\n# ステージング環境（プレリリース版を含む）\n$ dewy --registry ghr://linyows/myapp?pre-release=true ...\n```\n\n### ビルドメタデータとBlue/Greenデプロイメント\n\nセマンティックバージョニングでは、`+`記号で付加するビルドメタデータもサポートされています。Dewyはこれを**デプロイメントスロット**管理に使用し、Blue/Greenデプロイメントパターンを実現します。\n\n**仕組み:**\n- リリースにビルドメタデータでデプロイメントスロットを指定してタグ付け: `v1.2.3+blue`, `v1.2.3+green`\n- Dewyインスタンスを `--slot` オプションで起動し、デプロイ対象のスロットを指定\n- 各Dewyインスタンスは、設定されたスロットに一致するバージョンのみをデプロイ\n\n```sh\n# Blue環境\n$ dewy server --registry ghr://linyows/myapp --slot blue -- /opt/myapp/current/myapp\n\n# Green環境\n$ dewy server --registry ghr://linyows/myapp --slot green -- /opt/myapp/current/myapp\n```\n\n**Blue/Greenデプロイメントのワークフロー:**\n\n```sh\n# 1. 初期状態: BlueとGreen両方がv1.0.0で稼働\ngh release create v1.0.0+blue ...\ngh release create v1.0.0+green ...\n\n# 2. まずGreenに新バージョンをデプロイ\ngh release create v1.1.0+green ...\n# → Greenインスタンスのみがv1.1.0に更新される\n\n# 3. Greenが正常に動作していることを確認\n\n# 4. トラフィックをGreenに切り替え（ロードバランサー経由）\n\n# 5. Blueも同じバージョンに更新\ngh release create v1.1.0+blue ...\n# → Blueインスタンスがv1.1.0に更新される\n```\n\n**プレリリースとの組み合わせ:**\n\nビルドメタデータはプレリリースバージョンと組み合わせて使用できます:\n\n```sh\nv1.2.3-rc.1+blue   # Blueスロット用のプレリリース\nv1.2.3+green       # Greenスロット用の安定版リリース\n```\n\n\u003e [!NOTE]\n\u003e `--slot` を指定しない場合、Dewyはビルドメタデータに関係なくすべてのバージョンをデプロイし、後方互換性を維持します。\n\nデプロイワークフロー\n--\n\n次のシーケンス図は、ポーリングからサーバー再起動までのDewyのデプロイワークフローを示しています：\n\n```mermaid\nsequenceDiagram\n    participant S as Scheduler\n    participant D as Dewy\n    participant R as Registry\n    participant A as Artifact Store\n    participant C as Cache\n    participant F as File System\n    participant H as Hooks\n    participant App as Application\n    participant N as Notifier\n\n    Note over S,N: Scheduled Deployment Cycle\n\n    S-\u003e\u003eD: Run() - Start deployment check\n    D-\u003e\u003eR: Current() - Get latest version\n    R--\u003e\u003eD: {ID, Tag, ArtifactURL}\n\n    D-\u003e\u003eC: Read(\"current\") - Check current version\n    D-\u003e\u003eC: List() - Get cached artifacts\n    C--\u003e\u003eD: Cached version info\n\n    alt Version changed or not cached\n        D-\u003e\u003eA: Download(ArtifactURL)\n        A--\u003e\u003eD: Artifact binary data\n        D-\u003e\u003eC: Write(cacheKey, artifact)\n        D-\u003e\u003eC: Write(\"current\", cacheKey)\n        Note over D,C: Cache: v1.2.3--app_linux_amd64.tar.gz\n    else Version unchanged\n        Note over D: Skip deployment - already current\n    end\n\n    D-\u003e\u003eN: Send(\"Downloaded artifact for v1.2.3\")\n\n    Note over D,App: Deployment Process\n\n    D-\u003e\u003eH: execHook(BeforeDeployHook)\n    H--\u003e\u003eD: Success/Failure\n\n    alt Before hook failed\n        D-\u003e\u003eN: SendError(\"Before hook failed\")\n        Note over D: Abort deployment\n    else Before hook succeeded\n        D-\u003e\u003eF: ExtractArchive(cache → releases/timestamp/)\n        D-\u003e\u003eF: Remove old symlink\n        D-\u003e\u003eF: Symlink(releases/timestamp/ → current)\n\n        alt Server Application\n            D-\u003e\u003eApp: Start/Restart server process\n            App--\u003e\u003eD: Process started\n            D-\u003e\u003eN: Send(\"Server restarted for v1.2.3\")\n        end\n\n        D-\u003e\u003eH: execHook(AfterDeployHook)\n        H--\u003e\u003eD: Success/Failure (logged only)\n\n        D-\u003e\u003eR: Report({ID, Tag}) - Audit log\n        D-\u003e\u003eF: keepReleases() - Clean old releases\n\n        Note over D,N: Success - Reset error count\n        D-\u003e\u003eN: ResetErrorCount()\n    end\n\n    Note over S,N: Cycle repeats every interval (default: 10s)\n```\n\n### 主なワークフローポイント\n\n- **ポーリング**: Dewyは設定可能な間隔でレジストリを継続的にポーリングします\n- **バージョン検出**: セマンティックバージョニングを使用して新しいリリースを検出します\n- **キャッシュ**: ダウンロードはキャッシュされ、重複ダウンロードを回避します\n- **アトミックデプロイ**: 古いシンボリックリンクを削除し、新しいものをアトミックに作成します\n- **フック統合**: Before/afterフックがデプロイを中止またはカスタマイズできます\n- **エラーハンドリング**: 失敗したデプロイはエラー通知をトリガーします（制限付き）\n- **監査証跡**: 成功したデプロイはレジストリに報告されます\n\nデプロイフック\n--\n\nDewyはデプロイの前後にカスタムコマンドを実行できるフック機能をサポートしています。これらのフックは作業ディレクトリでシェル(`/bin/sh -c`)経由で実行され、全ての環境変数にアクセスできます。\n\n### フックオプション\n\n- `--before-deploy-hook`: デプロイ開始前にコマンドを実行\n- `--after-deploy-hook`: デプロイ成功後にコマンドを実行\n\n### 使用例\n\n```sh\n# デプロイ前にデータベースをバックアップ\n$ dewy server --registry ghr://myapp/api \\\n  --before-deploy-hook \"pg_dump mydb \u003e /backup/$(date +%Y%m%d_%H%M%S).sql\" \\\n  --after-deploy-hook \"echo 'デプロイ完了' | mail -s 'デプロイ成功' admin@example.com\" \\\n  -- /opt/myapp/current/myapp\n\n# デプロイ前にサービス停止、後に再起動\n$ dewy server --registry ghr://myapp/api \\\n  --before-deploy-hook \"systemctl stop nginx\" \\\n  --after-deploy-hook \"systemctl start nginx \u0026\u0026 systemctl reload nginx\" \\\n  -- /opt/myapp/current/myapp\n\n# デプロイ後にデータベースマイグレーション実行\n$ dewy assets --registry ghr://myapp/frontend \\\n  --after-deploy-hook \"/opt/myapp/current/migrate-db.sh\"\n```\n\n### フックの動作\n\n- **Before Hook**: before-deploy-hookが失敗するとデプロイは中止されます\n- **After Hook**: デプロイ成功後のみ実行されます。失敗してもデプロイは成功扱いになります\n- **実行環境**: フックは全ての環境変数を継承し、作業ディレクトリで実行されます\n- **ログ**: 全てのフック実行詳細（コマンド、stdout、stderr）がログに記録されます\n\n\u003e [!TIP]\n\u003e **よくある用途**\n\u003e - **データベース操作**: バックアップ、マイグレーション、スキーマ更新\n\u003e - **サービス管理**: 関連サービスの停止・開始\n\u003e - **キャッシュ管理**: キャッシュクリア、新デプロイの事前ウォームアップ\n\u003e - **通知**: 内蔵通知以外のカスタムアラート\n\u003e - **ヘルスチェック**: デプロイ成功の検証\n\u003e - **設定更新**: 動的な設定変更\n\n詳細設定\n--\n\nDewyは、拡張機能とモダンなインフラとのより良い統合のための詳細設定オプションを提供しています。\n\n### 構造化ログ\n\nDewyは、より良い可観測性とログ集約システムとの統合のために、JSON形式の構造化ログをサポートしています：\n\n```sh\n# JSON構造化ログを有効にする\n$ dewy server --registry ghr://linyows/myapp \\\n  --log-format json -l info -- /opt/myapp/current/myapp\n\n# デフォルトのテキスト形式（人間が読みやすい）\n$ dewy server --registry ghr://linyows/myapp \\\n  --log-format text -l info -- /opt/myapp/current/myapp\n```\n\nJSON形式では、解析とフィルタリングを簡単にする構造化されたフィールドが提供されます：\n- `time`: RFC3339タイムスタンプ\n- `level`: ログレベル（INFO、WARN、ERROR など）\n- `msg`: ログメッセージ\n- 操作に基づく追加のコンテキストフィールド\n\n### マルチポート対応\n\nDewyはサーバーアプリケーションの複数ポート設定をサポートしています：\n\n```sh\n# 複数ポート (カンマ区切り)\n$ dewy server --registry ghr://linyows/myapp \\\n  -p 8000,8001,8002 -- /opt/myapp/current/myapp\n\n# ポート範囲指定\n$ dewy server --registry ghr://linyows/myapp \\\n  -p 8000-8005 -- /opt/myapp/current/myapp\n```\n\nシグナルハンドリング\n--\n\nDewyはプロセス管理のための各種システムシグナルに対応しています：\n\n- **SIGHUP**: 無視（Dewyは動作を継続）\n- **SIGUSR1**: 手動サーバー再起動をトリガー\n- **SIGINT, SIGTERM, SIGQUIT**: グレースフルシャットダウンを開始\n- **内部SIGHUP**: サーバー再起動に内部的に使用\n\n### 手動サーバー再起動\n\nDewyを再起動せずにサーバーアプリケーションのみを手動で再起動できます：\n\n```sh\n# SIGUSR1を送信してサーバー再起動をトリガー\n$ kill -USR1 \u003cdewy-pid\u003e\n\n# systemdでDewyが管理されている場合\n$ systemctl kill -s USR1 dewy.service\n```\n\nシステム要件\n--\n\nDewyのデプロイには最小限のシステム要件があります：\n\n### ファイルシステム要件\n\n- **書き込み権限**: リリース管理のため作業ディレクトリへの書き込み権限が必要\n- **シンボリックリンクサポート**: `current`ポインタのためファイルシステムでシンボリックリンクサポートが必要\n- **一時ディレクトリ**: キャッシュストレージのためシステム一時ディレクトリへのアクセスが必要\n- **ディスク容量**: 7リリース分とキャッシュのための十分な容量（通常数百MB）\n\n### プロセス要件\n\n- **シェルアクセス**: フック実行のため`/bin/sh`が利用可能である必要\n- **ネットワークアクセス**: レジストリとアーティファクトストアへのアウトバウンド接続\n- **シグナルハンドリング**: プロセスがシステムシグナルを受信・処理できること\n\n\u003e [!NOTE]\n\u003e DewyはGoランタイム（コンパイル済み）以外の外部依存関係がない単一バイナリとして動作します。\n\nキャッシュ設定\n--\n\nDewyは冗長なネットワーク通信を避け、同じバージョンの不要なデプロイを防ぐため、ダウンロードしたアーティファクトを自動的にキャッシュします。デフォルトでは、システム再起動やクリーンアップ処理に耐えるよう永続的にキャッシュファイルが保存されます。\n\n### キャッシュディレクトリの優先順位\n\n1. **`DEWY_CACHEDIR`環境変数**（設定されている場合）- 最優先\n2. **`$PWD/.dewy/cache`** - カレントディレクトリ内のデフォルト場所\n\n権限問題でディレクトリ作成に失敗した場合、Dewyは自動的に一時ディレクトリにフォールバックします。\n\n### 使用例\n\n```sh\n# カスタムキャッシュディレクトリ（systemdサービス）\nEnvironment=DEWY_CACHEDIR=/var/cache/dewy\n\n# 永続ボリュームを使用するDocker\ndocker run -e DEWY_CACHEDIR=/app/cache -v /host/cache:/app/cache dewy\n```\n\nプロビジョニング\n--\n\nDewy用のプロビジョニングは、ChefとPuppetがあります。Ansibleがないので誰か作ってくれると嬉しいです。\n\n- Chef: https://github.com/linyows/dewy-cookbook\n- Puppet: https://github.com/takumakume/puppet-dewy\n\n背景\n--\n\nGoはコードを各環境に合わせたひとつのバイナリにコンパイルすることができます。\nKubernetesのようなオーケストレーターのある分散システムでは、Goで作られたアプリケーションのデプロイに困ることはないでしょう。\n一方で、コンテナではない単一の物理ホストや仮想マシン環境において、Goのバイナリをどうやってデプロイするかの明確な答えはないように思います。\n手元からscpやrsyncするshellを書いて使うのか、サーバ構成管理のansibleを使うのか、rubyのcapistranoを使うのか、方法は色々あります。\nしかし、複数人のチームで誰がどこにデプロイしたといったオーディットログや情報共有を考えると、そのようなユースケースにマッチするツールがない気がします。\n\nFAQ\n--\n\n質問されそうなことを次にまとめました。\n\n- Latestバージョンをレジストリから削除するとどうなりますか？\n\n    Dewyは削除後のLatestバージョンに変更します。リリースしたバージョンを削除したり上書きするのは望ましくありませんが、セキュリティの問題などやむを得ず削除するケースはあるかもしれません。\n    \n- オーディットログはどこにありますか？\n    \n    オーディットログはアーティファクトがホストされてるところにテキストファイルのファイル名として保存されます。現状は検索性がないです。何かいい方法が思いついたら変更するでしょう。\n    オーディットとは別で通知としてOTELなどのオブザーバービリティプロダクトに送ることも必要かもしれません。\n    \n- 複数Dewyからのポーリングによってレジストリのレートリミットにかかるのはどう対処できますか？\n    \n    キャッシュコンポーネントにHashicorp Consul やredisを使うと複数Dewyでキャッシュを共有出来るため、レジストリへの総リクエスト数は減るでしょう。その際は、レジストリTTLを適切な時間に設定するのがよいです。\n    なお、ポーリング間隔を長くするにはコマンドのオプションで指定できます。\n\n作者\n--\n\n[@linyows](https://github.com/linyows)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinyows%2Fdewy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinyows%2Fdewy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinyows%2Fdewy/lists"}