Keelson Deploy Spec
Spec version: 2026-10-06 / Raw text (AI向け): /ja/docs/reference/deploy-spec.txt
この文書は、Keelson にアプリをデプロイする際の対応ランタイム・制約・成立条件を定義する正本です。デプロイの可否判断は、この文書に従ってください。
クイックスタートや操作手順は デプロイする を参照してください。
デプロイ成功の定義
Section titled “デプロイ成功の定義”デプロイの完了は、ビルド結果だけでなく、アプリの種類に応じて確認してください。
| アプリの種類 | 完了時に確認する条件 |
|---|---|
| Web アプリ・ハイブリッド | ビルドが完了し、Web アプリのプロセスが起動してヘルスチェックに通過している。アプリ URL が発行され、アクセスできる。ハイブリッドでは静的ファイルも配信できる |
| 静的サイト・SPA | 配信するファイルのアップロード・公開が完了し、アプリ URL で配信できる。アプリのプロセス起動や Web のヘルスチェックは不要 |
| 定期実行専用アプリ | ビルドが完了し、定期実行のスケジュールと実行環境の設定が反映されている。Web のプロセス起動・ヘルスチェック・URL アクセスは確認対象外 |
Web アプリでは、ビルドが成功しても、起動に失敗した場合やヘルスチェックに通らない場合はデプロイ成功ではありません。アプリ URL は https://<ワークスペース slug>--<アプリ slug>.keelson.run です。
定期実行ジョブはデプロイ後、設定したスケジュールに従って実行されます。デプロイの成功だけでは、個々のジョブの処理が成功したことにはなりません。実行結果はジョブの履歴・ログで確認してください。
必須ファイル
Section titled “必須ファイル”すべてのデプロイには keelson.yaml が必要です。プロジェクトのルートディレクトリに配置します。
最小構成:
slug: my-appruntime: python-slimcommand: "python app.py"db: mode: nonedb と db.mode(libsql または none)は必須です。
Flask などのフレームワークを使うアプリには本番用サーバーが必要です。本番環境向けの設定を参照してください。
各フィールドの詳細は keelson.yaml リファレンス を参照してください。
配置リージョン
Section titled “配置リージョン”アプリは作成時に 1 つの論理リージョンへ配置されます。リージョンの論理キーは jp-tokyo(日本)と us-oregon(米国西海岸)です。現在新規作成に開放されているのは jp-tokyo のみで、us-oregon は定義済みですが未提供です。クラウド事業者のリージョン名ではなく、この表示名と論理キーを使います。
新規アプリでは keelson deploy --new --region <region>、または keelson.yaml のトップレベル region で配置先を指定できます。優先順位は CLI の指定、keelson.yaml、ワークスペースの既定リージョンの順です。
未提供のリージョン(現時点では us-oregon)を明示指定すると、別リージョンへ切り替えずに作成が拒否されます。指定がなければワークスペースの既定リージョン(日本)に配置されるため、ユーザーから求められない限り region は書かないでください。
リージョンはアプリ作成後に変更できません。既存アプリへ別のリージョンを指定しても移動は行われず、デプロイは拒否されます。別リージョンを使う場合は、新しいアプリとして作り直してください。
対応ランタイム
Section titled “対応ランタイム”Keelson は、以下のランタイム上でのみアプリを実行できます。
| ランタイム | 言語 | 用途 |
|---|---|---|
python-slim | Python | 軽量。API、テキスト処理、自動化など |
python-media | Python | メディア処理向け。画像・動画ライブラリを含む |
node-slim | Node.js | 軽量。Web アプリ、API など |
node-media | Node.js | メディア処理向け。画像処理ライブラリを含む |
go-slim | Go | 軽量 |
go-media | Go | メディア処理向け |
keelson.yaml の runtime フィールドで指定します。迷った場合は -slim から始め、メディア処理系ライブラリが必要になったら -media に切り替えてください。
slim と media の違い
Section titled “slim と media の違い”- slim — 言語ランタイムと標準ライブラリのみ。ビルドが速く、イメージサイズが小さい
- media — slim に加え、画像処理(Pillow、sharp 等)や動画処理に必要なシステムライブラリがプリインストールされている
対応フレームワーク
Section titled “対応フレームワーク”特定のフレームワークに依存しません。command で起動でき、HTTP サーバーとしてリクエストを受け付けるアプリであれば動作します。
例: FastAPI、Flask、Express、Next.js、Hono、Gin など。
非対応ランタイム
Section titled “非対応ランタイム”以下の言語・ランタイムはサポート対象外です。
- Ruby
- Java / Kotlin / Scala
- PHP
- Rust
- .NET / C#
- Elixir / Erlang
- Swift
非対応ランタイムを必要とする構成のままでは、Keelson へデプロイできません。
ビルド環境と実行環境の制約
Section titled “ビルド環境と実行環境の制約”Keelson は固定されたビルド環境・実行環境を提供します。アプリはその環境上でビルドおよび起動できる必要があります。
OS・アーキテクチャ
Section titled “OS・アーキテクチャ”- OS: Linux
- CPU: x86_64 (amd64)
root 権限
Section titled “root 権限”アプリは非 root ユーザーとして実行されます。sudo、apt-get install、システムレベルの変更は実行できません。
Dockerfile
Section titled “Dockerfile”リポジトリにあっても無視されます(Dockerfile があること自体はデプロイを妨げません)。Keelson はランタイムを選択し、command で起動する方式です。Dockerfile の代わりに keelson.yaml でランタイムと起動コマンドを指定します。
ファイルシステム
Section titled “ファイルシステム”| パス | 書き込み | 永続化 | 用途 |
|---|---|---|---|
/data | 不可(Keelson も作らず、アプリからも作れない) | 不可 | アプリは UID 1000 で実行され、root 所有の / 直下にはディレクトリを作れません |
アプリディレクトリ(/workspace) | 直下への新規作成は不可。既存ファイルやサブディレクトリは権限によって書き込み可能 | 不可 | ソースコード、依存関係 |
/tmp | 可(一時的) | 不可 | 一時ファイル |
ホームディレクトリ(/home/appuser) | Python・Node.js ランタイムでは可 | 不可 | ランタイムやツールのキャッシュ・設定 |
| その他 | パスの所有者・権限による | 不可 | 一時ファイルの保存には /tmp を使用 |
- 一時ファイルの書き込み先には
/tmpを使用してください。ローカルファイルへの書き込みは永続化されず、再起動やインスタンスの停止で失われます - Keelson が提供する永続ストレージは 3 種類です: Managed SQLite(
db.mode: libsql)、Files SDK(アプリ内部の非公開ファイル)、Media SDK(利用者に配信する画像・添付)。いずれもローカルのファイルパスとしては利用できません。外部のデータベースやストレージへの接続も可能です - ファイル SQLite は永続化されません。ファイル SQLite クライアントの使用はデプロイ時に検出され、
db.local_sqliteで一時用途と宣言しない限り拒否されます
- Web アプリは環境変数
PORTで指定したポートで HTTP リクエストを待ち受けてください 0.0.0.0で listen する必要があります。127.0.0.1やlocalhostではリクエストが届きません- HTTPS 終端は Keelson が行います。アプリは HTTP で listen してください
システムパッケージ
Section titled “システムパッケージ”Keelson は任意の OS パッケージ追加を前提とした環境ではありません。
-slimランタイムには最小限のシステムライブラリのみ含まれます-mediaランタイムには画像・動画処理に必要な一般的なライブラリが含まれます- それ以外のシステムライブラリが必要な場合、アプリは動作しない可能性があります
apt-get等によるパッケージ追加はできません(非 root のため)
プロセスモデル
Section titled “プロセスモデル”commandで起動した単一プロセスが基本です- systemd やデーモン管理は使えません
- 時刻で動く処理には
crons、リクエストの後に続く処理にはtasksを使ってください(バックグラウンドタスク。workersは廃止済みで、宣言するとデプロイが拒否されます)
依存関係に関する制約
Section titled “依存関係に関する制約”言語ランタイムが対応していても、依存ライブラリやシステム要件によってはデプロイできない場合があります。
言語パッケージマネージャで追加できる依存
Section titled “言語パッケージマネージャで追加できる依存”以下のパッケージマネージャで管理される純粋な言語パッケージは問題なくインストールできます。
- Python: pip(
requirements.txt) - Node.js: npm(
package.json) - Go: go mod(
go.mod)
依存関係はイメージのビルド時に Keelson が自動でインストールします(requirements.txt / pyproject.toml / package.json / go.mod を検出)。command ではインストールせず、アプリの起動だけを行ってください。command に pip install / npm install / go build があると、CLI の事前チェックが command_installs_dependencies でデプロイを止めます。
ビルドの制約: Node のロックファイルは package-lock.json のみ。公開レジストリのみ(private registry・認証付きインストール不可)。Go は CGO_ENABLED=0。ビルド対象は linux/amd64。ビルド時にシークレットは渡らない。上限 600 秒。
# Pythoncommand: "python app.py"
# Node.jscommand: "npm start"
# Go (Keelson 側で deploy 時に `./app` がビルドされます)command: "./app"ネイティブ依存が必要なパッケージ
Section titled “ネイティブ依存が必要なパッケージ”一部のパッケージは、C ライブラリやシステムレベルの依存を必要とします。
-mediaランタイムで動作するもの: Pillow、opencv-python、sharp、ffmpeg 関連など、一般的なメディア処理ライブラリ- 動作しない可能性があるもの: ランタイムに含まれないシステムライブラリに依存するパッケージ
サポート対象外になる典型パターン
Section titled “サポート対象外になる典型パターン”| パターン | 理由 |
|---|---|
apt-get install が必要 | 非 root でパッケージ追加不可 |
| 特殊な C ライブラリに依存 | ランタイムに含まれていない可能性 |
| GPU を前提とした推論ライブラリ | GPU インスタンス未提供 |
| データベースサーバー(PostgreSQL、MySQL、Redis) | 外部サービスとして接続は可能だが、Keelson 上での起動は不可 |
| systemd やバックグラウンドデーモン前提 | プロセスモデルが異なる |
デプロイモード
Section titled “デプロイモード”デプロイモードは、command と assets の設定に応じて自動的に決まります。CLI や API に表示される deploy_mode の値とアプリの種類の対応は、次のとおりです。
| アプリの種類 | deploy_mode の値 | command | assets | 説明 |
|---|---|---|---|---|
| Web アプリ | container | あり | なし | 通常のアプリデプロイ |
| 静的サイト | edge-static | なし | あり(fallback なし) | 静的ファイルのみ |
| SPA | edge-spa | なし | あり(fallback あり) | SPA(フォールバック付き) |
| ハイブリッド | hybrid | あり | あり(type: web を明示した場合は fallback 必須) | 静的ファイル + バックエンド API |
| 定期実行専用アプリ | container | なし | なし | crons が必須。Web サーバーを起動せず、定期実行ジョブのみを実行 |
定期実行専用アプリも deploy_mode は container ですが、Web アプリとは起動・完了確認の条件が異なります。
静的サイト・SPA では type: web を指定します。crons は併用できません。
予約 URL パス
Section titled “予約 URL パス”アプリのホスト上には、Keelson が内部処理に使うパスや、外部からのアクセスを拒否するパスがあります。次のパスをアプリの公開エンドポイントとして使わないでください。
/__keelsonとその配下は、すべての HTTP メソッドでプラットフォーム内部用です。プラットフォームが配信するアセット・ファイルダウンロード・内部エンドポイントに使われます。これらのパスにアプリのルートを定義しないでください。- ビルド出力の配信ルート直下に
__keelsonディレクトリを出力しないでください。 予約パスを含むビルドはビルド時にエラーコードreserved_path_conflictで拒否されます。ディレクトリ名を変更して再デプロイしてください。 GET /healthとGET /_healthは、ゲートウェイ経由ではプラットフォームが応答します。 アプリ側で同じパスを定義しても、その GET リクエストはアプリに届きません。/api/webhooks/emailと/api/webhooks/email-eventsは外部からアクセスできません。 エッジで拒否されるため、アプリ独自の Webhook には別のパスを使ってください。/api/mcpと/api/mcp/で始まるパスは、MCP のツール呼び出し専用です。 サーバー側のプログラムが動くアプリ(ハイブリッド構成のサーバー側を含む)では、keelson.yamlにmcp:を書いていなくても、MCP 経由以外のリクエストは 404 になります。このパスにはツールのハンドラ(POST /api/mcp/<ツール名>)以外のルートを置かないでください。静的に配信される部分には影響しません。mcp.enabled: trueのアプリでは、/mcp、/.well-known/oauth-protected-resource、/.well-known/oauth-protected-resource/mcpは Keelson が応答します。 これらのリクエストはアプリに届きません。詳しくは AI クライアントから使う(MCP)を参照してください。- 関連ルール:
auth.endpointsのパスは/__keelsonで始められません(/api/external/または/api/webhooks/で始める必要があります)。またslugに予約語は使えません。
/assets/*(Vite の既定出力先)、/files/*、/static/*、/uploads/* などはアプリで利用できます。/api/* も、上記の例外と認証設定のルールに従って利用できます。
フレームワーク静的パス衝突マトリクス(参考)
Section titled “フレームワーク静的パス衝突マトリクス(参考)”主要フレームワークが既定で出力する静的パスの参考一覧です。「確認済み」は本リポジトリで配信を確認したもの、「未検証」は既定パスからの推定です。未検証のフレームワークでは、実際のビルド出力と配信を確認してください。この表は /__keelson とのパス衝突の参考情報であり、フレームワークの対応可否を示すものではありません。
| フレームワーク | 既定の静的パス | /__keelson と衝突 | 状態 |
|---|---|---|---|
| Vite(Vue / Svelte / React / Solid / Preact) | /assets/* | しない | 確認済み |
| Remix v2 / VitePress | /assets/* | しない見込み | 未検証 |
| Angular | /assets/* | しない見込み | 未検証 |
| Next.js | /_next/static/* | しない見込み | 未検証 |
| Nuxt / SvelteKit / Astro | /_nuxt/* · /_app/* · /_astro/* | しない見込み | 未検証 |
| CRA / Django / Flask | /static/* | しない見込み | 未検証 |
環境変数とシークレット
Section titled “環境変数とシークレット”アプリの起動に必要な API キー、トークン、接続情報は、コードに直接埋め込まず、環境変数またはシークレットとして設定してください。
keelson.yamlのenv— バージョン管理に含めてよい値- コンソールのシークレット — API キーやトークンなど、コードに含めたくない値
必要な値が未設定の場合、アプリは正常に起動できないことがあります。
詳細は 環境変数とシークレット を参照してください。
Keelson が自動設定する環境変数
Section titled “Keelson が自動設定する環境変数”| 変数名 | 説明 |
|---|---|
PORT | アプリが listen するポート。読み取り専用で、自分で設定しない |
TZ | ワークスペースのタイムゾーン。ワークスペース作成時にブラウザから自動決定される |
KEELSON_MODE | Keelson 上で動作していることを示す印(値は keelson) |
KEELSON_APP_ID | アプリの内部 ID |
KEELSON_WORKSPACE_ID | ワークスペースの内部 ID |
KEELSON_TENANT_ID | KEELSON_WORKSPACE_ID の互換用別名(値は同じ) |
KEELSON_DEPLOY_ID | 現在のデプロイの内部 ID |
旧 tenant 名の変数も互換のため受け付けます。撤去時期は未定です。
db.mode: libsql のときは KEELSON_DB_URL / KEELSON_DB_AUTH_TOKEN(別名 TURSO_DATABASE_URL / TURSO_AUTH_TOKEN)が追加で注入されます。KEELSON_ で始まる名前はプラットフォーム予約で、env や secrets には使えません。
本番環境向けの設定
Section titled “本番環境向けの設定”Keelson のアプリは Cloud Run 上で動作し、通常運用中にも起動と停止が発生します。停止時にはプロセスへ SIGTERM が送られ、10 秒後に SIGKILL が送られます。本番用サーバーを使い、この時間内にドレイン処理を完了してください。
フレームワーク別の本番サーバ
Section titled “フレームワーク別の本番サーバ”Flask: app.run() は Werkzeug 開発サーバーを起動します。ローカル用の __main__ エントリーポイントの中に残すことはできますが、debug=False でもデプロイ先のサーバーにしてはいけません。gunicorn を requirements.txt に追加し、次のコマンドを使います。
command: "gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 --graceful-timeout 9 app:app"Keelson は 1 vCPU のため、worker は 1 にします。graceful timeout を 9 秒にすると、10 秒の SIGTERM 猶予内に収まります。app:app はプロジェクトのモジュール名とアプリケーションオブジェクト名に置き換えてください。
Django: gunicorn で Django を起動します。
command: "gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 --graceful-timeout 9 config.wsgi:application"DEBUGは既定で無効にします。DEBUG=Falseの場合、Django 自身は静的ファイルを配信しません。whitenoise をMIDDLEWAREに追加し、STATIC_ROOTを設定して、collectstatic済みの成果物を配信対象に含めてください。ALLOWED_HOSTS = ["*"]は維持してください。制限するとヘルスチェックが HTTP 400 になることがあります。config.wsgi:applicationはプロジェクトの WSGI モジュールに置き換えてください。
FastAPI / uvicorn: 0.0.0.0:$PORT にバインドし、worker 数は既定の 1 のままにします。
command: "uvicorn main:app --host 0.0.0.0 --port $PORT"--reload は使わないでください。ファイル監視がメモリを消費し、アプリが二重起動することがあります。main:app はプロジェクトのモジュール名とアプリケーションオブジェクト名に置き換えてください。
Next.js: 開発サーバーではなく、ビルド済みのアプリを起動します。
command: "npm run start"package script は次のように設定します。
"start": "next start -p $PORT"package.json に "start": "next dev" がある場合、回避策を加えるのではなく、その script を修正してください。next dev は本番用サーバーではありません。
Node.js: Keelson は NODE_ENV を自動設定しません。keelson.yaml で本番モードを宣言してください。未設定の場合、Express などのフレームワークがスタックトレースを返すことがあります。
env: NODE_ENV: "production"Go: ビルド済みバイナリを command: "./app" で起動します。ListenAndServe を停止処理なしで放置せず、signal.NotifyContext と server.Shutdown を使って新規リクエストの受付を止め、処理中のリクエストを 10 秒の猶予内に完了させてください。
デバッグ・開発モードの既定
Section titled “デバッグ・開発モードの既定”既定値は本番で安全な向きにします。Python の DEBUG は false を既定にします。
DEBUG = os.environ.get("DEBUG", "false").lower() == "true"true を既定にしてはいけません。
DEBUG = os.environ.get("DEBUG", "true").lower() == "true"デバッグ画面は、データベースの認証トークンを含む環境変数を表示することがあります。
本番かどうかの判別
Section titled “本番かどうかの判別”Keelson が値 keelson で設定する KEELSON_MODE を使って、プラットフォーム上での実行を判別します。
ON_KEELSON = os.environ.get("KEELSON_MODE") == "keelson"本番設定の不足を即時エラーにする検査は、ON_KEELSON が true の場合だけ適用してください。DEBUG をプラットフォーム判別に使うとローカルで起動できなくなるため、代用しないでください。
タイムアウト
Section titled “タイムアウト”| 対象 | 制限 |
|---|---|
| HTTP リクエスト | 120 秒以内にレスポンスを開始(超過で 504)。ストリーミングは開始後、無通信 120 秒・合計 300 秒まで |
| 定期実行ジョブ(cron) | 1〜600 秒(既定 300 秒。プラン上限がそれより低ければ切り詰め) |
| ビルド | 600 秒 |
- アプリから外部 API やサービスへの通信はデフォルトで可能です
- 例外は SMTP のポート(TCP 25・465・587・2525)で、常に遮断されます。メール送信はメール配信サービスの HTTPS API を使ってください
よくある失敗パターン
Section titled “よくある失敗パターン”| 症状 | 原因 | 対処 |
|---|---|---|
| 起動しているが接続できない、ヘルスチェックに失敗する | 0.0.0.0 で listen していない | host="0.0.0.0" を明示 |
| ポートに接続できない | ポート番号がハードコード | 環境変数 PORT から読み取る |
| モジュールが見つからない | 依存マニフェストに記載がない、またはイメージのビルド時にインストールが失敗 | ビルドログを確認し、依存を requirements.txt または package.json に記載する |
| ネイティブモジュールのビルド失敗 | システムライブラリ不足 | -media ランタイムに変更、または依存を見直す |
| 起動コマンドが見つからない | エントリポイントのパスが間違い | ファイル名・パスを確認 |
事前チェックが command_installs_dependencies で止まる | command に pip install / npm install がある | 削除して起動コマンドだけにする |
検証が db 不足で止まる | db.mode が無い | libsql または none を宣言する |
ビルドが reserved_path_conflict で失敗 | ビルド出力の配信ルート直下に __keelson(予約 URL プレフィックス)がある | ディレクトリ名を変更する。ほかの制限対象パスは予約 URL パスを参照 |
| 定期ジョブが一度も発火しない(エラーも出ない) | スケジュールがアプリのプロセス内にある(in-process スケジューラ)。予定時刻にはアプリがゼロにスケールしている | crons エントリとして宣言する |
| UI は成功と表示されたのにメール・通知が届かない | レスポンスを返した後に回した処理が走っていない | レスポンスを返す前に済ませるか、バックグラウンドタスクに投入する。タスクを使わない場合は、処理内容を DB に保存し、crons で定期的に読み出して実行する。次の定期実行まで待機し、実行状況によってはさらに遅れることをユーザーに伝える |
失敗時の確認手順
Section titled “失敗時の確認手順”- ビルドログを確認 — 依存関係のインストールが成功しているか
- 実行ログを確認 — 起動時エラーやランタイムエラーがないか
keelson.yamlを確認 —runtime、command、envの設定が正しいか
AI エージェントの期待動作
Section titled “AI エージェントの期待動作”AI エージェントは、Keelson へのデプロイ時に以下の順序で判断してください。
- ランタイム確認 — アプリの言語がこの仕様の対応ランタイムに含まれるか確認する
- 依存関係確認 — ネイティブ依存やシステムライブラリの要件が制約内か確認する
- keelson.yaml 確認 — ファイルの有無と設定内容の妥当性を確認する。なければ作成する
- 環境変数確認 — 必要な環境変数やシークレットが不足していないか確認する
- デプロイ実行 — CLI または Skill を使ってデプロイを実行する
- 完了確認 — デプロイ成功の定義に従い、アプリの種類に応じて確認する。Web アプリは起動・ヘルスチェック・URL アクセス、静的サイト・SPA は URL での配信、定期実行専用アプリは設定の反映を確認する
- 失敗時対応 — ログを確認し、修正可能な範囲で対処する。制約違反がある場合は理由を明示して停止する
- 非対応ランタイムの場合は、デプロイを試行しない。理由を明示して停止する
- 必須設定が不足している場合は、必要事項を提示する
- ビルド成功のみで完了扱いにしない
- 起動失敗時は必ずログを参照する
仕様参照の優先順位
Section titled “仕様参照の優先順位”- Web 上の最新 Keelson Deploy Spec(この文書)
- Web 上の最新 CLI バージョン情報
- Skill 同梱版の仕様
- 一般知識・推測
Web 上の正本と Skill 同梱の情報が矛盾する場合は、Web 上の正本を優先してください。