keelson.yaml
keelson.yaml はプロジェクトルートに置くデプロイ設定ファイルです。ランタイム、起動コマンド、環境変数、データベース、定期実行ジョブ、静的アセットなどを定義します。
デプロイ時に Keelson はこのファイルを読み、ビルドと実行環境を決めます。入門は keelson.yaml の設定を参照してください。
slug: my-appruntime: python-slimcommand: "python app.py"db: mode: noneトップレベルフィールド
Section titled “トップレベルフィールド”| フィールド | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
slug | string | はい | — | アプリの識別子。アプリ作成時に使われる |
workspace | string | — | null | プロジェクト単位の CLI 操作で使う既定ワークスペース。ワークスペースの slug を推奨。所属が 1 つだけなら CLI が自動選択するため書かなくてよい。明示した --workspace はこの値より優先し、apps list の一覧は絞り込まない |
description | string | — | null | アプリの説明(300 文字以内) |
type | string | — | null | アプリ種別。"web" のみ |
runtime | string | はい | — | 実行環境。対応ランタイムを参照 |
command | string | list | 条件付き | — | 起動コマンド。cron のみ・静的のみの構成では省略可 |
env | map | — | {} | 秘密でない環境変数 |
db | object | はい | — | データベースとローカル SQLite の方針 |
crons | list | 条件付き | [] | 定期実行ジョブ。command も静的 assets も無い場合は必須 |
assets | object | — | null | 静的アセット配信 |
health | object | — | null | デプロイ時ヘルスチェックのパス |
secrets | object | — | {} | シークレットの宣言と必須条件 |
auth | object | — | null | 対話ログインを通さない外部向けエンドポイント |
email | object | — | {} | 受信メール |
verify | string | list | — | [] | デプロイ後に追加で検証するパス |
region | string | — | null | 新規アプリの配置リージョン |
storage | object | — | {} | 廃止された disk_id だけを受理する互換ブロック |
廃止されたトップレベルキー databases と workers は、値が null や空リストでも拒否されます。永続的な関係データは db.mode: libsql、時刻起点の処理は crons で表現してください。
旧名のトップレベル tenant も workspace の互換用別名として受け付けます。撤去時期は
未定です。両方を書く場合、生の文字列値が完全に一致している必要があります。
上の表にないトップレベルキー(build、port、scaling など)や、各オブジェクトの中の未知のキーは拒否されます。独自のキーを足せる拡張可能な形式ではありません。crons / email / secrets / storage に null を書くと省略と同じにはならず拒否されます。省略したいときはキーごと書かないでください。
文字列の書き方
Section titled “文字列の書き方”keelson.yaml は CLI(YAML 1.2)と API(YAML 1.1)の 2 つの実装が解析します。引用符のないスカラーの型解決が食い違うため、次の文字列は引用符で囲む必要があります。囲まないと string_value_not_portable で拒否されます。
- 数字で始まる値(
slug: "123-app") - 日本語など ASCII 英字以外で始まる値(
description: "営業向けアプリ") -で始まる値。コマンドをリストで書くときのフラグ(command: [python, app.py, "--port", "8080"])- YAML が真偽値や null と解釈する語(
yes/no/on/off/true/false/nullとその大文字違い) :を含む値(":memory:")
英字で始まる通常の値(python app.py、my-app、dist)は引用符なしで書けます。env だけは規則が強く、値をすべて引用符かブロックスカラー(| / >)で書きます(env を参照)。
アプリの識別子です。アプリ作成時の公開 URL(https://<ワークスペース slug>--<slug>.keelson.run)の一部になります。
slug: my-appルール:
- 小文字英数字とハイフン(
a-z、0-9、-)のみ - 1〜63 文字
- 先頭と末尾は英数字
- ハイフンの連続(
--)は不可 - 予約語:
adminapiassetsauthconsolehealthstaticwww
public_slug は廃止された互換フィールドで、無視されます。
description
Section titled “description”アプリが誰向けで何をするかを示す 1〜2 文です。
description: "営業チーム向けの日報・週報作成アプリ。週次サマリーを自動集計します"前後の空白を除いて 300 文字(Unicode コードポイント)以内。超えるとデプロイが失敗します。アプリ台帳の説明欄に表示され、説明がまだ空のときだけ適用されます。コンソールで編集した説明がデプロイで上書きされることはありません。
アプリ種別です。省略可能です。
type: web指定できる値は web だけです。type: web を指定すると、assets だけで command なしのデプロイができます。
制約:
type: webとcronsは併用できません- Web アプリと cron を両方持つアプリでは
typeを省略します
runtime
Section titled “runtime”実行環境です。静的サイトだけのデプロイでも必須ですが、静的サイトではビルドに使われません。静的サイトは手元や CI でビルド済みの assets.dir をそのまま配信します。
対応ランタイム
Section titled “対応ランタイム”| ランタイム | 言語 | 用途 |
|---|---|---|
python-slim | Python | 軽量。API、テキスト処理など |
python-media | Python | 画像・動画処理(Pillow、opencv、ffmpeg 関連など) |
node-slim | Node.js | 軽量 |
node-media | Node.js | 画像処理(sharp など) |
go-slim | Go | 軽量 |
go-media | Go | メディア処理 |
迷ったら -slim から始め、メディア処理系ライブラリが必要になったら -media に切り替えます。
依存関係のインストール
Section titled “依存関係のインストール”コンテナ型とハイブリッド型では、依存パッケージはビルド時に Keelson が自動でインストールします。静的サイト(command なし)ではこの処理は走らず、アップロードされるのも assets.dir と keelson.yaml だけです。command には起動コマンドだけを書いてください。command に pip install / npm install / go build を含めると、CLI の事前チェックが command_installs_dependencies でデプロイを止めます。
| ランタイム | 検出するファイル | ビルド時に実行される処理 |
|---|---|---|
python-* | requirements.txt | python -m pip install --user -r requirements.txt |
python-* | pyproject.toml([project] または [build-system] あり)。requirements.txt がない場合のみ | python -m pip install --user . |
node-* | package-lock.json / package.json | npm ci(ロックファイルあり)または npm install、続けて npm run build --if-present |
go-* | go.mod / go.sum | go mod download、go build -o /workspace/app .(command: "./app" で起動) |
ビルドの制約:
requirements.txtとpyproject.tomlが両方あるときはrequirements.txtだけを使います。pyproject.toml側だけに書いた依存や自作パッケージのインストールは行われないので、必要なものはrequirements.txtに含めてください- インストール可能な Python の
pyproject.tomlには、対応するロックファイル(requirements.txt/poetry.lock/uv.lock/Pipfile.lock)のいずれかが必要です - Node のビルドは npm のみを使い、
package-lock.jsonが必要です。pnpm-lock.yaml/yarn.lockだけの場合は事前チェックがlockfile_unsupportedでデプロイを止めます。package-lock.jsonと併存している場合はそのまま残してかまいません - サードパーティ依存を宣言する Go モジュールには
go.sumが必要です。標準ライブラリだけを使うモジュールには必要ありません - 公開レジストリからのみ取得できます。private registry、
git+ssh依存、認証が必要なインストールは失敗します - Go は
CGO_ENABLED=0でビルドされます - ビルド対象は
linux/amd64のみ - ビルド時にシークレットは渡りません
- ビルドの上限時間は 600 秒
command
Section titled “command”アプリ起動時に実行するコマンドです。文字列(シェル経由)またはリスト(直接実行)で指定します。
# 文字列形式(/bin/sh -c で実行)command: "python app.py"
# リスト形式(exec で直接実行)command: - python - app.pyルール:
command、crons、静的assetsのいずれかが必要です- cron だけのアプリに
commandは不要です type: webでassetsがある静的サイトにcommandは不要です- 空文字列・空リストは「起動コマンドなし」として扱われます。通常の Web アプリでは指定が必要です。
crons[].commandは空にできません - 依存関係のインストールは含めません(依存関係のインストールを参照)
秘密でない環境変数をキーと値で定義します。値はすべて文字列です。
PORT は Keelson が実行時に設定します。env に書いても無視されます。
値は必ず引用符で囲むか、ブロックスカラー(| / >)で書いてください。 引用符のない値は env_value_not_string で拒否され、デプロイは開始されません。数値・真偽値も同様です。
env: NODE_ENV: "production" DEBUG: "false" LOG_LEVEL: "info"引用符が必須なのは、keelson.yaml を CLI(YAML 1.2)と API(YAML 1.1)の 2 つの実装が解析しており、引用符のないスカラーの型解決が食い違うためです。たとえば K: 0o123 は経路によって "83" にも "0o123" にもなります。引用符で囲めば両方で同じ文字列になります。
引用符を付けないキーは、英字か _ で始まり、英数字と _ だけで構成される必要があります。NODE_ENV や DB_POOL のような通常の環境変数名はそのまま書けます。
次の語は YAML 1.1 で真偽値・null と解釈されるため、引用符なしでは使えません:
yes Yes YES no No NO true True TRUE false False FALSE on On ON off Off OFF null Null NULL
ハイフンを含む名前や予約語は、キーを引用符で囲みます。
env: NODE_ENV: "production" "MY-VAR": "x" "yes": "x"KEELSON_ で始まるキー(大文字小文字を区別しない)はプラットフォーム予約で、env には設定できません。env の重複宣言、env 内のキー重複、YAML の merge key(<<)も拒否されます。
秘密の値は env ではなく secrets で宣言し、値はコンソールまたは CLI で設定します。env と同じ名前のシークレットが設定されている場合はシークレットの値が優先され、env の変更は反映されません。
データベースの扱いを選びます。db と db.mode は必須です。
db: mode: libsql| フィールド | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
mode | string | はい | — | libsql または none。旧名 turso は libsql に正規化 |
migrate | string | — | null | デプロイ時に実行するマイグレーションコマンド。libsql のときのみ有効 |
auto_adopt | boolean | — | false | 旧設定との互換のため受理されるが、現在は何もしない。DB を引き継ぐ機能ではない |
local_sqlite | object | — | null | 再生成可能な一時 SQLite ファイルの明示宣言 |
mode | 意味 |
|---|---|
libsql | Keelson がアプリ専用の Managed SQLite を用意し、KEELSON_DB_URL / KEELSON_DB_AUTH_TOKEN(別名 TURSO_DATABASE_URL / TURSO_AUTH_TOKEN)を注入する |
none | Keelson は DB を管理しない。DB 不要のアプリ、または外部 DB を使うアプリ |
mode: libsql は契約も接続設定も不要で、scale-to-zero に対応します。永続的な関係データにはこれを推奨します。
PostgreSQL、MySQL、自前の libSQL を使う場合は mode: none にし、接続情報をシークレットで渡します。外部 DB の接続情報を Keelson が注入することはありません。
/data のファイル SQLite を永続化するモードはありません。ファイル SQLite を使うコード(sqlite3、better-sqlite3 など)はデプロイ時に検出され、local_sqlite の宣言がなければ拒否されます。
マイグレーション
Section titled “マイグレーション”db.migrate は、新しいイメージでトラフィックを切り替える前に 1 回だけ実行されるコマンドです。
db: mode: libsql migrate: "python migrate.py"mode: libsqlのときのみ有効。文字列で指定します- コンテナ型・ハイブリッド型でのみ実行されます。静的サイトにはコンテナがないため、宣言しても実行されません
- 候補リビジョンがヘルスチェックを通った後、トラフィック切り替えの前に、デプロイ対象のイメージ上で実行されます。アプリの起動コードは移行前のスキーマで動く必要があります
- 終了コードが 0 以外ならデプロイは
deploy.runtime.migration_failedで失敗し、旧リビジョンが維持されます - 毎回のデプロイで実行されるため、冪等に書きます(
CREATE TABLE IF NOT EXISTS、ON CONFLICT DO NOTHING)
一時的なローカル SQLite
Section titled “一時的なローカル SQLite”再生成できるキャッシュ用途のファイルだけを db.local_sqlite で宣言します。宣言してもファイルは永続化されません。
db: mode: none local_sqlite: policy: ephemeral paths: - /tmp/cache.db reason: "外部 API から再構築できる派生キャッシュ"| フィールド | 型 | 必須 | 制約 |
|---|---|---|---|
policy | string | はい | ephemeral のみ |
paths | list | はい | 空でないこと。各パスは /tmp/ 配下か :memory: |
reason | string | はい | 消えても問題ない理由 |
廃止された databases ブロックは常に拒否されます。
定期実行ジョブを定義します。各ジョブは Web サービスとは別のインスタンスで実行されます。
crons: - name: cleanup schedule: "0 3 * * *" command: "python cleanup.py" timeout: 60 enabled: true| フィールド | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
name | string | はい | — | ジョブ名。小文字英数字とハイフン、1〜63 文字、重複不可 |
schedule | string | はい | — | 5 フィールドの cron 式 |
command | string | list | はい | — | 実行コマンド |
timeout | integer | — | 300 | タイムアウト秒。1〜600 |
enabled | boolean | — | true | false にするとスケジュールされない |
ルール:
- 1 アプリ最大 10 本。プランによりさらに少ない上限があります
type: webと併用できません- 別インスタンスで実行されるため、ローカルファイル(
/dataを含む)は Web と共有されません。共有する状態はdb.mode: libsqlに置きます - 前回の実行が継続中なら、その回はスキップされます
- スケジュールはワークスペースのタイムゾーンで評価されます
timeoutの絶対上限は 600 秒。省略時は 300 秒ですが、プランの上限がそれより低ければプラン上限に切り詰められます
本数・最小間隔・timeout 上限のプラン別の値はプランと制限を参照してください。
cron 式の例
Section titled “cron 式の例”| 式 | 意味 |
|---|---|
0 * * * * | 毎時 0 分 |
*/15 * * * * | 15 分ごと |
0 3 * * * | 毎日 3:00 |
0 9 * * 1-5 | 平日 9:00 |
0 0 1 * * | 毎月 1 日 0:00 |
* * * * *(毎分)は全プランの最小間隔より短いため拒否されます。実行の挙動と設計は定期実行ジョブを参照してください。
workers(廃止)
Section titled “workers(廃止)”workers(バックグラウンドワーカー / 定期ドレイン)は廃止されました。トップレベルに workers があると、値が空リストや null でも workers_not_supported で拒否されます。
同じ処理は crons で表現します。ドレイン型の処理は、短い間隔のスケジュールを 1 本立て、1 回の実行で未処理分を片付けて終了する形にします。
# NG — デプロイが拒否されるworkers: - name: drain command: "python worker.py" every: 10m
# OK — crons で書くcrons: - name: drain schedule: "*/5 * * * *" command: "python drain.py" timeout: 120assets
Section titled “assets”静的サイト、SPA、静的ファイル + バックエンド API(hybrid)の配信設定です。
assets: dir: dist fallback: index.html api: /api| フィールド | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
dir | string | はい | — | アセットディレクトリ(プロジェクトルートからの相対パス) |
static_dir | string | — | null | dir の廃止された別名。両方ある場合は一致が必要 |
fallback | string | 条件付き | null | SPA 用フォールバック(例: index.html)。dir 配下の相対パス |
api | string | — | null(ハイブリッドでは実効値 /api) | バックエンドへ転送するパスプレフィックス。command と assets の両方があるハイブリッドで省略すると /api が使われる |
ハイブリッドでは api のパス配下がバックエンドへ転送され、それ以外は静的アセットとして配信されます。省略時のプレフィックスは /api です。別のパスにしたいときだけ指定します。
ルール:
dirに..は使えませんapiは/で始まり、/そのものではなく、/__keelson配下でないことapiはトップレベルのcommandがある場合のみ有効assetsとcommandの両方がある hybrid ではfallbackが必須
アーカイブに含まれるもの
Section titled “アーカイブに含まれるもの”CLI はデプロイ用アーカイブを作るとき、パスに .git、.venv、__pycache__、.pytest_cache、node_modules、dist、build、.idea、.vscode、.DS_Store を含むものを除外します。宣言した assets.dir とその祖先は免除されるので、dist などのビルド出力は含まれます。ただし assets.dir 配下でも dist/node_modules/** のように除外名に再び一致するものは除外されます。.git、シンボリックリンク、通常ファイル以外、--secrets-from-env-file で指定したファイルは名前によらず常に除外されます。CLI はそのプロジェクト相対パスだけを、秘匿値を含めず、自動除外される .keelson-config/previous-secrets-files.json に保存します。
env 系のファイル(最後の要素が .env で始まるか終わるもの。.env、.env.production、.envrc、.secrets.env など)は assets.dir の中でも除外されます。
プロジェクト固有の除外は、プロジェクト直下の .keelsonignore に書きます。gitignore に似た記法(1 行 1 パターン、# コメント、/、末尾 /、*、?、**、[abc]、[a-z]、先頭 ! の否定)が使え、最後に一致した行が優先されます。!.env.production で env ファイルを意図的に再同梱できますが、.git、組み込み除外、.keelsonignore 自身、--secrets-from-env-file のファイルは再同梱できません。.gitignore は読みません。
assets があり、文字列形式・配列形式のどちらの command もない静的アプリでは、既定で assets.dir 配下のファイルと keelson.yaml だけをアーカイブします。assets.dir へ到達するため、その祖先ディレクトリは走査できます。外側のファイルを意図的に戻すには .keelsonignore の先頭 ! を使います。ディレクトリと中身を戻すには !keep/ と !keep/** の両方が必要です。コンテナ型・ハイブリッド型ではビルドに必要なソースを従来どおり同梱します。
assets.dir: . や同じ意味の ./ は避けてください。プロジェクト直下が公開 assets になるため、アーカイブされた全ファイルが配信され得ます。CLI はデプロイ前に警告しますが、この設定は禁止しません。
keelson deploy --check はアーカイブ内容と主要な設定を手元で検証しますが、API 側の検証より緩い項目があります(assets / crons / auth / email / secrets の未知キー、cron 式の妥当性、verify のパス形式など)。--check が通っても、デプロイ時に deploy.config.invalid で止まることがあります。
アップロード前に keelson deploy --check --json を実行し、archive.excluded、archive.excluded_env_files、archive.secret_like_files、archive.embedded_credentials、archive.unscanned_files、archive.unscanned_binary_count を確認してください。embedded_credentials は値を出さずパスと種別だけを報告します。プレビュー資格情報やアプリ用トークンが検出された場合はアップロードを停止し、Webhook 署名鍵のみの一致であれば警告を表示して続行します。16 MiB を超えるファイルとバイナリ判定されたファイルは本文検査をせず、除外ファイルも検査対象外です。secret_like_files は credentials.json や *.pem のような秘匿値を含みそうな名前に加え、過去に --secrets-from-env-file で指定したものの今回は除外指定しなかった実在ファイルも警告します。prod-secrets.txt のような env 系でない名前も対象で、警告されたファイルは除外されず同梱されます。
ブラウザキャッシュ
Section titled “ブラウザキャッシュ”ファイル名にコンテンツハッシュが入った JavaScript / CSS(例: index-B7hK2mQ1.js)は 1 年間キャッシュされます。Keelson は、ASCII 英数字と _ からなり英字と数字の両方を含む 8〜64 文字の末尾セグメントをハッシュと認識します。HTML、style.css や app.js のようなハッシュなしのファイル、画像などは、アクセスのたびに ETag で更新を確認します。
静的サイト(edge-static / edge-spa)の再デプロイは、新しいファイルがエッジに反映されるまで 25〜30 秒かかります。
health
Section titled “health”デプロイ時のヘルスチェックに使うパスです。/ が重い、DB に依存する、などの場合に軽量なエンドポイントを指定します。
health: path: /health- 省略時は
/を確認します /で始まり、..を含まず、/__keelsonで始まらない 2048 文字以内のパス- HTTP 2xx / 3xx / 404 で合格、それ以外の 4xx と 5xx で不合格。404 が通るため、合格は「起動した」ことの確認であり、そのパスが実装されていることの証明ではありません
- 候補リビジョンの内部 URL へ直接送られ、公開ホストや認証は経由しません。公開パスの検証は
verifyで行います
secrets
Section titled “secrets”アプリが必要とするシークレットと、必須の組み合わせを宣言します。値はここには書かず、コンソール、CLI、またはデプロイ時の env ファイルで設定します。
secrets: items: - name: OPENAI_API_KEY description: "OpenAI API key" - name: ANTHROPIC_API_KEY description: "Anthropic API key" required: - any_of: [OPENAI_API_KEY, ANTHROPIC_API_KEY] message: "AI プロバイダのキーを少なくとも 1 つ設定してください"| フィールド | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
items | list | — | [] | シークレットの定義 |
items[].name | string | はい | — | 名前。環境変数の形式(大文字英字か _ で始まり、A-Z0-9_ のみ、255 文字以内)で書く。KEELSON_ で始まる名前は予約 |
items[].description | string | — | "" | 用途の説明。コンソールに表示される |
required | list | — | [] | 設定済みシークレットに対して検証するルール |
| required[].any_of | list | 条件付き | null | いずれか 1 つが設定されていればよい名前の空でないリスト |
| required[].all_of | list | 条件付き | null | すべて設定されている必要がある名前の空でないリスト |
| required[].message | string | — | "" | 未設定時に表示する案内 |
required の各エントリは any_of または all_of のどちらか一方だけを持ちます。参照できるのは items で宣言した名前だけです。
名前は値を設定するときに大文字に正規化され、required の照合は大文字小文字を区別します。name: api_key と書くと値は API_KEY として保存され、required の条件が満たされません。最初から大文字で書いてください。MY-KEY のようにハイフンを含む名前は宣言できても値を設定できません。
新しいアプリでは keelson deploy --new --secrets-from-env-file <path> で、アプリ作成・シークレット設定・初回デプロイを 1 回で行えます。既存アプリのシークレット変更は次のデプロイで反映されます。
Webhook の受信など、対話ログインを通さずに外部システムから呼ばれるエンドポイントを宣言します。
auth: endpoints: - /api/webhooks/stripe - path: /api/external/status methods: [GET]authがある場合、endpointsは空でないリストが必須です- 各エントリはパス文字列、または
pathと省略可能なmethodsを持つオブジェクト - パスは
/api/external/または/api/webhooks/で始まり、重複しないこと。/__keelson配下は不可 - パスは前方一致です。
/api/external/statusは/api/external/status-extraにも一致します methodsを指定する場合は空でないリスト。省略時は全メソッドを許可。大文字小文字は区別しませんmethodsが効くのは/api/external/だけです。/api/webhooks/には適用されず、メソッドを絞りたければアプリ側で判定します
「対話ログインを通さない」は「Keelson の認証が不要」という意味ではありません。宣言しただけでは外部から届かず、呼び出し側は Keelson が発行する資格情報を付ける必要があります。
| パス | 必要な資格情報 |
|---|---|
/api/external/... | api スコープのアプリトークンを Authorization: Bearer で送る |
/api/webhooks/... | webhook スコープのアプリトークンを X-Webhook-Secret ヘッダーで送るか、/api/webhooks/<secret>/... の形の URL を外部サービスに登録する |
トークンの発行は keelson apps tokens create、URL の組み立ては外部連携を参照してください。Stripe の署名だけを送る通常の Webhook や、アプリ独自の API キーだけを送るクライアントは、アプリに届く前に拒否されます。
これらのパスへのリクエストには X-Keelson-User-Id が付きません。Keelson の資格情報に加えて、アプリ側でも Webhook 署名や API キーによる検証を行ってください。
受信メールの設定です。
email: inbound: enabled: trueemail.inbound.enabled は boolean で、既定は false です。受信メールを処理するにはコンテナが必要です。静的サイト(type: web + assets、command なし)で有効にすると、設定は受理されますがデプロイが deploy.config.invalid で失敗します。
verify
Section titled “verify”デプロイ後の検証で追加で確認するパスです。既定では / だけを確認します。
verify: - /dashboard - /settings- 単一のパスは文字列でも 1 要素のリストでも指定できます
- 最大 20 パス(前後の空白を除き、重複を除いた数)。各パスは
/で始まり、//で始まらず、パス要素としての..と制御文字を含まないこと - コンテナ / hybrid では公開ホスト経由で候補リビジョンから取得し、静的 / SPA では公開前にリリースマニフェスト上で解決します
- どちらの種類でも、宣言したパスが 2xx / 3xx 以外(404 / 401 / 403 / 405 など)なら
verification_declared_path_unreachableでデプロイに失敗します verify:にはアプリ自身のログインを必要としないパスを書いてください。検証リクエストにはアプリのユーザー情報が付かないため、アプリが返す 401 / 403 も不合格です/はverify:にも書かれていても従来どおり寛容です。API だけのアプリが/で 404 を返しても合格します
クライアント側ルーティングでしか到達できない画面など、/ から辿れないエントリを確認したいときに使います。
これは health.path とは別の判定です。health.path は候補リビジョンを内部 URL で直接確認し、プロセスが起動した証拠として 404 でも合格します。verify は宣言した公開パスが実際に配信できるかを確認するため、404 では不合格です。
region
Section titled “region”新規アプリを作るときの配置リージョンを任意で指定します。
region: us-oregonクラウド事業者のリージョン名ではなく、Keelson の論理キーを指定します。
| 論理キー | 表示名 |
|---|---|
jp-tokyo | 日本 |
us-oregon | 米国西海岸 |
新規アプリでは CLI の --region、keelson.yaml の region、ワークスペースの既定リージョンの順で優先されます。明示したリージョンが未定義または新規作成に未開放の場合は、別リージョンへ切り替えずに拒否されます。
アプリのリージョンは作成時に確定し、後から変更できません。既存アプリと異なる region を指定したデプロイは拒否されます。別リージョンへ移す場合は、新しいアプリとして作り直してください。
storage
Section titled “storage”storage は廃止された disk_id だけを受理します。値は無視され、永続ストレージや /data の同期を有効にしません。残っていたら削除してください。
| フィールド | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
disk_id | string | — | null | 無視される旧識別子。小文字英数字とハイフン、1〜32 文字 |
デプロイモード
Section titled “デプロイモード”デプロイモードは command、assets、fallback の有無から導出されます。直接は選べません。keelson status --json などの出力は deploy_mode の生ラベルを返します。
| 呼称 | deploy_mode | command | assets | fallback | 説明 |
|---|---|---|---|---|---|
| Web アプリ | container | あり | なし | — | 通常のアプリ |
| 静的サイト | edge-static | なし | あり | なし | 静的ファイルのみ |
| SPA | edge-spa | なし | あり | あり | フォールバック付き静的ファイル |
| ハイブリッド | hybrid | あり | あり | 必須 | 静的ファイル + バックエンド API |
フィールド間の制約
Section titled “フィールド間の制約”| ルール | 内容 |
|---|---|
| 実行面が必要 | command、crons、静的 assets のいずれかを指定する |
type: web は cron 不可 | type: web と crons を併用しない |
| 静的サイトにはコンテナがない | command のない静的サイト・SPA では、crons、db.migrate、email.inbound は動かない。宣言が受理されても実行されない(email はデプロイ失敗)ので、これらが要るならコンテナ型かハイブリッドにする |
workers は廃止 | crons で書き直す |
db.migrate は libsql のみ | db.mode: libsql が必要 |
| ローカル SQLite は一時領域のみ | db.local_sqlite.paths は /tmp/ 配下か :memory: |
assets.api にはバックエンドが必要 | トップレベルの command を設定する |
hybrid には fallback が必要 | assets と command が両方あるとき assets.fallback を設定する |
Web アプリ + Managed SQLite
Section titled “Web アプリ + Managed SQLite”slug: crud-appdescription: "顧客と案件を管理する社内 CRM"runtime: python-slimcommand: "python app.py"db: mode: libsql migrate: "python migrate.py"env: PYTHONUNBUFFERED: "1"静的 SPA
Section titled “静的 SPA”手元で npm run build などを実行して dist を作ってからデプロイします。Keelson 側ではビルドしません。
slug: marketing-sitetype: webruntime: node-slimdb: mode: noneassets: dir: dist fallback: index.html定期実行のみ
Section titled “定期実行のみ”slug: daily-reportruntime: python-slimdb: mode: libsqlenv: PYTHONUNBUFFERED: "1"crons: - name: generate schedule: "0 9 * * *" command: "python report.py" timeout: 120Web アプリ + 定期ドレイン
Section titled “Web アプリ + 定期ドレイン”Web アプリが pending 行を Managed SQLite に書き、cron が別インスタンスで処理します。共有する状態はローカルファイルではなく db.mode: libsql に置きます。
slug: task-drainerruntime: python-slimcommand: "python app.py"db: mode: libsqlenv: PYTHONUNBUFFERED: "1"crons: - name: drain schedule: "*/5 * * * *" command: "python drain.py" timeout: 120ハイブリッド(静的ファイル + バックエンド API)
Section titled “ハイブリッド(静的ファイル + バックエンド API)”slug: photo-galleriesruntime: node-slimcommand: "node server.js"db: mode: libsqlenv: NODE_ENV: "production"assets: dir: dist fallback: index.html api: /apiWebhook を受ける API
Section titled “Webhook を受ける API”slug: payment-hooksruntime: node-slimcommand: "npm start"db: mode: libsqlenv: NODE_ENV: "production"secrets: items: - name: STRIPE_WEBHOOK_SECRET description: "Stripe の Webhook 署名シークレット" required: - all_of: [STRIPE_WEBHOOK_SECRET]auth: endpoints: - path: /api/webhooks/stripe methods: [POST]Stripe に登録する URL には webhook スコープのアプリトークンを含めます(https://<host>/api/webhooks/<token>/stripe)。methods は Webhook には適用されないので、POST 以外を拒否したければアプリ側で判定します。
Go アプリ
Section titled “Go アプリ”slug: my-go-appruntime: go-slimcommand: "./app"db: mode: noneKeelson がデプロイ時に Linux 向けにビルドし、バイナリを ./app に置きます。
よくあるエラー
Section titled “よくあるエラー”| 原因 | 対処 |
|---|---|
db または db.mode がない | db.mode を libsql か none で宣言する |
廃止された databases がある | 削除する。永続データは Managed SQLite、一時 SQLite は db.local_sqlite で宣言 |
workers がある(workers_not_supported) | 削除して crons で書き直す |
command に pip install / npm install がある(command_installs_dependencies) | 削除する。依存はビルド時に自動インストールされる |
依存マニフェストがない(missing_dependency_manifest) | Go ではプロジェクトルートに go.mod を置く。Python または Node.js では、外部ライブラリを使う場合に適切なマニフェストを置く。標準ライブラリだけなら不要 |
runtime と command の言語が合わない(runtime_command_mismatch) | ランタイムを合わせるか、起動コマンドを直す |
env の値が引用符なし(env_value_not_string) | すべての値を引用符で囲む(数値・真偽値も) |
環境変数名が KEELSON_ で始まる | 名前を変える。この名前空間はプラットフォーム予約 |
local_sqlite.paths が /tmp/ の外 | /tmp/、:memory:、または Managed SQLite を使う |
command、crons、静的 assets のどれもない | いずれかを追加する |
crons[].timeout が 600 を超える | 600 以下、かつプランの上限以下にする |
assets.api が / で始まらない | /api のような絶対パスにする |
hybrid で assets.fallback がない | index.html などを設定する |
ビルドが reserved_path_conflict で失敗 | ビルド出力直下の __keelson ディレクトリを改名する |