# Keelson ドキュメント(全文) Keelson は、AI ツールで作った社内アプリを、ログイン保護と権限付きで運用するための基盤です。 このファイルは日本語ドキュメントの全ページを 1 つにまとめたものです。 索引: https://keelson.dev/ja/llms.txt デプロイ可否の判定は Keelson Deploy Spec を正本としてください: https://keelson.dev/ja/docs/reference/deploy-spec.txt # はじめに --- # ドキュメントガイド Keelson でできること、できないこと、目的別の入口 URL: https://keelson.dev/ja/docs/introduction/what-is-keelson/ Language: ja --- Keelson は、AI ツールなどで作った社内アプリをデプロイし、ログインとアクセス権を付けてチームで使えるようにするサービスです。 利用を始めるには、[Keelson コンソールでアカウントを作成・ログイン](https://console.keelson.dev/sign-in)してください。 初めて試す方はクイックスタート、すでにアプリを持っている方は持ち込みガイドから始めてください。 ## 目的から選ぶ - [試す](https://keelson.dev/ja/docs/introduction/quickstart/) — サンプルをデプロイして、ログイン保護が効くところまで。所要 15 分 - [持ち込む](https://keelson.dev/ja/docs/building-apps/bring-your-app/) — Lovable / Bolt / v0 や手元のコードで作ったアプリをデプロイする - [困っている](https://keelson.dev/ja/docs/deploy/troubleshooting/) — デプロイが失敗する、利用者が開けない、データが消えた ## 対応しているアプリと用途 Python / Node.js / Go の Web アプリ、ビルド済みの静的サイト、定期実行ジョブに対応しています。社内の数人〜数百人が使う業務アプリを想定しており、利用者数は料金に影響しません。 常駐プロセスや WebSocket を前提とする構成、GPU が必要なアプリなどには対応していません。フレームワークごとの対応状況は[対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/)を確認してください。 Keelson 専用のフレームワークで作る必要はありません。既存の外部 DB やサービスも利用できます。ほかの環境へ移す場合に必要な準備は [FAQ](https://keelson.dev/ja/docs/introduction/faq/#keelson-向けに作ったアプリはほかの環境でも動きますか)を参照してください。 サービス概要と料金は[公式サイト](https://keelson.dev/ja/)にあります。 ## 読む人別のガイド ### アプリを作ってデプロイする人 **まず読む** - [クイックスタート](https://keelson.dev/ja/docs/introduction/quickstart/) — サンプルをデプロイして試す - [基本コンセプト](https://keelson.dev/ja/docs/introduction/core-concepts/) — 用語と、アプリ・Keelson の役割分担を知る - [対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/) — 自分のアプリをデプロイできるか確認する **必要になったら参照する** - [アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/) — 起動・停止と、処理の実行方法 - [データベース](https://keelson.dev/ja/docs/building-apps/persistent-storage/) / [ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/) — 保存先の使い分け - [ログイン中のユーザー情報を使う](https://keelson.dev/ja/docs/building-apps/using-identity/) — 作成者の記録や、ユーザーごとの表示 - [デプロイする](https://keelson.dev/ja/docs/deploy/deploy/) / [更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/) — 変更の反映と戻し方 - [リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/) — 設定項目やコマンドの詳細 ### ワークスペースを運営する人 1. [メンバーを招待する](https://keelson.dev/ja/docs/workspace/invite-members/) 2. [メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/) 3. [チームにアプリを共有する](https://keelson.dev/ja/docs/access-control/share-with-team/) — 特定のチームだけに公開する手順 4. [グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/) — 誰がどのアプリを使えるか 5. [IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/) 6. [プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/) / [料金と契約の運用](https://keelson.dev/ja/docs/workspace/billing/) ### AI エージェント AI エージェント向けの仕様は [Keelson Deploy Spec](https://keelson.dev/ja/docs/reference/deploy-spec/) に 1 ページでまとまっています。次の URL をエージェントに渡すと、アプリを Keelson にデプロイできるかを確認し、必要なコードや設定の変更を提案します。 ``` https://keelson.dev/ja/docs/reference/deploy-spec.txt ``` ドキュメント全体の索引は [`/ja/llms.txt`](https://keelson.dev/ja/llms.txt)、全文は [`/ja/llms-full.txt`](https://keelson.dev/ja/llms-full.txt) にあります。各ページは URL の末尾を `.md` に変えると Markdown で取得できます(例: `/ja/docs/introduction/quickstart.md`)。 CLI に同梱されている Skill(`keelson install-agent`)には、同じ内容に加えて言語別の書き換え手順が入っています。 ## よくある質問 導入前によく聞かれることは [FAQ](https://keelson.dev/ja/docs/introduction/faq/) にまとめています。 --- # クイックスタート サンプルアプリを Keelson にデプロイして、ログイン保護が効くところまで確認する URL: https://keelson.dev/ja/docs/introduction/quickstart/ Language: ja --- 小さなサンプルアプリを Keelson にデプロイし、ブラウザで開き、ログインしていない人には開けないことを確認します。 - **できること**: 自分のワークスペースに最初のアプリが作成され、専用 URL とログイン保護が付く - **所要時間**: 15 分ほど。ビルドの待ち時間が大半です - **必要なもの**: Keelson のアカウント、ターミナル、Claude Code / Codex / Cursor のいずれか。外部サービスの API キーは要りません - **完了条件**: 発行された URL を自分のブラウザで開くと挨拶の画面が出て、シークレットウィンドウで開くとログイン画面になる Keelson のアカウントがまだ無い方は、[console.keelson.dev](https://console.keelson.dev/sign-in) からサインアップしてください。 ## 1. CLI を入れてログインする Keelson CLI は、ターミナルからログインやデプロイを行うためのツールです。使っている OS のタブを選び、次のコマンドでインストールしてください。 **macOS / Linux** ```bash curl -fsSL https://keelson.dev/install.sh | sh ```
keelson コマンドが見つからない場合 インストーラーは、コマンドを探す場所(PATH)を変更しません。次の行を `~/.zshrc` や `~/.bashrc` に追加し、ターミナルを開き直してください。 ```bash export PATH="$HOME/.keelson/bin:$PATH" ```
**Windows (PowerShell)** Windows 10 / 11 または Windows Server 2016 以降に標準搭載されている Windows PowerShell 5.1 以上で実行します。 ```powershell irm https://keelson.dev/install.ps1 | iex ``` インストール後、現在の PowerShell で `keelson` コマンドを使えるように、次を実行します。 ```powershell $env:Path = "$env:USERPROFILE\.keelson\bin;$env:Path" ```
次回以降の PowerShell でも使えるようにする インストーラーは、コマンドを探す場所(PATH)を変更しません。「環境変数を編集」からユーザー環境変数の `Path` に `%USERPROFILE%\.keelson\bin` を追加し、PowerShell を開き直してください。
続けてログインします。ブラウザが開くので、Keelson のアカウントでログインしてください。 ```bash keelson login ``` ## 2. サンプルアプリをダウンロードする 1. [サンプルアプリをダウンロード(ZIP)](https://keelson.dev/downloads/keelson-hello-ja.zip)します。 2. ZIP を展開します。 3. 展開した `keelson-hello` フォルダを Claude Code / Codex / Cursor で開きます。
サンプルの中身を見る ```python # main.py from html import escape from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse app = FastAPI() @app.get("/", response_class=HTMLResponse) def index(request: Request): email = escape(request.headers.get("X-Keelson-User-Email") or "ゲスト") return f"""

こんにちは、{email} さん

このアプリは Keelson で動いています。

""" ``` ```text # requirements.txt fastapi uvicorn ``` ```yaml # keelson.yaml slug: hello runtime: python-slim command: "uvicorn main:app --host 0.0.0.0 --port $PORT" db: mode: none ``` このアプリは、Keelson が付けるヘッダーからログイン中のユーザーのメールアドレスを読んで表示します。認証のコードは 1 行もありません。
## 3. AI エージェントに Skill を入れる Skill は、AI エージェントに Keelson のデプロイ手順を教えるものです。Keelson CLI に同梱されています。展開した `keelson-hello` フォルダでターミナルを開き、使っているエージェントに合わせて 1 回実行します。 **Claude Code** ```bash keelson install-agent claude-code --global ``` `--global` を付けない場合、いま開いているプロジェクトにだけ入ります。 **Codex** ```bash keelson install-agent codex ``` **Cursor** ```bash keelson install-agent cursor ``` 配置先や更新方法は [CLI コマンド](https://keelson.dev/ja/docs/reference/cli/#セットアップ)を参照してください。 ## 4. デプロイを依頼する エージェントのチャットに次のように依頼します。 > このアプリを Keelson にデプロイして エージェントがデプロイを実行し、完了まで待ちます。初回は数分かかります。完了すると、次のようなアプリの URL が表示されます。 ``` https://<ワークスペース>--hello.keelson.run ``` エージェントを使わない場合は、フォルダで `keelson deploy --new` を実行しても同じです。 公開 URL はアプリの作成時に発行されるため、URL が表示されただけではデプロイ成功の証拠にはなりません。画面のない環境では、デプロイの完了前にコマンドが終了し、その後デプロイが失敗することもあります。URL を開く前に、デプロイ時に表示された ID で状態を確認してください。 ```bash keelson status ``` 失敗している場合は、このコマンドで理由と次に必要な操作を確認できます。 ## 5. 確認する 1. URL を自分のブラウザで開きます。「こんにちは、… さん」と本文が表示されれば成功です。「ゲスト」と表示されても、未ログインという意味ではありません。ログイン方法によってメールアドレスを取得できない場合に表示されます 2. 同じ URL を**シークレットウィンドウ**で開きます。Keelson のログイン画面になり、アプリは表示されません これで、専用 URL とログイン保護が付いたアプリを利用できます。デプロイしたアプリは [Keelson コンソール](https://console.keelson.dev)にも表示されます。 ## 次のステップ - **同僚に共有する** — [チームにアプリを共有する](https://keelson.dev/ja/docs/access-control/share-with-team/)。招待して、相手のアカウントで開けることを確認します - **表示を変えて更新する** — `main.py` の文言を変えて、もう一度「デプロイして」と頼みます。反映と戻し方は[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/) - **自分のアプリをデプロイする** — [対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/)で対応状況を確認し、[持ち込みガイド](https://keelson.dev/ja/docs/building-apps/bring-your-app/)へ - [基本コンセプト](https://keelson.dev/ja/docs/introduction/core-concepts/) — 認証や管理の仕組みを共有して、社内アプリを手軽に増やす --- # 基本コンセプト ワークスペース・アプリ・グループの関係と、Keelson とアプリの役割分担 URL: https://keelson.dev/ja/docs/introduction/core-concepts/ Language: ja --- Keelson では、同じワークスペースに社内アプリとメンバーをまとめて管理します。アプリを増やすたびに、ログインやメンバー管理の仕組みを作り直す必要はありません。 このページでは、基本的な用語と、Keelson が用意する機能・アプリ側で実装する機能の違いを説明します。 ## 基本の用語 | 用語 | 意味 | |---|---| | ワークスペース | メンバーやアプリをまとめて管理する単位 | | アプリ | デプロイして利用する業務ツール。案件管理や日報など | | メンバー | ワークスペースに参加している人 | | グループ | 部署やチームなど、アクセス権をまとめて設定するためのメンバーの集まり | | デプロイ | アプリのコードと設定を送り、Keelson 上で使える状態にすること | たとえば、同じワークスペースに「営業日報」と「経費申請」を作り、営業チームには営業日報、全社員には経費申請を共有できます。 ## アプリを開くときの仕組み Web アプリや静的サイトをデプロイすると、HTTPS で保護された専用 URL が発行されます。証明書の取得や更新は Keelson が行います。 ```text https://<ワークスペース>--<アプリ>.keelson.run ``` 通常のアプリ画面は、URL を知っているだけでは開けません。Keelson がログインとアプリの閲覧権限を確認し、許可されたアクセスだけをアプリに渡します。 ```text ブラウザ ↓ Keelson:ログイン・アプリの閲覧権限・IP 制御の条件を確認 ↓ アプリ:画面を表示し、業務の処理を実行 ``` アプリ側でログイン画面や Keelson のログインセッションを実装する必要はありません。誰がアクセスしているかは、Keelson が渡すユーザー情報で確認できます。 外部サービスからの Webhook など、ブラウザのログインを使わない呼び出しには別の設定を行います。詳しくは[外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/)を参照してください。 ## メンバーとアクセス権をまとめて管理する ### 同じワークスペースのアプリでログインを共有する ユーザーは 1 回ログインすれば、同じワークスペース内で閲覧権限のあるアプリを開けます。Keelson のログインをアプリごとにやり直す必要はありません。アプリが独自の外部認証も使っている場合は、そのログインが別途必要になることがあります。 ### グループにアプリごとの権限を設定する メンバーとグループはワークスペースで管理し、アプリごとにグループへ権限を割り当てます。 | 権限 | できること | |---|---| | 閲覧(`view`) | アプリを開いて利用する | | 管理(`manage`) | アプリをデプロイし、設定やシークレットを変更する | 新しいアプリには、既定で「全員に閲覧、開発者に管理」が割り当てられます。特定のチームだけに絞る場合は[チームにアプリを共有する](https://keelson.dev/ja/docs/access-control/share-with-team/)を参照してください。 **管理権限は、業務上の承認権限とは別です。** 「上司だけが申請を承認できる」「担当者だけが案件を編集できる」といったルールは、ユーザーやグループの情報を使ってアプリ側で実装します。 ## アプリと Keelson の役割分担 | 機能 | Keelson が用意すること | アプリで実装すること | |---|---|---| | 画面と業務処理 | アプリの URL と実行環境 | 入力画面、集計、申請などの機能 | | ログインと権限 | ログイン、メンバー管理、アプリを開ける人の確認 | 本人のデータだけ表示するなど、業務に応じた制御 | | データの保存 | Managed SQLite、Files / Media SDK | 保存先を使った読み書き | | API キーなどの秘密情報 | シークレットの保管とアプリへの受け渡し | 受け取った情報を使う外部サービスへの接続 | | 定期実行 | 設定した時刻・間隔で処理を起動 | 1 回分の処理を行って終了するコード | | 運用 | ログ、アプリ一覧、Managed SQLite のバックアップと復元 | 業務上の処理結果やエラーをログに記録すること | 通常は、AI エージェントに作りたい機能を伝え、アプリのコードと Keelson の設定を作成してもらいます。 ## 利用できる共通機能 ### API キーなどをシークレットとして管理する 共通の API キーはワークスペースに設定し、アプリへ環境変数として渡せます。アプリごとに別の値を設定して上書きすることもできます。秘密の値をコードや `keelson.yaml` に直接書く必要はありません。 詳しくは[環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/)を参照してください。 ### アプリ専用のデータベースを用意できる `keelson.yaml` に `db.mode: libsql` と書くと、アプリ専用の Managed SQLite が用意されます。接続情報は Keelson が渡しますが、接続してデータを読み書きするコードはアプリ側に必要です。 Managed SQLite にはバックアップと復元が付きます。Files / Media のファイルは、このバックアップの対象外です。保存先の選び方は[データベース](https://keelson.dev/ja/docs/building-apps/persistent-storage/)と[ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/)を参照してください。 ### 決まった時刻・間隔で処理を実行できる 毎朝の集計や定期的なデータ同期は、`keelson.yaml` の `crons` に設定します。Web アプリへのアクセスがなくても実行できます。設定方法は[定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/)を参照してください。 ### アプリの一覧から運用状況を確認できる コンソールでは、各アプリを誰が作ったか、誰が使えるか、最後にいつ利用・デプロイされたかを確認できます。作成者以外も、アプリの管理状況を把握できます。 ## 起動とデータ保存について知っておくこと - **アクセスがない状態が続くと、Web アプリは停止します。** 次のアクセスで起動するため、停止後の最初の応答には通常より時間がかかることがあります。レスポンスを返した後の処理は、最後まで実行されることが保証されません。 - **サーバー内のローカルファイルは、再起動・再デプロイで失われます。** この性質を「揮発性」と呼びます。残したいデータは Managed SQLite、Files SDK、Media SDK などに保存してください。 実装時の注意点は[アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)と[対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/)を参照してください。 ## 次に読む - [クイックスタート](https://keelson.dev/ja/docs/introduction/quickstart/) - [ログイン中のユーザー情報を使う](https://keelson.dev/ja/docs/building-apps/using-identity/) - [メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/) - [デプロイする](https://keelson.dev/ja/docs/deploy/deploy/) --- # FAQ 導入前によく聞かれること URL: https://keelson.dev/ja/docs/introduction/faq/ Language: ja --- 対応アプリ、料金、アクセス権、データについて、導入前によくある質問をまとめました。設定や操作の詳細は、各回答のリンク先を参照してください。 ## 対応アプリと実行環境 ### Lovable / Bolt / v0 で作ったアプリはデプロイできますか 構成によります。ビルド済みの HTML・CSS・JavaScript は静的サイトとして、Next.js などサーバー側の処理があるものは Web アプリとしてデプロイできます。静的サイトは手元でビルドし、外部サービスの接続先なども設定しておきます。 外部から接続できる DB やストレージは使い続けられますが、作成ツール内のデータや認証機能が自動で移るわけではありません。まず AI エージェントにコードの確認を依頼してください。詳しくは[持ち込みガイド](https://keelson.dev/ja/docs/building-apps/bring-your-app/)を参照してください。 ### Keelson 向けに作ったアプリは、ほかの環境でも動きますか はい。Keelson 専用のフレームワークで作る必要はなく、ほかのホスティングサービスや自分のサーバー、自分の PC のローカル環境でも動かせます。 動かす環境に合わせて、Python / Node.js などの実行環境や依存パッケージを用意し、起動設定やデータベースの接続先などを設定します。Keelson に任せていたログイン保護・アクセス制御・定期実行が必要な場合は、その環境で用意します。Keelson 固有の認証情報や Files / Media SDK を使っている部分は、コードの変更やデータの移行が必要です。 ### Streamlit は動きますか 現在は動きません。Streamlit は WebSocket が必須で、Keelson の実行モデルと合わないためです。Gradio は検証中です。[対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/)を参照してください。 ### Django は使えますか 現在は未対応です。Keelson の Managed SQLite(libSQL)と Django ORM の互換性に制約があるためです。[フレームワーク別の注意点](https://keelson.dev/ja/docs/building-apps/frameworks/#django)を参照してください。 ### アプリはずっと起動していますか いいえ。Web アプリはアクセスがない状態が続くと停止し、次のアクセスで起動します。そのため、停止後の最初の応答には通常より時間がかかることがあります。 決まった時刻の処理は定期実行ジョブに設定します。レスポンスを返した後のバックグラウンド処理は、最後まで実行されることが保証されません。詳しくは[アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)を参照してください。 ## 料金と利用上限 ### 料金はいつから発生しますか 14 日間の無料トライアルの終了後です。Starter / Plus はカード登録なしで始められ、終了までにカードを登録しなければ課金されずに終わります。Team はトライアル開始時にカード登録が要ります。[料金と契約の運用](https://keelson.dev/ja/docs/workspace/billing/#料金はいつから発生するか)。 ### 作る人が 2 人、使う人が 50 人なら、どのプランですか Plus 以上です。開発・管理する人が 2 人なら、Developers の席が 2 席必要です。利用者 50 人は App User として追加でき、その人数は料金に影響しません。 Developers の席には Owner / Admin / Developer を数えます。あわせて「同時に使えるアプリ数」(Starter 1、Plus 2、Team 4)が用途に合うかを確認してください。詳しくは[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)を参照してください。 ### アプリを 10 個保存して、普段は一部だけ使う場合、何が上限になりますか 有料契約中は保存数に上限がなく、上限は「同時に動かせる数」だけです。直近 5 分にアクセスがあったアプリだけが枠を使い、使われていないアプリはスリープして枠を空けます。トライアル中だけは保有数も 3 個まで(静的サイトとしてデプロイ済みのアプリは数えません)です。[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/#同時に使えるアプリ数)。 ### 同時に使えるアプリ数の上限に達すると、利用者には何が表示されますか 同時に動かせるアプリ数の上限に達していると、スリープ中のアプリを開いた利用者には、起動できる枠が空くまで待つよう案内する画面が表示されます。枠を使っているアプリへのアクセスが約 5 分途絶えると、その枠が空きます。他のアプリが使われ続けている間は空きません。重要なアプリには[優先起動](https://keelson.dev/ja/docs/deploy/app-status-and-logs/#優先起動)(Plus 以上)で枠を予約できます。 ### アプリ内で使う OpenAI などの API 利用料は、Keelson の料金に含まれますか 含まれません。アプリから外部 API を呼ぶ費用は、その API の提供元との契約です。API キーはシークレットとして設定してアプリから利用します。[外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/)。 ## アクセス権とデータ ### URL を知っている人は誰でも開けますか 開けません。ワークスペースのメンバーがログインし、そのアプリの閲覧権限を持っている場合だけ表示されます。ログインしていない人にはログイン画面が出ます。社外の人に見せるには、その人をメンバーとして招待します(App User は人数無制限)。[認証とログイン](https://keelson.dev/ja/docs/access-control/auth-and-login/)。 ### データはどこに置かれますか。バックアップはありますか アプリとその Managed SQLite は、日本リージョンに配置されます。 ※ 米国西海岸リージョンは近日リリース予定です。 Managed SQLite には、全プランでバックアップと復元が付きます。Files / Media SDK のファイルや外部 DB は、このバックアップの対象外です。 日次バックアップ、手動バックアップ、時刻を指定した復元(PITR)、ダウンロードが使えます。詳しくは[データベース](https://keelson.dev/ja/docs/building-apps/persistent-storage/#バックアップと復元)を参照してください。 ### アプリを更新すると、保存したデータは消えますか Managed SQLite、Files SDK、Media SDK に保存したデータは、通常の再デプロイだけでは消えません。一方、アプリが動くサーバー内のローカルファイルは、再起動・再デプロイで失われます。 DB の変更処理やアプリのコードでデータを削除・更新した場合は、その変更が反映されます。保存先の違いは[データベース](https://keelson.dev/ja/docs/building-apps/persistent-storage/)、変更を戻す方法は[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/)を参照してください。 ### トライアル終了・プラン変更・解約のとき、アプリとデータはどうなりますか どの場合も、アプリとデータがその場で消えることはありません。契約が終了すると新しいデプロイと起動がブロックされ、14 日の猶予の後に自動削除されます。猶予中に再契約すれば残ります。プランのダウングレードは請求期間の終わりに適用され、上限を超えている分は起動できなくなります。[料金と契約の運用](https://keelson.dev/ja/docs/workspace/billing/#解約後のアプリとデータ)。 # アプリを作る --- # 対応アプリと制約 Keelson にデプロイできるアプリと、対応ランタイム・実行環境の制約 URL: https://keelson.dev/ja/docs/building-apps/supported-app-types/ Language: ja --- Keelson は、Python・Node.js・Go の Web アプリ、静的サイト、定期実行ジョブに対応しています。 フレームワークやデータの保存方法によっては、コードや設定の変更が必要です。以下の表で対応状況を確認してください。 Dockerfile は不要です。アプリに含まれていても、Keelson のビルドには使用されません。 ## アプリの対応状況 | アプリ | 対応状況 | 補足 | |---|---|---| | Python の Web アプリ(FastAPI、Flask など) | 対応 | 環境変数 `PORT` で指定されたポートで起動。Flask は gunicorn を使用 | | Node.js の Web アプリ(Express、Hono、Next.js など) | 対応 | 環境変数 `PORT` で指定されたポートで起動。Next.js は `next start` | | Go の Web アプリ(net/http、Gin など) | 対応 | Keelson がビルドして `./app` で起動 | | ビルド済みの静的サイト / SPA(React、Vue、Svelte など) | 対応 | `assets` にビルド出力を指定 | | フロントエンド(静的)+ バックエンド API | 対応 | hybrid 構成。`assets.api` で API のパスを指定 | | 定期実行だけ(Web UI なし) | 対応 | `crons` だけを定義 | | 外部の PostgreSQL / MySQL / libSQL に接続する | 対応 | `db.mode: none`。接続情報はシークレットで渡す | | 外部 API(OpenAI、Slack、Google Sheets など)を呼ぶ | 対応 | 外部通信は制限なし | | ファイル SQLite を使っている(`sqlite3`、`better-sqlite3` など) | 変更が必要 | libSQL クライアントに置き換えて `db.mode: libsql` | | ローカルファイルにデータを保存している | 変更が必要 | Managed SQLite か Files SDK / Media SDK へ。ローカルディスクは再起動で消える | | アプリ内でタイマーやバックグラウンドスレッドを動かしている | 変更が必要 | リクエスト処理中に完了させるか、定期実行ジョブに移す([アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)) | | Django | 現在未対応 | Keelson の Managed SQLite(libSQL)と Django ORM の互換性に制約があるため、現在は対応していません | | Streamlit | 未対応 | WebSocket が必須のため、現在は動きません([フレームワーク別の注意点](https://keelson.dev/ja/docs/building-apps/frameworks/#streamlit--gradio)) | | Gradio | 検証中 | 4 以上を検証中。現時点では動作を保証しません | | Ruby / PHP / Java / Rust / .NET / Elixir | 未対応 | 対応ランタイムは Python / Node.js / Go のみ | | Dockerfile で apt パッケージを追加している | 未対応 | root 権限なし。画像・動画系は `-media` ランタイムで代替できる場合あり | | 常駐プロセス・デーモン・WebSocket サーバー前提 | 未対応 | アイドル時に停止する実行モデルと合わない | | Redis / Kafka / DB サーバーを自前で起動する | 未対応 | 外部サービスとして接続するのは可 | | GPU が必要 | 未対応 | | 「変更が必要」のアプリは、コードや設定を変更して対応できる場合があります。AI エージェントに確認を依頼すると、必要な変更を提案します。 他のツールで作ったアプリ(Lovable、Bolt、v0 など)をデプロイする手順は[持ち込みガイド](https://keelson.dev/ja/docs/building-apps/bring-your-app/)にあります。 > **ヒント: AI に判定してもらう** > > AI エージェントに次の URL を渡し、「このアプリを Keelson にデプロイできるか確認してください」と依頼してください。アプリのコードを確認し、必要なコードや設定の変更を提案します。 > > ``` > https://keelson.dev/ja/docs/reference/deploy-spec.txt > ``` ## ランタイム `keelson.yaml` の `runtime` で選びます。迷ったら `-slim` から始め、画像・動画・PDF 処理のライブラリ(Pillow、sharp、ffmpeg など)が必要になったら `-media` に切り替えます。 | ランタイム | 言語バージョン | ビルド時の処理 | |---|---|---| | `python-slim` / `python-media` | Python 3.12 | `requirements.txt` または `pyproject.toml` から自動インストール | | `node-slim` / `node-media` | Node.js 24 | `package.json` と `package-lock.json` から依存を自動インストール。`npm run build` があれば実行 | | `go-slim` / `go-media` | Go 1.26 | `go.mod` から `go build` し、`./app` として起動 | Go のバージョンは、ビルドに使用するツールチェーンのバージョンです。依存パッケージはビルド時にインストールされます。`command` には起動コマンドだけを書きます。 - **Node.js:** ビルドには npm を使います。`pnpm-lock.yaml` / `yarn.lock` のみの構成は対応していないため、`package-lock.json` を用意してください。 - **Go:** `CGO_ENABLED=0` でビルドします。cgo に依存するライブラリは使用できません。 依存ファイルの要件やビルドの制約は、[keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#依存関係のインストール)を参照してください。 ## 実行環境の制約 | 項目 | 内容 | |---|---| | OS / CPU | Linux / x86_64 | | 権限・システムパッケージ | 非 root で動作します。`sudo` や `apt-get` は使えません | | Web サーバーの起動 | `0.0.0.0` と環境変数 `PORT` で指定されたポートで待ち受けます | | データの保存 | ローカルファイルは永続保存されません。残したいデータには Managed SQLite や Files / Media SDK を使います | | 処理の実行 | リクエスト処理と定期実行ジョブに対応します。詳しくは[アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)を参照してください | 実行時間やアプリ数などの上限は[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)を参照してください。 ## 最小構成 Python(FastAPI)の例です。`keelson.yaml` と `requirements.txt` と `app.py` の 3 ファイルでデプロイできます。 ```yaml # keelson.yaml slug: my-app runtime: python-slim command: "python app.py" db: mode: none ``` ```text # requirements.txt fastapi uvicorn ``` ```python # app.py import os from fastapi import FastAPI import uvicorn app = FastAPI() @app.get("/") def index(): return {"message": "Hello from Keelson"} if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=int(os.environ["PORT"])) ``` 通常は AI エージェントが `keelson.yaml` を書くので、自分で作る必要はありません。 ## 次に読む - [keelson.yaml の設定](https://keelson.dev/ja/docs/building-apps/keelson-yaml/) — 設定ファイルの入門 - [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/) - [ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/) — Files / Media SDK - [定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/) - [Keelson Deploy Spec](https://keelson.dev/ja/docs/reference/deploy-spec/) — AI エージェント向けの正本 --- # アプリが動くタイミング Web アプリの起動と停止、リクエスト処理と定期実行ジョブの使い分け URL: https://keelson.dev/ja/docs/building-apps/how-apps-run/ Language: ja --- Keelson は、アクセスに応じて Web アプリを起動し、アクセスがない状態が続くと停止します。次のアクセスがあると、再び起動します。 画面表示や API の処理はリクエストを受けて実行し、毎日の集計などは Keelson の定期実行ジョブで実行します。アプリが常に起動していることを前提にした処理には対応していません。 ## Web アプリの起動と停止 アプリが停止しているときにリクエストを受けると、Keelson がアプリを起動します。このため、停止後の最初のアクセスでは、通常より応答に時間がかかることがあります。 再起動すると、メモリ上の変数やローカルファイルに保存したデータは引き継がれません。残しておきたいデータは、Managed SQLite や Files / Media SDK に保存してください。 詳しくは[データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/)と[ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/)を参照してください。 ## リクエストに応じて実行する処理 データの保存や外部 API の呼び出しなど、そのリクエストで必要な処理は、レスポンスを返すまでに完了させてください。 レスポンスを返した後にバックグラウンドで続ける処理は、最後まで実行されることが保証されません。FastAPI の `BackgroundTasks` や、完了を待たずに開始する非同期処理を使う場合は、処理方法の変更が必要です。 AI の回答生成など、結果を少しずつ返す処理にはストリーミングを利用できます。ただし、接続が切れた後も処理を続ける仕組みとしては利用できません。 ## 決まった時刻・間隔で実行する処理 毎朝のレポート作成や定期的なデータ同期は、`keelson.yaml` の `crons` に設定します。Web アプリにアクセスがなくても、設定したスケジュールに従って実行されます。 ジョブは Web アプリとは別の実行環境で起動し、指定したコマンドの処理が終わると終了します。Web アプリと共有するデータは、データベースなどに保存してください。 アプリ内のタイマーやスケジューラで時刻を待つ方法は、アプリの停止中には動作しません。定期的な処理は Keelson の定期実行ジョブに設定してください。 設定方法は[定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/)を参照してください。 ## 処理に合わせた実装方法 | やりたいこと | 実装方法 | |---|---| | フォームの内容を保存する | リクエスト処理中に保存し、結果を返す | | AI の回答を順次表示する | リクエスト処理中にストリーミングで返す | | 毎朝レポートを作成する | 定期実行ジョブに設定する | | 外部サービスと定期的に同期する | 1 回分の同期処理を定期実行ジョブで実行する | | 受け付けた処理を後でまとめて実行する | 未処理の内容を DB に保存し、定期実行ジョブで処理する | DB に保存して後で処理する方法では、次のジョブ実行まで待ち時間が発生します。すぐに開始する必要がある処理には適していません。また、処理の重複や失敗に備える必要があります。詳しくは[定期実行ジョブの設計](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/#設計のルール)を参照してください。 Keelson は、任意のバックグラウンド処理を即座に開始するタスク実行 API や、常駐ワーカーを提供していません。 ## ブラウザ側の処理 ここまでの説明は、サーバー側の処理が対象です。ブラウザ側のタイマーや画面の自動更新に、この制約は適用されません。 ## 実行時間の上限 HTTP リクエストと定期実行ジョブには、それぞれ実行時間の上限があります。長い処理は、上限内に完了する単位に分けてください。 詳細は[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/#http-の時間上限)と[定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/)を参照してください。 ## 関連ページ - [対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/) - [定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/) - [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/) - [ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/) --- # 他のツールで作ったアプリを持ち込む 手元のアプリを AI エージェントで確認し、データやログインの設定を整えてデプロイする URL: https://keelson.dev/ja/docs/building-apps/bring-your-app/ Language: ja --- Lovable、Bolt、v0 などで作ったアプリや、手元で開発したアプリも、ソースコードがあれば Keelson へのデプロイを検討できます。対応できるかどうかは、使ったツールの名前ではなく、アプリの言語やデータの保存方法で決まります。 まず AI エージェントにコードを確認してもらい、必要な変更を確認してからデプロイします。**外部サービスにあるデータや利用者のアカウントは、コードをデプロイしただけでは Keelson に移りません。** ## 1. ソースコードを用意する 作成したツールからコードをエクスポートするか、Git リポジトリを手元に取得し、アプリのフォルダを AI エージェントで開きます。 Keelson CLI とエージェント用の Skill の準備、Keelson へのログインがまだの場合は、[クイックスタート](https://keelson.dev/ja/docs/introduction/quickstart/)を先に進めてください。 ## 2. エージェントに確認を頼む 次のように依頼してください。 > このアプリを Keelson にデプロイしたいです。コードを確認し、対応できるかと必要な変更を説明してください。データベース、ログイン、ファイルの保存先、定期的な処理を確認し、既存のデータや利用者のアクセス権に影響する変更は、実施前に説明してください。 エージェントが確認するのは、主に次の点です。 | 確認すること | 確認する理由 | |---|---| | アプリの言語とフレームワーク | Keelson の対応範囲と、起動・ビルド方法を確認するため | | データの保存先 | 外部 DB を使い続けるか、Managed SQLite に変更するかを判断するため | | ログインとアクセス権 | 既存の利用者が自分のデータを引き続き使えるようにするため | | ファイルの保存先 | 再起動で消える保存方法になっていないかを確認するため | | タイマーやバックグラウンド処理 | リクエスト処理や Keelson の定期実行ジョブに変更する必要があるかを確認するため | 対応している言語・フレームワークは[対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/)、処理の実行方法は[アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)にまとめています。 ## 3. データとログインの扱いを確認する ### 外部のデータベースやストレージを使っている場合 アプリから接続できる外部サービスは、デプロイ後も使い続けられます。この場合、データを移す必要はありません。たとえば、外部 DB を使うアプリは `db.mode: none` にし、接続情報を設定します。 サーバー側で使う API キーやパスワードは[シークレット](https://keelson.dev/ja/docs/deploy/environment-variables/)で渡します。ブラウザ側で使うサービスの URL や公開用のキーは、そのサービスの案内に従って設定してください。秘密の値をブラウザに送るコードへ埋め込まないでください。 Supabase などをブラウザから直接呼ぶ構成では、外部サービス側のアクセス権設定も引き続き必要です。Keelson のログインでアプリを保護しても、外部サービスのデータ権限が自動で置き換わるわけではありません。 ### すでにログイン機能がある場合 Keelson では、アプリを開くときに Keelson のログインが必要です。元のログイン機能を残すと、利用者は両方にログインすることになります。 元のログインを外せるかどうかは、ユーザーの識別やデータのアクセス権に使っているかで判断します。 | 元のログインの役割 | 対応方法 | |---|---| | アプリを開く人を制限するためだけに使っている | Keelson のログインとアプリのアクセス権に置き換えることを検討できます | | ユーザーごとに見せるデータを制限している | 元の認証を残すか、Keelson のユーザー情報を使って権限を判定するように変更します | | データに元のサービスのユーザー ID を保存している | 既存のユーザーと Keelson のユーザーをどう対応付けるかを決めます | たとえば Supabase の RLS(行ごとのアクセス制御)で `auth.uid()` を使っている場合、ログイン機能だけを外すと、誰のデータかを判定できなくなります。ログイン画面を削除する前に、データへのアクセス方法を確認してください。 ### アプリ内のファイルに保存している場合 アプリが動くサーバー内のファイルは、再起動・再デプロイで失われます。残したいものに合わせて保存方法を変更します。 | 残したいもの | Keelson の保存先 | |---|---| | 顧客情報、案件、申請など、検索・更新するデータ | [Managed SQLite](https://keelson.dev/ja/docs/building-apps/persistent-storage/) | | アプリ内部の設定ファイルや処理済みデータの記録 | [Files SDK](https://keelson.dev/ja/docs/building-apps/files-and-media/#files-sdk) | | 画面に表示する画像、利用者が開く PDF や添付ファイル | [Media SDK](https://keelson.dev/ja/docs/building-apps/files-and-media/#media-sdk) | 保存先を変更する場合は、コードの変更に加えて、既存データを移す手順もエージェントに確認してください。 ## 4. デプロイする 変更内容を確認したら、エージェントに依頼します。 > 確認した内容で必要な変更と keelson.yaml の作成を行い、このアプリを Keelson にデプロイしてください。 エージェントはアプリの構成に合わせて設定を作成します。主な構成は次のとおりです。設定を自分で書く必要はありません。 | アプリの構成 | デプロイ方法 | |---|---| | 静的サイト / SPA(ビルド済みの HTML・CSS・JavaScript) | ビルドしたファイルを `assets` に指定して配信します。外部サービスの API をブラウザから呼ぶアプリも含みます | | サーバー側の処理がある Web アプリ(Next.js、Express、FastAPI など) | `command` で Web サーバーを起動します | | 静的な画面と API サーバーを組み合わせたアプリ | `assets` と `command` を設定し、`assets.api` で API のパスを指定します(ハイブリッド構成) | 設定の読み方は [keelson.yaml の設定](https://keelson.dev/ja/docs/building-apps/keelson-yaml/)、操作手順は[デプロイする](https://keelson.dev/ja/docs/deploy/deploy/)を参照してください。 ### 静的サイトのビルドについて 静的サイトは、手元でビルドしてからデプロイします。Keelson にアップロードされるのは `assets.dir` の中身と `keelson.yaml` で、Keelson 上で `npm install` や `npm run build` は実行されません。 ビルド時に読み込むサービスの URL や公開用のキーは、ビルド前に設定します。デプロイ後にサーバーの環境変数を設定しても、ビルド済みの画面には反映されません。エージェントには、設定を含めてビルドとデプロイを依頼してください。 ## 5. デプロイ後に確認する - Keelson の URL で画面が開き、必要な操作ができる - 既存のデータが表示され、追加・更新したデータも保存される - 画像や添付ファイルを表示・閲覧できる - 元の認証を残した場合も含め、想定したログイン手順で利用できる - 他のメンバーも利用でき、見せるべきでないデータは表示されない ## コードと一緒には移らないもの 作成ツールが提供するデータベース、認証、ファイル保存、サーバー側の関数は、ソースコードだけをデプロイしても移りません。外部から利用できるものは接続を維持し、利用できないものはデータの移行や処理の書き換えが必要です。 作成ツール内の編集機能も Keelson には移りません。デプロイ後のコード変更は、手元の AI エージェントなどで行い、再デプロイして反映します。 ## 関連ページ - [対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/) - [keelson.yaml の設定](https://keelson.dev/ja/docs/building-apps/keelson-yaml/) - [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) - [フレームワーク別の注意点](https://keelson.dev/ja/docs/building-apps/frameworks/) --- # keelson.yaml の設定 AI エージェントが作成する設定ファイルの役割と、確認しておきたい項目 URL: https://keelson.dev/ja/docs/building-apps/keelson-yaml/ Language: ja --- `keelson.yaml` は、アプリの起動方法やデータベースの利用、定期実行などを Keelson に伝える設定ファイルです。アプリのソースコードと同じフォルダの一番上(プロジェクトルート)に置きます。 **通常は、デプロイを依頼した AI エージェントが作成・更新します。** このページでは、エージェントが作った設定を確認するときに役立つ項目を説明します。すべての設定項目や細かい条件は [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/)を参照してください。 ## 設定ファイルの例 Python の Web アプリで、Keelson のデータベースを使う例です。 ```yaml slug: my-app # アプリの識別子 runtime: python-slim # Python の実行環境 command: "python app.py" # Web サーバーを起動するコマンド db: mode: libsql # Keelson の Managed SQLite を使う ``` | 項目 | 確認すること | |---|---| | `slug` | アプリを識別する名前です。`https://<ワークスペース>--.keelson.run` の一部になります | | `runtime` | アプリの言語に合う実行環境です。Python / Node.js / Go から選びます | | `command` | アプリの Web サーバーを起動するコマンドです。依存パッケージのインストールはビルド時に行われます | | `db.mode` | Keelson のデータベースを使うなら `libsql`、使わない場合や外部 DB を使う場合は `none` です | `db.mode: libsql` はデータベースを用意する設定です。アプリのコードにも、用意された DB に接続して読み書きする処理が必要です。既存のファイル SQLite が、この設定だけで Managed SQLite に切り替わるわけではありません。 Files / Media SDK だけを使うアプリは `db.mode: none` で構いません。Files / Media の利用を宣言する設定は不要です。 ## アプリの構成による違い どのアプリにも `slug`、`runtime`、`db.mode` が必要です。そのほかの項目は、アプリの構成で変わります。 | アプリの構成 | 主な設定 | |---|---| | Web アプリ | `command` に起動コマンドを書く | | 静的サイト / SPA | `type: web` と `assets` を設定し、`command` は書かない | | 静的な画面 + API サーバー(ハイブリッド) | `assets` と `command` の両方を設定する | | 定期実行だけのアプリ | `crons` を設定し、Web サーバー用の `command` は書かない | Web アプリに `crons` を追加することもできます。定期実行の設定は[定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/)を参照してください。 ### 静的サイト / SPA ビルド済みのファイルを配信する例です。`assets.dir` にはビルド出力のフォルダを指定します。 ```yaml slug: my-site type: web runtime: node-slim db: mode: none assets: dir: dist fallback: index.html # SPA で、画面の URL を直接開いたときにも index.html を返す ``` 静的サイトは手元でビルドしてからデプロイします。Keelson 上で依存パッケージのインストールやビルドは行われません。通常の静的サイトで、見つからないページを `index.html` に戻す必要がなければ `fallback` は省略できます。 ### 静的な画面 + API サーバー `/api` 以下へのリクエストをサーバーで処理し、それ以外ではビルド済みの画面を配信する例です。 ```yaml slug: my-app runtime: node-slim command: "node server.js" db: mode: libsql assets: dir: dist fallback: index.html api: /api ``` ## 必要に応じて追加する設定 | やりたいこと | 設定 | 詳しくは | |---|---|---| | アプリの説明を付ける | `description` | [リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#description) | | アプリに設定値を渡す | `env` | [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) | | API キーなどを使う | `secrets` に必要な名前を宣言する。秘密の値は書かない | [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) | | デプロイ時に DB のテーブルや列を変更する | `db.migrate` | [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/) | | 決まった時刻・間隔で処理を実行する | `crons` | [定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/) | | 起動確認に使うページを指定する | `health.path` | [リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#health) | | 外部サービスから Webhook を受け取る | `auth.endpoints` | [外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/) | ## デプロイ前に確認すること - **アプリ名と保存先が意図どおりか。** `slug` が対象アプリの名前か、`db.mode` が利用するデータベースに合っているかを確認します。 - **API キーやパスワードが直接書かれていないか。** `secrets` には名前と説明だけを書き、値はコンソールなどから設定します。 - **必要な定期処理が設定されているか。** アプリ内のタイマーに任せず、`crons` のスケジュールを確認します。 起動コマンドや依存ファイルの確認は、エージェントに依頼できます。次のコマンドでは、アップロードせずに設定と送信対象のファイルを確認できます。 ```bash keelson deploy --check --json ``` この確認だけでは、実際にアプリが起動するかやプランの上限内かまでは分かりません。デプロイ後はアプリの URL を開き、動作を確認してください。 ## 設定を変更したら `keelson.yaml` の変更は、次のデプロイで反映されます。エージェントに「設定を変更して再デプロイしてください」と依頼してください。 `PORT` など Keelson が設定する環境変数や、廃止された設定項目は自分で追加する必要はありません。古い設定を引き継ぐ場合や検証エラーが出た場合は、[keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/)を参照してください。 ## 次に読む - [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/) - [デプロイする](https://keelson.dev/ja/docs/deploy/deploy/) - [対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/) — ランタイムのバージョンと制約 --- # データベース(Managed SQLite) 顧客情報や業務データを残すための保存先と、データベースの使い方・バックアップ・復元 URL: https://keelson.dev/ja/docs/building-apps/persistent-storage/ Language: ja --- 顧客情報、案件、申請内容など、アプリで登録・検索・更新するデータには **Managed SQLite** を使います。Keelson がアプリ専用に用意するデータベースで、保存したデータはアプリを再起動・再デプロイしても残ります。 ## 何をどこに保存するか 画像や設定ファイルにも、再起動後に残せる保存先があります。保存したいものと用途で選びます。 | 保存したいもの・用途 | 保存先 | |---|---| | 顧客情報、案件、申請などを登録・検索・更新する | **Managed SQLite** | | 設定ファイルや処理済みデータの記録を、アプリ内部で読み書きする | **Files SDK** | | 画像を画面に表示する、PDF や添付ファイルを利用者が開く | **Media SDK** | たとえば案件管理アプリなら、案件名や担当者は DB に、添付 PDF は Media に保存します。DB には添付ファイルの ID も記録し、案件とファイルを関連付けます。 ファイルの保存方法は[ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/)を参照してください。 ## ローカルファイルは消える ここでいう「ローカルファイル」は、**Keelson 上でアプリが動くサーバー内に書き込むファイル**です。アプリを再起動・再デプロイしたり、アクセスがなくなって停止したりすると、そのファイルは失われます。この性質を「揮発性」と呼びます。 `./data.db`、`/tmp/data.db`、`/data/main.db` のように保存先のフォルダを変えても、再起動後にデータを残すことはできません。定期実行ジョブは Web アプリとは別の環境で動くため、これらのファイルを共有することもできません。 アップロードの受け取りや変換途中のファイルなど、処理中だけ使う一時ファイルは `/tmp` に置いて構いません。後で必要になるデータは、上の表の保存先に保存してください。 ### ファイル SQLite を使っているアプリ `sqlite3` や `better-sqlite3` でファイルに保存している場合は、Managed SQLite に接続するコードへ変更します。AI エージェントに、次のように依頼できます。 > このアプリのデータが、Keelson で再起動・再デプロイした後も残るようにしてください。ファイル SQLite を使っている箇所を確認し、Managed SQLite への変更と、既存データの移し方を説明してください。 ファイル SQLite を使うコードはデプロイ時に検出され、宣言がなければ拒否されます。再生成できるキャッシュ用途に限り、`db.local_sqlite` で一時ファイルの利用を宣言できます。この設定でもファイルは再起動後に残りません。詳しくは[リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#db)を参照してください。 ## Managed SQLite を使う `keelson.yaml` に次の設定を書くと、アプリ専用のデータベースが用意されます。通常は AI エージェントが設定と接続コードを作成します。 ```yaml db: mode: libsql ``` - **DB サーバーの準備は不要です。** 接続 URL と認証トークンは、Keelson がアプリの環境変数に設定します。 - **アプリごとにデータを分けます。** 接続用の認証情報でアクセスできるのは、そのアプリの DB だけです。 - **保存を確定したデータは再起動後も残ります。** SQL のコミットが完了した時点で保存されます。 - **日本リージョンに配置されます。** 米国西海岸リージョンは近日リリース予定です。 - **バックアップから戻せます。** 日次バックアップ、手動バックアップ、指定時刻への復元に対応しています。 ### 接続コード 設定ファイルの変更に加えて、アプリ側も libSQL クライアントで DB に接続する必要があります。SQL は SQLite と同じように書けますが、ローカルのファイルパスではなく、Keelson が渡す接続 URL と認証トークンを使います。対応クライアントは Python・Node.js・Go で利用できます。 以下はテーブルを作り、データを 1 件保存する例です。Python は `libsql`、Node.js は `@libsql/client` を依存パッケージに追加します。 #### Python ```python import os, libsql conn = libsql.connect( database=os.environ["KEELSON_DB_URL"], auth_token=os.environ["KEELSON_DB_AUTH_TOKEN"], ) conn.execute(""" CREATE TABLE IF NOT EXISTS items ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP ) """) conn.execute("INSERT INTO items (name) VALUES (?)", ("サンプル",)) conn.commit() ``` #### Node.js ```javascript import { createClient } from "@libsql/client"; const db = createClient({ url: process.env.KEELSON_DB_URL, authToken: process.env.KEELSON_DB_AUTH_TOKEN, }); await db.execute(` CREATE TABLE IF NOT EXISTS items ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP ) `); await db.execute({ sql: "INSERT INTO items (name) VALUES (?)", args: ["サンプル"] }); ``` ### テーブルや列を追加・変更する 顧客名や案件名など、何を保存するかを定義したものを「スキーマ」と呼びます。テーブルがまだなければ、上の例のように `CREATE TABLE IF NOT EXISTS` で作成できます。 デプロイに合わせてテーブルや列を変更する場合は、`db.migrate` に変更用のコマンドを書きます。この処理を「マイグレーション」と呼びます。 ```yaml db: mode: libsql migrate: "python migrate.py" ``` `db.migrate` は新しいコードに切り替える前に実行されます。失敗した場合は、それまでのコードでアプリの提供を続けます。ただし、DB に加えた変更は自動では戻りません。 同じコマンドがデプロイのたびに実行されても結果が壊れないようにし(冪等性)、それまでのコードでも読み書きできる変更にしてください。詳しくは[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/)を参照してください。 ### 同時書き込み SQLite は、同時に書き込みを行う処理を 1 つずつ実行します。Web アプリと定期実行ジョブなどが同時に書き込むと、待ち時間が発生することがあります。書き込みが集中し、応答時間に影響する場合は、処理の見直しや外部の PostgreSQL などを検討してください。 ## 外部データベースを使う すでに使っている PostgreSQL、MySQL、外部の libSQL などに接続する場合は、`db.mode: none` にします。接続情報は自分で用意し、シークレットとして設定してください。この設定で Keelson が外部 DB を作成したり、既存のデータを移したりすることはありません。 ```yaml db: mode: none secrets: items: - name: DATABASE_URL description: "PostgreSQL の接続文字列" required: - all_of: [DATABASE_URL] ``` Django は現在未対応です。詳しくは[フレームワーク別の注意点](https://keelson.dev/ja/docs/building-apps/frameworks/#django)を参照してください。 外部 DB を使う主なケースです。 | ケース | 選択肢 | |---|---| | データ量や必要な処理速度が Managed SQLite では対応できない | 外部 PostgreSQL | | 同時書き込みが非常に多い | PostgreSQL、MySQL | | BI ツールや基幹システムから直接参照する | 共有の PostgreSQL、データウェアハウス | | Keelson のプランより長い期間のバックアップが必要 | 外部のマネージド DB | ## バックアップと復元 誤ってデータを削除・更新した場合に備えて、すべてのプランでバックアップと復元を利用できます。 | 方法 | 用途 | |---|---| | 日次バックアップ | 毎日自動で保存されるバックアップから戻す | | 手動スナップショット | 大きな変更の前など、必要なタイミングでバックアップを作る(1 アプリ 1 日 5 回まで) | | 時刻復元(PITR) | 戻せる期間内の時刻を指定し、その時点のデータに戻す | | ダウンロード | バックアップや指定時刻のデータを手元に保存する | ### 保存されるバックアップと戻せる期間 | | Starter | Plus | Team | |---|---|---|---| | 日次バックアップの保存数 | 1 回分 | 3 回分 | 7 回分 | | 時刻を指定して戻せる期間 | 過去 24 時間 | 過去 7 日 | 過去 14 日 | コンソールのアプリ画面で「復元ポイント」を開き、タイムライン上のバックアップや時刻を選ぶと、復元やダウンロードができます。 復元はアプリ単位で、他のアプリには影響しません。復元前の状態は 72 時間保持され、その間は復元を取り消せます。復元の実行には、ブラウザでの承認が必要です。 ### 復元の対象 このバックアップで戻せるのは **Managed SQLite のデータだけ**です。Files / Media SDK のファイル、外部 DB、アプリのコードや設定は対象外です。 たとえば、DB に保存した添付ファイルの ID を復元しても、Media から削除済みのファイル本体は戻りません。コードや設定を含めた変更の戻し方は[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/)を参照してください。 ## 容量 - Managed SQLite にはプランごとの固定上限はありません。ただし、基盤側の技術上限は適用されます。また、平常の業務利用を著しく超える負荷や、プラットフォームの安定運用・他のお客様の利用・当社の合理的な運用コストに影響を及ぼす利用を検知した場合、アプリの実行を制限または停止することがあります。緊急時は事前の通知なく制限することがあります - ワークスペースのストレージ(Files / Media SDK のファイル、スナップショット、デプロイ用ファイルなどの合計)はプランごとに上限があります。DB の容量はこれとは別枠です プラン別の制限は[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)を参照してください。 ## 関連ページ - [ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/) - [定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/) — Web と cron で状態を共有する - [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#db) --- # ファイルとメディア アプリ内部で使う Files と、画像や添付ファイルを URL で表示する Media の使い分け URL: https://keelson.dev/ja/docs/building-apps/files-and-media/ Language: ja --- アプリの再起動・再デプロイ後も残したいファイルは、Files SDK または Media SDK で保存します。SDK は、アプリのコードから保存・読み取りなどを行うためのライブラリです。 **アプリ内部で読み書きするファイルには Files、画面に表示したり利用者が開いたりするファイルには Media を使います。** Media に保存すると、ブラウザから直接開ける URL を使えるため、画像表示や添付ファイルの閲覧に適しています。 ## 用途で選ぶ | | Files SDK | Media SDK | |---|---|---| | 主な用途 | アプリ内部の処理に使うファイルを保存・更新する | 利用者に画像を見せる、PDF や添付ファイルを開いてもらう | | 例 | 設定 JSON、処理済み URL の一覧、中間集計ファイル | 商品写真、申請書 PDF、利用者向けのレポート | | 読み取り方 | サーバー側のコードが SDK で読み取る。配信用 URL は付かない | サーバー側のコードで読み取れるほか、ブラウザから URL で開ける | | 更新方法 | 同じ名前(キー)で上書きできる。更新頻度の目安は 1 キーにつき 1 秒に 1 回程度 | 上書きせず、新しいファイルとして保存するたびに ID が付く | | 1 ファイルの上限 | 10 MiB | 50 MiB | ファイル形式だけで決める必要はありません。たとえば CSV でも、アプリ内部で集計に使うなら Files、利用者に渡すレポートなら Media が適しています。 Media の URL は誰でも開ける公開 URL ではありません。**そのアプリを閲覧できるメンバーだけが、Keelson にログインして開けます。** Files も Media も、利用には `keelson.yaml` への追加設定は不要です。 ## 再起動後もファイルを残すには アプリが動くサーバー内のファイルは、再起動・再デプロイで失われます。この性質を「揮発性」と呼びます。`/tmp` や `/data` に書くだけでは、後で使うファイルを残せません。 Files / Media SDK で保存が完了すると、ファイルはアプリの再起動後も残ります。後から同期処理を行う必要はありません。顧客情報や案件など、項目ごとに検索・更新するデータには [Managed SQLite](https://keelson.dev/ja/docs/building-apps/persistent-storage/) を使ってください。 ## インストール 必要な SDK をアプリの依存パッケージに追加します。以下のコード例はサーバー側で実行します。通常は AI エージェントに、保存したいファイルと用途を伝えて実装を依頼できます。 | 言語 | パッケージ | |---|---| | Node.js | `npm install @keelsonhq/files @keelsonhq/media` | | Python | `pip install keelson-sdk`(`from keelson import files, media`) | | Go | `go get github.com/keelsonhq/go-sdk`(`.../go-sdk/files`、`.../go-sdk/media`) | ## Files SDK Files は、アプリが名前を付けて保存し、必要に応じて同じ名前で更新するファイルに向いています。Web アプリと定期実行ジョブの間で、保存したファイルを共有できます。 保存先の名前を「キー」と呼びます。`settings.json` や `reports/2026-08.csv` のように指定します。主な操作は、保存する `write`、読み取る `read`、削除する `delete`、キーの一覧を取得する `list` です。`read` はファイルがなければ `null` / `None` を返します。 次は、設定を保存して読み取り、レポートの一覧取得と削除を行う例です。 ```javascript import * as files from "@keelsonhq/files"; await files.write("settings.json", JSON.stringify({ theme: "dark" })); const raw = await files.read("settings.json"); // Uint8Array | null const settings = raw ? JSON.parse(new TextDecoder().decode(raw)) : {}; const keys = await files.list("reports/"); // ["reports/2026-08.csv", ...] await files.delete("reports/2026-07.csv"); ``` ```python import json from keelson import files files.write("settings.json", json.dumps({"theme": "dark"})) settings = json.loads(files.read("settings.json") or "{}") # read() -> bytes | None keys = files.list("reports/") files.delete("reports/2026-07.csv") ``` ローカルファイルから移す場合は、書き込みと読み取りの両方を SDK に変更します。Files には配信用 URL がないため、保存したファイルを利用者に渡したい場合は、アプリ側にダウンロード処理を実装するか、Media を使ってください。 ## Media SDK Media は、アプリの画面で見せる画像や、利用者が開く PDF・添付ファイルに向いています。保存したファイルを Keelson が URL で配信するため、アプリ側にファイル配信用の処理を書く必要はありません。 ### 保存して画面に表示する流れ 1. サーバー側のコードで `put` を呼び、ファイルを保存します。 2. 返されたファイル ID を、案件や商品などのデータと一緒に DB に記録します。 3. `url(id)` で URL を取得し、画面の画像やリンクに設定します。ブラウザがその URL にアクセスすると、Keelson が認証を確認してファイルを返します。 画像を保存するサーバー側の関数の例です。引数には、アップロードで受け取った画像データを渡します。 ```javascript import * as media from "@keelsonhq/media"; async function savePhoto(imageBytes) { const id = await media.put(imageBytes, { contentType: "image/png", filename: "photo.png", }); // id を DB に記録し、url を画面に返します。 return { id, url: media.url(id) }; } ``` ```python from keelson import media def save_photo(image_bytes): file_id = media.put( image_bytes, content_type="image/png", filename="photo.png", ) # file_id を DB に記録し、url を画面に返します。 return {"id": file_id, "url": media.url(file_id)} ``` Keelson 上での URL は `/__keelson/media/<ファイルID>` という形式です。たとえば、画像の URL を `` の `src` に、PDF の URL をリンクの `href` に設定します。 ```html 商品の写真 申請書を開く ``` ファイルの読み取りは Keelson が処理します。URL を知っているだけでは開けず、そのアプリの閲覧権限が必要です。 ### 更新・削除とその他の操作 保存済みのファイルは上書きできません。差し替える場合は新しいファイルを保存し、DB に記録した ID を更新します。不要になった古いファイルは別途削除してください。 - サーバー側で中身を読み取るには `get(id)`、種類(Content-Type)とサイズを調べるには `stat(id)` を使います。 - 存在確認は `exists(id)`、削除は Node.js では `del(id)`、Python では `delete(id)` です。 - Content-Type を省略すると、ファイル名の拡張子から決まります。 ## ローカル開発 手元で開発するときは、Keelson の接続設定がなければ、どちらの SDK もローカルのフォルダにファイルを保存します。手元のファイルが、デプロイ時に Keelson の Files / Media に自動で移されるわけではありません。 - Files: `./.keelson/files/` 配下に実ファイルとして書きます。`.keelson/` を `.gitignore` に入れてください - Media: `./media/` 配下に書きます(`MEDIA_DIR` で変更可) Keelson 上では、必要な環境変数を Keelson が設定します。 Media のローカルモードでは、URL の既定値は `/media/<ファイルID>` です。ブラウザで表示を確認するには、開発用サーバーにファイルを返す処理を用意してください。`media.url()` は URL を返す関数で、ローカルの HTTP 配信を開始するものではありません。 Files SDK のローカルモードは OS によって条件が違います。確実に動くのは Linux(WSL2 や Linux の devcontainer を含む)です。 | SDK | Linux | macOS | Windows | |---|---|---|---| | Node.js | 動く | 標準では動かない。`KEELSON_FILES_ALLOW_BESTEFFORT_LOCAL=1` で試験的に有効化できるが、環境によっては書き込みに失敗する | 動かない | | Python | 動く | 動く | 動かない(POSIX 専用の API を使うため) | | Go | 動く | 動く | 動く | Node.js を macOS / Windows で使う場合や、Python を Windows で使う場合は、Linux の開発環境(devcontainer や WSL2)を利用してください。Media SDK のローカルモードにこの OS 制限はありません。 ## ファイルの管理と容量 - コンソールや CLI には、アプリのファイルを一覧表示・ダウンロード・差し替える機能はありません。利用者向けのファイル一覧はアプリに用意します。Media は保存した ID から閲覧用リンクを作り、Files は必要に応じてダウンロード処理を実装してください。 - 上限を超える大容量ファイルは、S3 互換などの外部オブジェクトストレージにアプリから直接保存してください(外部通信に制限はありません) Files / Media のファイルはワークスペースのストレージ容量([プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/))に含まれます。 Managed SQLite のバックアップには、Files / Media のファイル本体は含まれません。DB を復元しても、削除したファイルは戻りません。 ## 関連ページ - [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/) - [定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/) — cron から Files SDK を使う --- # 定期実行ジョブ 決まった時刻・間隔で処理を動かす方法と、実行結果の確認 URL: https://keelson.dev/ja/docs/building-apps/scheduled-jobs/ Language: ja --- 毎朝のレポート作成や、1 時間ごとのデータ同期など、決まった時刻・間隔で処理を動かせます。この処理を「定期実行ジョブ」と呼びます。Web アプリへのアクセスがなくても実行されます。 通常は AI エージェントに、実行したい処理とスケジュールを伝えると、`keelson.yaml` の `crons` に設定します。 > 毎朝 9 時に売上を集計する定期実行ジョブを追加してください。実行結果をログで確認できるようにしてください。 ## 基本 Web アプリに、毎日 9 時に `report.py` を実行するジョブを追加した例です。 ```yaml slug: my-app runtime: python-slim command: "python app.py" db: mode: libsql crons: - name: daily-report schedule: "0 9 * * *" # 毎日 9:00 command: "python report.py" timeout: 120 # 1 回の実行を最大 120 秒にする ``` | 項目 | 意味 | |---|---| | `name` | ジョブの名前。小文字英数字とハイフンで指定します | | `schedule` | 実行する時刻・間隔を表す cron 式 | | `command` | 1 回分の処理を実行し、終了するコマンド | | `timeout` | 1 回の実行時間の上限(秒)。上限に達すると停止します | | `enabled` | `false` にすると定期実行を止めます。省略時は `true` です | `name`、`schedule`、`command` は必須です。`timeout` は 1〜600 秒の範囲で、プランの上限以下を指定してください。省略時は 300 秒ですが、プランの上限がそれより短ければ、その上限が適用されます。上限を超える値を明示すると、デプロイは拒否されます。 Web アプリなしで、定期実行だけのアプリも作れます。その場合はトップレベルの `command` を省略します。定期実行だけのアプリは「同時に使えるアプリ数」の枠を消費しません。 ## スケジュールの書き方 `schedule` には、時刻や間隔を 5 つの項目で表す「cron 式」を書きます。 | やりたいこと | cron 式 | |---|---| | 毎日 9:00 | `0 9 * * *` | | 平日 9:00 | `0 9 * * 1-5` | | 毎時 0 分 | `0 * * * *` | | 15 分ごと(Plus / Team) | `*/15 * * * *` | | 5 分ごと(Team) | `*/5 * * * *` | | 毎月 1 日 0:00 | `0 0 1 * *` | スケジュールは**ワークスペースのタイムゾーン**で評価されます。タイムゾーンはワークスペース作成時にブラウザから設定され、後から変更できません。実行開始は予定時刻より遅れることがあります。 最小間隔は Starter 60 分 / Plus 15 分 / Team 5 分です。それより短いスケジュールはデプロイ時に拒否されます。毎分の実行には対応していません。
cron 式の各項目 ```text ┌───────────── 分(0–59) │ ┌─────────── 時(0–23) │ │ ┌───────── 日(1–31) │ │ │ ┌─────── 月(1–12) │ │ │ │ ┌───── 曜日(0–6、0=日曜) * * * * * ``` `*` はすべての値を表します。たとえば `0 9 * * *` は「毎月・毎日・すべての曜日の 9 時 0 分」です。
## 実行結果とログ コンソールのアプリ画面で、ジョブごとの実行履歴、成功・失敗、ログを確認できます。「今すぐ実行」で、次の予定時刻を待たずに動作を確認することもできます。 失敗した場合はログを確認し、必要なシークレットや設定値がそろっているか、`timeout` 内に処理が終わるかを調べます。ログを AI エージェントに渡して、原因の調査と修正を依頼できます。 標準出力・標準エラーのログは、1 回あたり 256 KiB まで記録されます。超えた分は省略されます。 ### 月間実行回数 実際に開始した実行を数えます。成功・失敗・「今すぐ実行」は含み、スキップされた回は含みません。プランの上限に達すると当月の残りの実行はスキップされ、翌月にリセットされます。 本数・実行時間・月間実行回数の上限は[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)を参照してください。 ## 実行モデル 定期実行ジョブは、1 回分の処理を行って終了します。アプリを動かし続けるための機能ではありません。 | 項目 | 動作 | |---|---| | Web アプリとの関係 | 別の実行環境で動きます。メモリやローカルファイルは共有しません | | データの保存 | 実行環境内のファイルは次回に引き継がれません。残したいデータは Managed SQLite や Files / Media SDK に保存します | | 前回の実行が終わっていない場合 | 同じジョブの次の実行をスキップします。後で実行するための予約は残りません | | 実行に失敗した場合 | 自動ですぐに再試行はしません。次の予定時刻には通常どおり実行します | | 実行時間の上限に達した場合 | 処理の途中でも停止します | アプリ内のタイマーやスケジューラは、アプリが停止している間には動作しません。決まった時刻の処理には `crons` を使ってください。レスポンスを返した後のバックグラウンド処理も、完了が保証されません。リクエスト内で完了させるか、後述の方法で定期実行に移します。 詳しくは[アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)を参照してください。 ## 設計のルール ### 再実行してもデータが重複しないようにする 途中で停止した処理を次回やり直したり、「今すぐ実行」で同じ処理を繰り返したりしても、登録や送信が重複しないようにします。この性質を「冪等性」と呼びます。 たとえば、日付が一意の `reports` テーブルに集計結果を保存するなら、同じ日付のデータがあれば更新します。 ```python conn.execute(""" INSERT INTO reports (date, total) VALUES (?, ?) ON CONFLICT(date) DO UPDATE SET total = excluded.total """, (today, total)) ``` ### 受け付けた処理を後で実行する Web アプリで受け付けた処理を後でまとめて実行する場合は、未処理の内容を Managed SQLite に保存します。定期実行ジョブが未処理のデータを読み取り、処理してから完了を記録します。 ```yaml # Team プランで 5 分ごとに実行する例 crons: - name: process-pending schedule: "*/5 * * * *" command: "python process_pending.py" timeout: 120 ``` - **開始までの待ち時間を考慮します。** 次のジョブ実行まで待つため、すぐに開始する必要がある用途には適していません。利用者にも待ち時間を案内してください。 - **同じ処理が繰り返される場合に備えます。** メール送信などが成功しても、完了を DB に記録する前にジョブが止まることがあります。 - **失敗の回数と理由を記録します。** 再試行の上限を設け、繰り返し失敗するデータをどう扱うか決めてください。Keelson が個々の未処理データを自動で再試行・隔離するわけではありません。 リクエスト内で完了できる短い処理は、レスポンスを返す前に済ませてください。 ### 1 回で処理する量を決める 大量のデータを処理するときは、1 回の件数に上限を設け、残りは次回に処理します。実行時間の上限を超える処理は、複数回に分けてください。 外部 API を呼ぶ場合は、相手のサービスが定める呼び出し回数の制限にも合わせます。間隔を広げるか、1 回あたりの呼び出し回数を減らしてください。 ## 実装例 ### 毎朝の集計(Python) `sales` と `reports` テーブルが作成済みの例です。集計対象の日付はアプリ側で決めます。スケジュールのタイムゾーンと、コードで日付を求める際のタイムゾーンは区別してください。 ```python # report.py import os, datetime, libsql conn = libsql.connect( database=os.environ["KEELSON_DB_URL"], auth_token=os.environ["KEELSON_DB_AUTH_TOKEN"], ) today = datetime.date.today().isoformat() row = conn.execute( "SELECT COUNT(*), COALESCE(SUM(amount), 0) FROM sales WHERE date = ?", (today,) ).fetchone() conn.execute( "INSERT INTO reports (date, count, total) VALUES (?, ?, ?) " "ON CONFLICT(date) DO UPDATE SET count = excluded.count, total = excluded.total", (today, row[0], row[1]), ) conn.commit() print(f"集計完了: {today} {row[0]} 件 / {row[1]}") ``` ### 外部 API との同期(Node.js) ```javascript // sync.js import { createClient } from "@libsql/client"; const db = createClient({ url: process.env.KEELSON_DB_URL, authToken: process.env.KEELSON_DB_AUTH_TOKEN, }); const res = await fetch(process.env.SYNC_API_URL); if (!res.ok) throw new Error(`同期先 API のエラー: ${res.status}`); const items = await res.json(); for (const item of items) { await db.execute({ sql: `INSERT INTO synced_items (id, data) VALUES (?, ?) ON CONFLICT(id) DO UPDATE SET data = excluded.data`, args: [item.id, JSON.stringify(item)], }); } console.log(`同期完了: ${items.length} 件`); ``` ### Slack 通知 通知処理を `notify.py` に実装した場合の設定例です。Webhook URL はシークレットで渡します。 ```yaml slug: daily-notifier runtime: python-slim db: mode: none secrets: items: - name: SLACK_WEBHOOK_URL description: "通知先の Slack Incoming Webhook" required: - all_of: [SLACK_WEBHOOK_URL] crons: - name: daily-notify schedule: "0 9 * * 1-5" command: "python notify.py" timeout: 30 ``` ## デプロイが拒否されたとき | 状況 | 対処 | |---|---| | `timeout` に 600 秒を超える値、またはプラン上限を超える値を指定した | 上限以下にし、必要なら処理を分割する | | スケジュールがプランの最小間隔より短い | 間隔を広げる | | ジョブの本数がプラン上限を超えている | 処理をまとめるか、不要なジョブを削除する | | `type: web` と `crons` を併用している | 定期実行だけなら `type` を外す。静的サイトに処理を追加する場合は、サーバーを持つ構成への変更も確認する | | 廃止された `workers:` が残っている | 削除し、処理に応じて `crons` かリクエスト処理に変更する | ## 向いていないこと - イベント発生後、すぐに開始する必要がある処理。定期実行では次の予定時刻まで待ちます。 - 分割できず、1 回の実行時間の上限を超える処理。 - ジョブの完了を待って別のジョブを開始するなどの、ワークフロー制御。 ## 関連ページ - [アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/) - [プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/) - [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/) - [ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/) - [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#crons) --- # ログイン中のユーザー情報を使う ログインユーザーの識別、運用者だけの画面、グループごとの分岐と業務上の権限 URL: https://keelson.dev/ja/docs/building-apps/using-identity/ Language: ja --- Keelson がログインと、アプリを開ける人の確認を行います。アプリでは、そのユーザー情報を使って、作成者を記録したり、本人のデータだけを表示したりできます。 「誰がどの申請を承認できるか」など、アプリ内の業務ルールはアプリ側で実装します。用途に応じて、次の 3 つの方法を使い分けます。 | やりたいこと | 使うもの | 追加設定 | |---|---|---| | 誰がアクセスしているか知りたい(作成者の記録、自分のデータだけ表示) | ヘッダー `X-Keelson-User-Id` / `-Email` / `-Name` | 不要 | | アプリの運用者(デプロイ・設定変更ができる人)だけに見せる画面を作りたい | ヘッダー `X-Keelson-User-App-Perms` | 不要(権限はコンソールで設定) | | 部署ごと・役職ごとの分岐、承認者の判定 | Identity SDK の `attributes.groups` | `keelson apps directory enable` | 「上司だけが承認できる」のような業務上の権限は、アプリ管理用の `manage` ではなく、所属グループ、またはアプリ自身のデータ(担当者テーブルなど)で判断します。`manage` を持つのはアプリをデプロイ・設定できる人であり、業務上の承認者と一致するとは限りません。 ## 1. 誰がアクセスしているか Keelson は、ログイン済みユーザーからのリクエストに、ユーザー情報をヘッダー(リクエストに付く付加情報)として渡します。アプリのサーバー側で読み取れます。 | ヘッダー | 内容 | |---|---| | `X-Keelson-User-Id` | ユーザー ID(安定した識別子。DB に保存するならこれ) | | `X-Keelson-User-Email` | メールアドレス(Keelson に値がなければ空文字) | | `X-Keelson-User-Name` | 表示名(Keelson に値がなければ空文字) | 作成者を記録するなら、データの保存時にユーザー ID も記録します。本人のデータだけを表示するなら、DB の検索条件にその ID を使います。ヘッダーを読み取るだけで、データの絞り込みが自動で行われるわけではありません。 ```python # FastAPI / Flask user_id = request.headers.get("X-Keelson-User-Id") email = request.headers.get("X-Keelson-User-Email") ``` ```javascript // Express const userId = req.headers["x-keelson-user-id"]; const email = req.headers["x-keelson-user-email"]; ``` これらのユーザー情報は、Keelson がログインを確認したうえで付けます。呼び出し元が同名のヘッダーを送っても、Keelson が確認したユーザー情報に置き換えられます。アプリ側で Keelson のログインセッションを管理する必要はありません。 ### SDK で読み取る Identity SDK を使うと、ユーザー情報を `id`、`email`、`name` としてまとめて取得できます。`getCurrentUser` はヘッダーを読むだけで、外部への通信や Directory API の有効化は不要です。JavaScript では `await` を付けて呼びます。ヘッダーがない場合は例外(`IdentityError`)になります。 ```javascript import { getCurrentUser } from "@keelsonhq/identity"; app.get("/", async (req, res) => { const user = await getCurrentUser({ headers: req.headers }); // { id, email, name } res.type("text").send(`こんにちは、${user.name ?? "ゲスト"} さん`); }); ``` ## 2. 運用者だけの画面 アプリの権限は「閲覧(view)」と「管理(manage)」の 2 種類で、コンソールまたは CLI でグループに割り当てます([グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/))。`manage` はデプロイ・設定変更・シークレット編集ができる運用者の権限で、既定では Owner / Admin / Developer が持ちます。Keelson はその結果をヘッダーで渡します。 | `X-Keelson-User-App-Perms` | 意味 | |---|---| | `view` | 閲覧できる | | `view,manage` | 閲覧と管理ができる | アプリは `manage` が含まれるかだけを見ます。グループ名はコードに書きません。 ```javascript // Express — ヘッダーはリクエストごとに違うので、ハンドラの中で読む function canManage(req) { const perms = (req.headers["x-keelson-user-app-perms"] ?? "").split(","); return perms.includes("manage"); } app.get("/admin", (req, res) => { if (!canManage(req)) return res.status(403).end(); res.send("運用者向けの画面"); }); ``` ```python # FastAPI / Flask — 同じくリクエストごとに読む def can_manage(request) -> bool: perms = request.headers.get("X-Keelson-User-App-Perms", "").split(",") return "manage" in perms ``` 「経理チームだけが使えるアプリ」は権限の割り当てだけで実現でき、アプリ側のコードは要りません([チームにアプリを共有する](https://keelson.dev/ja/docs/access-control/share-with-team/))。「運用者だけが設定画面を開ける」は `manage` の確認で実現できます。誰が `manage` を持つかは、コードを変えずにコンソールで変えられます。 ## 3. グループごとの分岐 部署ごと・役職ごとの分岐や、「承認者だけが承認できる」のような業務上の権限が必要なら、Identity SDK でユーザーの所属グループを取得します。 画面の出し分けだけでは不十分です。「本人の申請だけ見える」を実装するときは、一覧の絞り込みに加えて、**API で他人の申請 ID を指定しても取得・更新できない**ことをサーバー側で確認してください。判定に使うのは、ブラウザから送られた値ではなく、Keelson が付けたヘッダーや SDK の戻り値です。 ### 準備 アプリに Directory API の読み取りを許可し、再デプロイします。 Directory アクセスを有効にするとトークンが保存されますが、再デプロイするまでアプリには注入されません。 ```bash keelson apps directory enable keelson deploy ``` これでアプリに `KEELSON_DIRECTORY_TOKEN` が注入され、SDK が自動で使います。トークンはサーバー側だけで使い、ブラウザに渡さないでください。 ### 使い方 ```javascript import { getCurrentIdentity } from "@keelsonhq/identity"; // リクエストを処理する関数の中で取得します。 const me = await getCurrentIdentity({ headers: req.headers }); const groups = me.attributes?.groups ?? []; // 例: ["everyone", "developers", "経理"] const isAccountingMember = groups.includes("経理"); // この結果を使って、経理向けの操作を許可するか判断します。 ``` ```python from keelson_identity import get_current_identity me = get_current_identity(headers=request.headers) groups = me.attributes.groups if me.attributes else [] is_accounting_member = "経理" in groups # この結果を使って、経理向けの操作を許可するか判断します。 ``` `attributes.groups` に入るのは**グループのキー**です。 - ロールに応じたシステムグループ: Owner は `owners` `developers` `everyone`、Admin は `admins` `developers` `everyone`、Developer は `developers` `everyone`、App User は `everyone` - そのアプリに権限が割り当てられているカスタムグループのうち、ユーザーが属するもの。アプリに割り当てていないグループは出ません - キーは変わらないので、コードに書いて判定に使えます。日本語のキー(`経理`)も使えます `getCurrentIdentity` の戻り値には、ユーザー(`id` `email` `name`)、ワークスペースでのロール(`workspace.role`)、このアプリでの権限(`app.permissions`)も含まれます。 ### 担当者の選択肢にメンバー一覧を使う 担当者の選択肢を出すなど、他のメンバーの情報が必要なときは `listMembers` / `list_members`(検索、ロール・グループで絞り込み)、`getUser`、`listGroups` が使えます。 ## ローカル開発 Identity SDK は `KEELSON_LOCAL_MODE=1` で、開発用のダミーユーザーを返します。ユーザー ID やメールアドレスは `KEELSON_LOCAL_USER_ID` / `KEELSON_LOCAL_USER_EMAIL` で変更できます。 ただし、ダミーユーザーは本番の権限を完全には再現しません。**一般利用者には管理画面を開かせない、といった動作は、実際の権限を設定したテスト用アプリでも確認してください。**
ローカルで権限を確認するときの注意点 - ヘッダーを直接読むコードには、SDK のダミーは適用されません。テスト用のリクエストにヘッダーを付けるなどして確認します。 - ダミーの `app.permissions` は常に `manage,view` です。`KEELSON_LOCAL_WORKSPACE_ROLE=APP_USER` にしても、管理権限のないユーザーの動作にはなりません。 - カスタムグループは含まれません。ダミーの Owner は `admins` にも含まれますが、本番の Owner は `admins` には含まれません。
## Webhook などログインなしのリクエスト 外部システムから呼ばれるパス(`auth.endpoints`)には `X-Keelson-User-Id` が付きません。そこでは Webhook の署名やアプリトークンで認証します。[外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/)を参照してください。 ## 関連ページ - [グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/) — 誰に view / manage を与えるか - [認証とログイン](https://keelson.dev/ja/docs/access-control/auth-and-login/) --- # 外部システムとの連携 Webhook の受信、API トークン、受信メール、外部 DB URL: https://keelson.dev/ja/docs/building-apps/external-integrations/ Language: ja --- OpenAI などの API を呼ぶ、外部サービスの通知を受け取る、アプリ宛てのメールを処理するなど、用途に応じて連携方法を選べます。 | やりたいこと | 必要な対応 | |---|---| | 外部の API を呼ぶ | [接続情報や API キーを設定する](#外部の-api-を呼ぶ) | | 外部サービスから通知を受ける | [Webhook の受信先と、送信元を確認する方法を設定する](#webhook-を受ける) | | 社内の別システムからアプリの API を呼ぶ | [アプリトークンと呼び出せるパスを設定する](#別のシステムからアプリの-api-を呼ぶ) | | アプリ宛てのメールを受け取る | [メール受信を有効にし、受信処理を実装する](#メールを受け取る) | | 外部 DB やストレージを使う | [接続情報を設定する](#外部データベース) | ## 外部の API を呼ぶ アプリから外部サービスへの通信に制限はありません。必要な API キーを[シークレット](https://keelson.dev/ja/docs/deploy/environment-variables/)に設定し、アプリから呼び出します。外部サービス側の契約や呼び出し回数の制限は、そのサービスの条件に従います。 一方、外部のシステムからアプリを呼ぶ場合は、既定で Keelson のログインが必要です。ブラウザでログインできないシステムから呼び出すには、以下の設定を行います。 ## Webhook を受ける Webhook は、外部サービスで起きた出来事をアプリに通知する仕組みです。たとえば決済完了の通知を受けて、注文の状態を更新できます。 `keelson.yaml` の `auth.endpoints` に受信先のパスとメソッドを設定します。この設定は、指定したパスをブラウザのログインなしで呼べるようにするものです。誰からの呼び出しかは、署名やアプリトークンで確認します。 パスは `/api/webhooks/` または `/api/external/` で始まる必要があります。 ```yaml auth: endpoints: - path: /api/webhooks/stripe methods: [POST] ``` 指定したパスの受信処理もアプリ側に実装し、その URL を送信元のサービスに登録します。これらのリクエストには、ログインユーザーの情報(`X-Keelson-User-Id`)は付きません。 - **送信元が署名を付ける場合**(Stripe、GitHub、Slack など): 署名シークレットを `secrets` で受け取り、署名を検証します - **送信元が署名を付けない場合**: アプリトークン(次の節)を発行し、`X-Webhook-Secret` ヘッダーまたは URL `/api/webhooks//...` で受け取ります 宣言していないパスは、これまでどおりログイン必須のままです。Webhook のために必要なパスだけを開けてください。 なお `/api/webhooks/email` と `/api/webhooks/email-events` はプラットフォーム予約のため、独自のアプリ Webhook として宣言できません。メール受信を有効にすると、下記のとおりプラットフォームが `/api/webhooks/email` を直接呼びます。`auth.endpoints` への追加は不要です。 ## 別のシステムからアプリの API を呼ぶ 社内の別システムやスクリプトからアプリの API を呼ぶ場合は、アプリトークンを発行します。 ```bash keelson apps tokens create --name batch-client --scope api --allowed-ip 203.0.113.0/24 ``` - トークンは `keelson_...` の形式で、作成時に 1 回だけ表示されます - `--scope api` は `/api/external/` 配下、`--scope webhook` は `/api/webhooks/` 配下に対応します - `--allowed-ip` で送信元 IP を絞れます(CIDR、複数可)。ワークスペースやアプリの IP 制御とは別に、トークン単位で適用されます - 同じ設定はコンソールのアプリ画面からも行えます。`keelson apps tokens list / rotate / delete` でローテーションと失効ができます 呼び出し側は `Authorization: Bearer keelson_...` を付けて、`auth.endpoints` で宣言したパスを呼びます。 ```bash curl -H "Authorization: Bearer keelson_xxx" https://acme--myapp.keelson.run/api/external/status ``` ```yaml auth: endpoints: - path: /api/external/status methods: [GET] - /api/external/import # メソッド指定なし = すべて ``` Keelson は、トークンが有効で対象アプリ・用途に合っていること、送信元 IP が許可されていること、パスとメソッドが宣言に合っていることを確認してから、アプリにリクエストを渡します。 ## メールを受け取る アプリ宛てのメールを受け取り、問い合わせの登録や添付ファイルの処理に使えます。Keelson がメールを受信し、内容をアプリの受信処理に渡します。 1. 次の設定でメール受信を有効にします。 2. アプリに `POST /api/webhooks/email` の受信処理を実装します。 3. デプロイ後、コンソールに表示された受信アドレスへメールを送って確認します。 メール受信にはサーバー側の処理が必要です。静的サイトだけの構成では利用できません。 ```yaml email: inbound: enabled: true ``` 既定は無効です。メールを送るだけ、または扱わないアプリでは設定しません。 デプロイに成功すると、アプリには `@inbound.keelson.run` というアドレスが割り当てられます。`` はアプリの slug です。現在の環境で実際に割り当てられたアドレスはコンソールに表示されます。 アプリに `POST /api/webhooks/email` を実装してください。このパスはプラットフォーム予約なので `auth.endpoints` には宣言しません。メールが届くと Keelson が直接呼び出します。 ### 受信処理に渡される情報 | 項目 | 内容 | |---|---| | `delivery_id` | 配信を識別する ID。同じメールの再配信を判別するために使います | | `from` / `to` | 差出人と宛先 | | `subject` | 件名 | | `text` / `html` | 本文 | | `attachments` | 添付ファイルの ID、ファイル名、サイズなど |
受信データの JSON 例 代表的なキーの抜粋です。追加のキーが届いても処理できるように実装してください。 ```json { "delivery_id": "del_01JEXAMPLE", "attempt": 1, "received_at": "2026-09-04T10:15:30Z", "from": { "name": "Ada Lovelace", "address": "ada@example.com" }, "to": [ { "name": "Support", "address": "my-app@inbound.keelson.run" } ], "cc": [], "reply_to": { "name": "Ada Lovelace", "address": "replies@example.com" }, "subject": "アカウントについての質問", "text": "プレーンテキスト部分の本文です。", "html": "

HTML 部分の本文です。

", "envelope_to": "my-app@inbound.keelson.run", "references": [""], "attachments": [ { "id": "att_01JEXAMPLE", "filename": "question.pdf", "content_type": "application/pdf", "size_bytes": 48231, "download_url": "https://example.invalid/temporary-download" } ] } ```
### 受信メールの署名を検証する 受信処理では、Keelson から届いた通知かどうかを SDK で確認してから、本文や添付ファイルを処理します。確認に使う署名シークレットは、`KEELSON_EMAIL_WEBHOOK_SECRET` としてアプリに渡されます。 署名の検証には、JSON に変換する前の、変更を加えていないリクエスト本文を使ってください。以下の例は検証成功後に `200`、検証失敗時に `401` を返します。二重処理を防ぐ方法は次の節で説明します。
Python の実装例 ```python import os from fastapi import FastAPI, HTTPException, Request, Response from keelson_email import EmailError, verify_webhook app = FastAPI() secret = os.environ["KEELSON_EMAIL_WEBHOOK_SECRET"] @app.post("/api/webhooks/email") async def receive_email(request: Request) -> Response: try: message = verify_webhook(await request.body(), request.headers, secret) except EmailError as exc: raise HTTPException(status_code=401, detail="invalid signature") from exc # ここで message を処理します。 return Response(status_code=200) ```
Node.js の実装例 ```typescript import { createServer } from "node:http"; import { verifyWebhook } from "@keelsonhq/email"; const secret = process.env.KEELSON_EMAIL_WEBHOOK_SECRET; if (!secret) throw new Error("KEELSON_EMAIL_WEBHOOK_SECRET is required"); createServer(async (request, response) => { if (request.method !== "POST" || request.url !== "/api/webhooks/email") { response.writeHead(404).end(); return; } let message; try { message = await verifyWebhook(request, secret); } catch { response.writeHead(401).end(); return; } // ここで message を処理します。 response.writeHead(200).end(); }).listen(process.env.PORT ?? 3000); ```
Go の実装例 ```go package main import ( "net/http" "os" "github.com/keelsonhq/go-sdk/email" ) func main() { secret := os.Getenv("KEELSON_EMAIL_WEBHOOK_SECRET") if secret == "" { panic("KEELSON_EMAIL_WEBHOOK_SECRET is required") } http.HandleFunc("/api/webhooks/email", func(w http.ResponseWriter, r *http.Request) { message, err := email.VerifyWebhook(r, secret) if err != nil { http.Error(w, "invalid signature", http.StatusUnauthorized) return } // ここで message を処理します。 _ = message w.WriteHeader(http.StatusOK) }) if err := http.ListenAndServe(":"+os.Getenv("PORT"), nil); err != nil { panic(err) } } ```
### 同じメールが 2 回届くことに備える アプリが `200` を返す前に停止したり、応答が遅かったりすると、同じメールが再配信されることがあります(at-least-once 配信)。署名が正しくても、初めて届いたメールとは限りません。注文の登録や返信メールの送信などが二重に行われないようにしてください。 - 受信データの `delivery_id`(配信イベントでは `event_id`)と処理状況を DB に保存し、処理済みなら再処理せず `200` を返す - ID の保存と業務データの更新は同じトランザクションで行う - 処理中に同じ ID が来たら `503` を返して再配信に回す
SDK の重複処理防止機能を使う場合 SDK には重複抑止の補助があります。Go は `VerifyWebhookOnce` / `VerifyEventWebhookOnce` に `IdempotencyStore` を渡します。Node.js / Python は `setIdempotencyStore` / `set_idempotency_store` で永続ストアを登録できますが、これは SDK の組み込みサーバーに効くもので、上の例のように `verifyWebhook` を自分で呼ぶ場合には適用されません。組み込みサーバーの既定の重複抑止はプロセス内メモリなので、再起動や複数インスタンスをまたいでは効きません。
## 外部データベース PostgreSQL、MySQL、自前の libSQL に接続する場合は `db.mode: none` にし、接続情報をシークレットで渡します。詳しくは[データベース](https://keelson.dev/ja/docs/building-apps/persistent-storage/#外部データベースを使う)を参照してください。 ## 外部オブジェクトストレージ Files / Media SDK の上限を超えるファイルは、S3 互換のストレージにアプリから直接保存します。認証情報はシークレットで渡します。 ## 関連ページ - [ログイン中のユーザー情報を使う](https://keelson.dev/ja/docs/building-apps/using-identity/) - [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) - [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#auth) --- # フレームワーク別の注意点 FastAPI / Flask / Express / Next.js / Go の起動方法と、未対応フレームワークの注意点 URL: https://keelson.dev/ja/docs/building-apps/frameworks/ Language: ja --- このページでは、フレームワークごとの本番向けの起動方法と注意点を説明します。Web サーバーは、環境変数 `PORT` で指定されたポートで起動してください。データベースや通信方式に制約があるフレームワークもあるため、[対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/)も確認してください。 開発サーバーは、性能やエラー画面での内部情報の表示、終了時のリクエスト処理などに問題があるため、本番向けのサーバーを使用してください。 通常の設定は AI エージェントに任せられます。このページは、起動方法を確認したいときや、デプロイ時の問題を調べるときに、自分のフレームワークの箇所を参照してください。 ## 全フレームワーク共通 - **`0.0.0.0` と環境変数 `PORT` で指定されたポートで待ち受ける。** `127.0.0.1` ではリクエストが届きません - **起動コマンドにインストール処理を含めない。** `requirements.txt` / `package.json` / `go.mod` からビルド時に入ります - **停止は SIGTERM → 10 秒後に SIGKILL。** 処理中のリクエストは 10 秒以内に終わらせます - **1 vCPU。** worker 数は 1 にします - **デバッグモードの既定は off。** デバッグ画面は環境変数(DB の認証トークンを含む)を表示することがあります - **「Keelson 上か」の判別は `KEELSON_MODE`。** 値が `keelson` ならプラットフォーム上です。`DEBUG` をこの目的に使うとローカルで起動できなくなります ```python import os ON_KEELSON = os.environ.get("KEELSON_MODE") == "keelson" DEBUG = os.environ.get("DEBUG", "false").lower() == "true" # 既定は false ``` ## Python ### FastAPI / uvicorn ```yaml command: "uvicorn main:app --host 0.0.0.0 --port $PORT" env: PYTHONUNBUFFERED: "1" ``` `--reload` は付けません(ファイル監視がメモリを消費し、二重起動することがあります)。worker は既定の 1 のままにします。 ### Flask `app.run()` は開発サーバーです。gunicorn を `requirements.txt` に追加して起動します。 ```yaml command: "gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 --graceful-timeout 9 app:app" env: PYTHONUNBUFFERED: "1" ``` `app:app` はモジュール名とアプリオブジェクト名に置き換えます。`--graceful-timeout 9` で 10 秒の SIGTERM 猶予に収めます。 ### Django Django は現在未対応です。Keelson の Managed SQLite(libSQL)と Django ORM の互換性に制約があるためです。 ### SQLAlchemy / SQLModel / Flask-SQLAlchemy ファイル SQLite を使う構成では、`sqlalchemy-libsql-native` を使って Managed SQLite に接続する方法があります。この方法は実験的な扱いです。接続設定の変更に加えて、モデル・クエリ・マイグレーションが動作するかを確認してください。AI エージェントに、必要な変更と互換性の確認を依頼してください。 ### Streamlit / Gradio Streamlit は WebSocket が必須のため、現在は動きません。Gradio は 4 以上を検証中です。 ## Node.js ### 共通 `NODE_ENV` は自動設定されません。`keelson.yaml` で宣言します。未設定だと Express などがスタックトレースをレスポンスに含めます。 ```yaml env: NODE_ENV: "production" ``` ビルドには npm と `package-lock.json` を使います。`pnpm-lock.yaml` / `yarn.lock` しかない場合は、事前チェックでデプロイが止まります。`package-lock.json` を生成し、npm で依存のインストールとビルドが成功するかを確認してください。詳しくは[依存関係のインストール](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#依存関係のインストール)を参照してください。 ### Express ```yaml command: "npm start" # package.json: "start": "node server.js" ``` - エラーハンドラでスタックを返さない - `app.set("trust proxy", 1)` でクライアント IP / プロトコルをエッジから受け取る - セッションや JWT のシークレットは `secrets` で ### Next.js ビルドして `next start` で起動します。`next dev` は本番用ではありません。 ```yaml command: "npm run start" # package.json: "start": "next start -p $PORT" ``` - `npm run build` がビルド時に自動実行されます。`.next/` が生成されることを確認します - `"start": "next dev"` になっていたら直します - `KEELSON_DB_URL` をサーバー側で読みます。`NEXT_PUBLIC_*` に入れるとブラウザに配布されます ### Prisma `provider = "sqlite"` のままでは動きません。`@prisma/adapter-libsql` を `@prisma/client` と同じメジャーバージョンにそろえて使います(6.x で検証済み)。利用中のバージョンでクエリやマイグレーションが動作するかを、AI エージェントに確認してもらってください。 ## Go Keelson が `go build -o /workspace/app .` でビルドし、`./app` で起動します。 ```yaml runtime: go-slim command: "./app" ``` - `CGO_ENABLED=0` でビルドされます。`mattn/go-sqlite3` などの cgo SQLite ドライバは使えません。Managed SQLite には純 Go の libSQL クライアントを使います - `ListenAndServe` を放置せず、`signal.NotifyContext` と `server.Shutdown` で 10 秒以内に処理中のリクエストを処理し切ります - GORM を使っている場合は `database/sql` + libSQL に置き換えます ## 静的サイト / SPA Vite、Next.js の静的エクスポート、Astro などは、手元でビルドした出力を `assets.dir` に指定してデプロイします。`command` のない静的サイトでは、Keelson 上で依存パッケージのインストールやビルドは行われません。 静的サイトには `type: web` が必要です。`dist/` を `.gitignore` に入れていても、`assets.dir` に指定していれば送信対象に含まれます。設定例は [keelson.yaml の設定](https://keelson.dev/ja/docs/building-apps/keelson-yaml/)を参照してください。 ## 関連ページ - [対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/) - [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/) - [Keelson Deploy Spec](https://keelson.dev/ja/docs/reference/deploy-spec/) — AI エージェント向けの正本 # デプロイと運用 --- # デプロイする AI エージェントまたは CLI でアプリをデプロイし、完了を確認する URL: https://keelson.dev/ja/docs/deploy/deploy/ Language: ja --- 作ったアプリを Keelson で使えるようにする操作を「デプロイ」と呼びます。初めてアプリを使うときや、変更した内容を反映するときに行います。通常は AI エージェントに依頼できます。 ## 必要なもの - [対応している](https://keelson.dev/ja/docs/building-apps/supported-app-types/)アプリのソースコード - アプリのフォルダに置く設定ファイル `keelson.yaml`(なければ AI エージェントに作成を依頼できます) - Keelson CLI のインストールとログイン([クイックスタート](https://keelson.dev/ja/docs/introduction/quickstart/)) - アプリが必要とする API キーなどの値([環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/)) 新規作成には Owner / Admin / Developer のロール、既存アプリの更新には、そのアプリの管理権限(`manage`)が必要です。 ## AI エージェントに頼む アプリのフォルダを AI エージェントで開き、次のように依頼します。Keelson のスキルの設定方法は[クイックスタート](https://keelson.dev/ja/docs/introduction/quickstart/)にあります。 > このアプリを Keelson にデプロイしてください。必要な設定を確認し、完了したらアプリの URL と動作確認の結果を教えてください。 エージェントには、次の内容を確認・実行してもらいます。 1. アプリの保存方法や起動設定が Keelson に合っているか確認する 2. `keelson.yaml` を作成・更新し、必要な API キーなどの登録先を案内する 3. デプロイを実行し、完了まで確認する 4. 失敗した場合はログを調べ、原因と対応方法を説明する 5. 完了後に動作を確認し、確認した内容を報告する 初回デプロイでアプリが作られます。2 回目以降は、同じワークスペース内の `keelson.yaml` の `slug` に対応するアプリが更新されます。`slug` はアプリを識別する名前です。 ## 完了後に確認する Web アプリや静的サイトは、報告された URL を開き、画面表示や主な操作を確認します。確認する項目やエージェントへの依頼例は[デプロイ後の確認](https://keelson.dev/ja/docs/deploy/verify-deploy/)を参照してください。 定期実行だけのアプリは、画面を開く代わりに、コンソールの「定期実行」タブでスケジュールと実行結果を確認します。手動で試す方法は[定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/)にあります。 ## 反映されるもの・されないもの | 変更 | 反映のタイミング | |---|---| | コード、`keelson.yaml` の設定 | デプロイで反映 | | シークレット | 保存後、次のデプロイで反映。「適用」でも、コードを再アップロード・ビルドせずに再デプロイして反映できる | | アプリ権限、IP 制御、公開 URL のアクセス設定 | デプロイなしで反映。通常は 2 分以内。障害中の変更は復旧後に反映 | 公開 URL をアプリ内部でも使っている場合は、[URL 変更後の確認](https://keelson.dev/ja/docs/deploy/public-url/#アプリの中から自分の-url-を知る)も参照してください。 ## 失敗したとき エラーメッセージに含まれるエラーコード(`code`)や対処のヒント(`hint`)を AI エージェントに伝えると、原因の調査に役立ちます。ログの確認方法と症状別の対処は[トラブルシューティング](https://keelson.dev/ja/docs/deploy/troubleshooting/)にあります。 更新の切り替え前に失敗した場合、以前のバージョンへのアクセスは維持されます。ただし、データベースに加えた変更は自動では戻りません。データベースの変更を含む場合は、[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/)の手順で状態を確認します。 ## CLI で直接デプロイする エージェントを介さず、ターミナルから実行することもできます。 ```bash # 初回(アプリを作ってデプロイ) keelson deploy --new # 初回にシークレットも登録する場合 keelson deploy --new --secrets-from-env-file .env.keelson # 2 回目以降 keelson deploy # アップロードせずに設定とアーカイブ内容を確認する keelson deploy --check --json ``` - `--secrets-from-env-file` で指定したファイルはアーカイブから除外されます - 複数のワークスペースに属している場合は `--workspace ` を付けます - 更新先のアプリを明示するには `--app ` を付けます。アップロードするソースは、コマンドを実行したフォルダのものです - スクリプトから使う場合は `keelson deploy --ndjson --yes` を使うと、完了まで待って結果を 1 行 1 JSON で返します ## デプロイ中に起きること ここからは、設定やログを詳しく確認するときの説明です。サーバーで画面や API の処理を行う Web アプリでは、次の処理が行われます。 1. **検証** — `keelson.yaml` とアップロードするファイルを確認します 2. **ビルド** — 必要なライブラリをインストールし、実行に必要なファイルをまとめます。このまとまりを「コンテナイメージ」と呼びます(ビルドの上限は 900 秒) 3. **起動** — 新しいコードと設定でアプリを起動します。この実行単位を「リビジョン」と呼びます 4. **ヘルスチェック** — アプリが応答するか、`health.path`(既定 `/`)と `verify` のパスで確認します 5. **マイグレーション** — DB の構造などを更新する `db.migrate` があれば実行します 6. **切り替え** — 利用者のアクセス先を新しいリビジョンに移します 静的サイト / SPA は、ビルド済みの HTML・JavaScript などを配信します。Web サーバーの起動は行いません。定期実行だけのアプリには Web のアクセス先を切り替える処理はなく、設定した時刻にジョブが実行されます。 保存方法や起動設定を調整する例として、ローカルの SQLite ファイルから Managed SQLite への移行や、Keelson が渡す `PORT` を使う変更があります。詳しくは[対応アプリと制約](https://keelson.dev/ja/docs/building-apps/supported-app-types/)を参照してください。 ## 次に読む - [デプロイ後の確認](https://keelson.dev/ja/docs/deploy/verify-deploy/) — 画面や API の動作を確認する - [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) - [アプリ URL とドメイン](https://keelson.dev/ja/docs/deploy/public-url/) - [アプリの状態とログ](https://keelson.dev/ja/docs/deploy/app-status-and-logs/) --- # デプロイ後の確認 デプロイ後に確認する操作と、AI エージェントが画面や API の応答を調べる方法 URL: https://keelson.dev/ja/docs/deploy/verify-deploy/ Language: ja --- デプロイが完了したら、アプリを開き、普段使う操作ができるか確認します。AI エージェントには、画面や API が正常に応答するかの確認を依頼できます。 ## 自分で確認すること - 自分のアカウントでアプリを開けるか - 一覧表示や検索など、主な操作ができるか - 保存機能がある場合、テスト用のデータを保存して読み直せるか 利用者に共有する前には、その人がアプリを開ける権限を持っているかも確認します。自分のアカウントで開けても、他の利用者が開けるとは限りません([アプリ URL とドメイン](https://keelson.dev/ja/docs/deploy/public-url/))。 定期実行だけのアプリは、コンソールの「定期実行」タブで実行結果を確認します。 ## AI エージェントに確認を頼む > デプロイしたアプリの主な画面と API を確認してください。確認できたことと、まだ確認していないことを教えてください。データを変更する確認にはテスト用データを使ってください。 画面や API から応答が返っても、計算結果や業務上のルールが正しいかは別途確認が必要です。普段使う入力例と期待する結果を伝えると、エージェントも確認しやすくなります。 ## エージェントが応答を確認する方法 通常のアプリの URL は認証で保護されているため、ログイン情報を付けない `curl` では確認できません。`keelson app curl` は、CLI にログインした本人の権限でリクエストを送ります。 本人としてアプリにアクセスするための一時的な認証情報を「プレビュートークン」と呼びます。`app curl` は内部でトークンを取得するため、利用者が値を扱う必要はありません。 ### 1 回の応答を確認する(keelson app curl) 次のコマンドで、ページや API の応答を取得できます。 ```bash keelson app curl / # GET / keelson app curl -i /api/items # ヘッダーも表示 ``` データの登録・更新・削除やファイルのアップロードは、実際のアプリに変更を加えます。次は書き込みの例です。パスとデータは、確認するアプリに合わせます。 ```bash keelson app curl /api/items --method POST \ --data '{"name":"example"}' \ --header 'Content-Type: application/json' keelson app curl /upload --form title=example --form photo=@sample.png ``` - レスポンス本文は標準出力、メソッド・URL・ステータスは標準エラー出力に出ます。`-i` を付けるとヘッダーも標準エラー出力に出るので、本文だけをファイルに落とせます - 既定は `GET`。`--method` で `POST` / `PUT` / `PATCH` / `DELETE` を明示すると、有効期間 5 分の書き込みを許可するトークンが使われます - `--data` は書き込みメソッドとだけ併用できます。`@ファイル名` でファイルから読みます - `--form` を使うとメソッドは `POST` になり、multipart の `Content-Type` は CLI が付けます(`--header` での上書きは不可) - パスは `/` で始める必要があります。絶対 URL と `//` で始まるパスは拒否されます。リダイレクトは追いません - `/__keelson/media/...` と `/__keelson/assets/...` も `GET` / `HEAD` で確認できます - 対象のアプリを明示する場合は `--app ` エージェントには、成功を示すステータスだけでなく、返された内容の種類(`Content-Type`)も確認してもらいます。たとえば、存在しない JavaScript ファイルの代わりに SPA の HTML が返ると、`200` でも画面は正常に動きません。 ### 別のツールや複数のリクエストで確認する(keelson preview) 別の HTTP クライアントを使う、複数回リクエストする、有効期間を選ぶ、といった場合はトークンを直接発行します。 ```bash keelson preview # GET / HEAD のみ。既定 30 分 keelson preview --ttl 5m keelson preview --allow-writes # POST / PUT / PATCH / DELETE も可。既定 5 分、最大 10 分 keelson preview --json # トークン・URL・有効期限を JSON で ``` `--json` が返す `token` と `app_url` を別の HTTP クライアントで使います。トークンは Bearer トークンとして渡します。 ```bash curl --header 'Authorization: Bearer ' '/api/items' ``` トークンは標準出力に 1 回だけ表示され、Keelson は保存しません。ログや報告書に残さないでください。`keelson preview` で発行できるトークンは、アプリ × 利用者につき 1 本です。もう一度発行すると、有効期限内でも前のトークンは取り消されます。`keelson app curl` は別の内部用のトークンを使うため、`preview` で発行したトークンを取り消しません。 ## 他の人がデプロイしたアプリ 現在配信中のデプロイを自分が作っていない場合、プレビュートークンの発行前に、ブラウザで開く承認 URL が案内されます。承認には、そのアプリの管理権限(`manage`)が必要で、管理権限がある本人が承認することもできます。 承認画面で対象アプリ、書き込みの許可、有効期間を確認し、トークンの発行を承認します。承認後、案内された `--confirmation ` を付けて同じコマンドを再実行します。 ## この確認で分かること・分からないこと - これらのコマンドで取得できるのは、本人の権限で送ったリクエストへの応答です。ブラウザでの見た目や操作、他の利用者のアクセス権限は別途確認します - 静的サイトには書き込み先がないので、書き込みメソッドは拒否されます - 読み取り用の `GET` でも、アプリ側の実装によってはデータの変更やメール送信が起こります。確認対象の処理をエージェントに調べてもらい、意図しない変更が起きるパスは避けます ## 関連ページ - [デプロイする](https://keelson.dev/ja/docs/deploy/deploy/) - [CLI コマンド](https://keelson.dev/ja/docs/reference/cli/) --- # 環境変数とシークレット 設定値と API キーをアプリに渡す URL: https://keelson.dev/ja/docs/deploy/environment-variables/ Language: ja --- 外部サービスの API キーや接続先などを、アプリに設定できます。設定値をアプリに渡す仕組みを「環境変数」と呼びます。API キーなどの秘密の値は、Keelson の「シークレット」に登録します。 | 種類 | 例 | どこに書くか | |---|---|---| | 秘密でない設定値 | `NODE_ENV`、`LOG_LEVEL`、公開 API の URL | `keelson.yaml` の `env` | | 秘密の値 | API キー、トークン、DB 接続文字列、Webhook の署名シークレット | **シークレット**(コンソール / CLI / デプロイ時の env ファイル) | `keelson.yaml` はソースコードと一緒に管理するファイルです。秘密の値は含めず、シークレットに登録します。 ## 必要な設定を AI エージェントに確認する > このアプリに必要な設定値と API キーを整理してください。設定ファイルには名前と用途を記載し、秘密の値を登録する場所を案内してください。 設定ファイルや値の読み取り処理はエージェントに依頼できます。秘密の値はチャットに貼る代わりに、コンソールや手元の設定ファイルへ入力します。 ## シークレットの値を登録する 既存のアプリは、コンソールのアプリ画面にある「シークレット」タブで追加・更新・削除できます。保存後に表示されるのは名前と更新日時で、値は再表示されません。 初回デプロイ時には、手元の env ファイルに値を入力し、デプロイと同時に登録することもできます。以下のファイルは書式の例です。 ```dotenv # .env.keelson OPENAI_API_KEY=sk-... SLACK_WEBHOOK_URL=https://hooks.slack.com/... ``` ```bash # 初回デプロイと同時に登録 keelson deploy --new --secrets-from-env-file .env.keelson # 既存アプリの更新と同時に登録 keelson deploy --secrets-from-env-file .env.keelson # 値を登録し、アップロード・ビルドなしの再デプロイで反映 keelson secrets set --from-env-file .env.keelson --apply ``` `--secrets-from-env-file` で指定したファイルはアップロード対象から除外されます。秘密を含むファイルは Git に追加せず、値をコマンドに直接書くことも避けてください。コマンドに書いた値はシェル履歴に残ることがあります。 ## 登録した値をアプリに反映する シークレットは保存しただけでは、動いているアプリに反映されません。次のいずれかで反映します。 - コードも更新する場合は、`keelson deploy` でデプロイする - 値だけを反映する場合は、コンソールに表示される「未反映の変更があります」の **適用**ボタンを押す - CLI で登録と反映をまとめて行う場合は、上の `secrets set --apply` を使う 「適用」と `--apply` は、コードを再アップロード・ビルドせずに再デプロイします。最後に成功したデプロイの実行用ファイル(コンテナイメージ)を使い、新しい値でアプリを起動します。完了後は、API キーを使う操作などが動くか確認します。 ## env(秘密でない値) ここからは設定ファイルとコードの詳細です。秘密でない値は、エージェントに `keelson.yaml` の `env` への記載を依頼できます。 ```yaml env: NODE_ENV: "production" LOG_LEVEL: "info" ``` - 値は必ず引用符で囲みます(数値・真偽値も)。引用符がないとデプロイが拒否されます - `PORT` と `KEELSON_` で始まる名前は書けません(Keelson が設定します) - 変更は次のデプロイで反映されます ## 必要なシークレットを設定ファイルに記載する `keelson.yaml` の `secrets` に、アプリが読むシークレットの**名前だけ**を宣言します。値は書きません。 ```yaml secrets: items: - name: OPENAI_API_KEY description: "OpenAI API key" - name: SLACK_WEBHOOK_URL description: "通知先の Slack Webhook" required: - all_of: [OPENAI_API_KEY] message: "OPENAI_API_KEY を設定してください" ``` `items` は名前と用途の一覧で、コンソールにも表示されます。`required` はデプロイに必要な条件です。この例では `OPENAI_API_KEY` が未設定だと `message` が表示されます。`SLACK_WEBHOOK_URL` は一覧にありますが、必須条件には含まれていません。 ## 設定する範囲と優先順位 | 範囲(スコープ) | 設定場所 | 用途 | |---|---|---| | ワークスペース | コンソールの「シークレット」 | 全アプリ共通の値(共有 API キーなど) | | アプリ | アプリ画面の「シークレット」タブ | そのアプリだけの値、またはワークスペースの値の上書き | 同じ名前があれば **アプリ > ワークスペース > `env`** の順で優先されます。アプリ画面のシークレットタブには、どちらのスコープから来た値かが表示されます。 ## アプリからの読み方 `env` もシークレットも、サーバー側のコードから環境変数として読み取ります。 ```python import os api_key = os.environ["OPENAI_API_KEY"] ``` ```javascript const apiKey = process.env.OPENAI_API_KEY; ``` ## ビルド時には渡らない `env` もシークレットも、ビルド(依存関係のインストール、`npm run build`)には渡りません。ビルドが読めるのはアップロードしたソース一式だけです。 フロントエンドのビルドに埋め込む公開値(`VITE_API_URL` など)は、ソース内の設定ファイルに書きます。ブラウザに配布される値なので、ここに認証情報を置かないでください。 ## システムが自動設定する環境変数 Keelson はプラットフォーム管理の変数を各アプリに設定します。自分で定義または上書きしないでください。 | 変数 | 内容 | |---|---| | `PORT` | Web アプリの待ち受けポート。 | | `TZ` | ワークスペースのタイムゾーン。 | | `KEELSON_MODE` | プラットフォームモードを示す値。 | | `KEELSON_APP_ID` | アプリの内部 ID。 | | `KEELSON_WORKSPACE_ID` | ワークスペースの内部 ID。 | | `KEELSON_TENANT_ID` | `KEELSON_WORKSPACE_ID` の互換用別名(値は同じ)。 | | `KEELSON_DEPLOY_ID` | 現在のデプロイの内部 ID。 | | `KEELSON_APP_URL` | ホストを解決できる場合のアプリの公開 URL。 | | `KEELSON_DIRECTORY_BASE_URL` | ホストを解決できる場合の Directory API のベース URL。 | 旧 tenant 名の変数も互換のため受け付けます。撤去時期は未定です。 機能を有効にすると追加の変数が設定されます。完全な一覧と設定条件は[環境変数一覧](https://keelson.dev/ja/docs/reference/environment-variables/)にあります。 `NODE_ENV` は自動設定されないため、アプリが必要とする場合は `env` に記載します。 ## 次に読む - [環境変数一覧](https://keelson.dev/ja/docs/reference/environment-variables/) - [外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/) - [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#secrets) --- # アプリ URL とドメイン アプリに割り当てられる URL、アプリ内からの参照、URL の変更、カスタムドメイン URL: https://keelson.dev/ja/docs/deploy/public-url/ Language: ja --- Web アプリや静的サイトには専用の URL が割り当てられ、デプロイ後に利用者へ共有できます。自社で管理するドメインを使うこともできます。 標準の URL は次の形式です。`slug` は、URL などに使う識別名です。 ``` https://<ワークスペース slug>--<アプリ slug>.keelson.run ``` ワークスペースの slug が `acme`、`keelson.yaml` の `slug` が `dashboard` なら `https://acme--dashboard.keelson.run` です。HTTPS の証明書は Keelson が管理します。 URL は、コンソールのアプリ画面、デプロイ完了時の AI エージェントの報告、`keelson status` で確認できます。 ## アクセスできる人 URL を知っているだけでは開けません。ワークスペースにログインし、そのアプリの閲覧権限を持つメンバーだけが開けます。IP 制御を設定していれば、許可されたネットワークからのアクセスに限られます。 App User には**アプリの URL を別途共有する**必要があります。App User はコンソールを開けないため、自分で URL を確認する手段がありません。上のいずれかの方法で URL をコピーし、チャットやメールで本人に送ってください。 - [認証とログイン](https://keelson.dev/ja/docs/access-control/auth-and-login/) - [グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/) - [IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/) ## URL を変更する アプリ作成後も URL は変えられます(Owner / Admin)。コンソールのアプリ設定「公開 URL」から行います。 変更すると以前の URL からは開けなくなり、新しい URL への自動転送もありません。利用者に新しい URL を共有し、ブックマークや外部サービスの設定を更新します。影響を確認するチェックを付けてから変更します。 - 以前の URL は 30 日間予約され、他のアプリが同じ名前を使えません。その間のアクセスには、利用できなくなったことを示す `410 Gone` が返ります。30 日後に自動で解放されます - `keelson.yaml` の `slug` を変えてもアプリの URL は変わりません。`slug` はアプリの識別に使われます。コンソールでアプリの識別名も変更した場合は、次のデプロイ前に `keelson.yaml` の `slug` を合わせます ワークスペースの slug も設定から変更できますが、**既存アプリの URL は変わりません**。新しいワークスペース slug の形式に揃えたい場合は、アプリごとに公開 URL を更新します。 ## カスタムドメイン Team プランでは、`app.example.com` のような自社のサブドメインでアプリを利用できます。設定には、ドメインの管理画面で DNS を変更できる権限が必要です。社内のドメイン管理者に依頼する場合は、Keelson が表示する設定値を共有します。 - 対象: Team プラン。ワークスペース合計で 10 件まで、1 アプリに 1 ドメイン - サブドメインのみ。ルートドメイン(`example.com`)とメールドメインは対象外 - カスタムドメイン経由でも、認証・権限・IP 制御は同じように適用されます 設定は次の順で行います。 1. Owner または Admin が、コンソールのアプリ設定か `keelson domains add [--app ]` でドメインを登録します。登録すると、DNS に設定する CNAME の転送先が表示されます 2. DNS 事業者の設定で、登録したサブドメインの CNAME を表示された転送先へ向けます。本番環境の転送先は `custom-origin.keelson.run` です。コンソールまたは CLI に表示された値を使用してください 3. コンソールの状態表示か `keelson domains verify [--app ]` で有効になったことを確認します。有効化には数分かかることがあります 所有権の確認、HTTPS 証明書の発行、配信の設定は Keelson が自動で行います。 ## アプリの中から自分の URL を知る メール内のリンクなど、アプリが自分の URL を組み立てる場合の実装方法です。設定は AI エージェントに依頼できます。 アプリの標準 URL は環境変数 `KEELSON_APP_URL` で渡されます。リクエストの `Host` ヘッダーは内部のホスト名になるので、絶対 URL が必要な場面(メール内のリンク、リダイレクト、`og:url`)では `KEELSON_APP_URL` を使います。 ```python import os base_url = os.environ["KEELSON_APP_URL"] # 例: https://acme--dashboard.keelson.run ``` ローカル開発では設定されません。「Keelson 上で動いているか」の判別には `KEELSON_MODE` を使ってください。 公開 URL を変更しても、動いているアプリの環境変数はその場では更新されません。`KEELSON_APP_URL` を使うアプリは再デプロイし、メール内のリンクや移動先が新しい URL になっているか確認します。 カスタムドメインを設定しても、`KEELSON_APP_URL` は標準 URL のままです。メールのリンクなどにもカスタムドメインを使いたい場合は、その URL をアプリ側の設定値として持つようエージェントに依頼します([環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/))。 ## 関連ページ - [デプロイする](https://keelson.dev/ja/docs/deploy/deploy/) - [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) --- # アプリの状態とログ アプリの状態、サスペンドと再開、優先起動、ログ、デプロイ履歴とロールバック URL: https://keelson.dev/ja/docs/deploy/app-status-and-logs/ Language: ja --- アプリが使える状態か確認したり、不具合の原因を調べたりするときは、コンソールの状態表示とログを確認します。ログには、アプリの処理やエラー、アクセスの記録が残ります。 ## アプリの状態 コンソールのアプリ一覧とアプリ画面に、状態がバッジで表示されます。 | 状態 | 意味 | |---|---| | **稼働中** | 最近のアクセスにより、「同時に使えるアプリ数」の枠を 1 つ使っている | | **スリープ中** | デプロイ済みで、最近のアクセスによる枠を使っていない。停止しているアプリはアクセス時に自動で起動する | | **配信中** | 静的サイト / SPA を配信している。画面のファイルは Keelson が直接返す | | **サスペンド** | 手動で停止した状態。**アクセスがあっても起動・再公開しない**。データ・URL・設定は保持される | | **起動中** / **デプロイ中** | 起動・停止の切り替え、または新しいコードや設定の反映を処理している | | **未デプロイ** | アプリは作られているが、まだデプロイされていない | | **エラー** | 直近のデプロイまたは実行に失敗した。アプリ画面に原因が表示される | | **削除中** | 削除処理中。完了すると一覧から消える | | **—** | 定期実行だけのアプリ。ジョブごとの実行結果は「定期実行」タブで確認する | 「稼働中」「スリープ中」は利用状況の表示で、サーバーのプロセスが起動しているかを直接示すものではありません。Web アプリは、アクセスがない状態が続くと停止し、次のアクセスで起動します([アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/))。 通常は、直近 5 分にアクセスがあったアプリが枠を使います。優先起動で予約した枠は、アクセスがなくても確保されます。枠が空いていないときは、空くまで待つよう案内する画面が表示されます。予約していない枠は、そのアプリへのアクセスが約 5 分途絶えると空きます。 「エラー」は直近のデプロイの失敗を示す場合もあり、以前のバージョンが使えることがあります。「概要」の失敗内容と、アプリを実際に開けるかを合わせて確認します。 ### サスペンドと再開 一時的に止めたいアプリは、アプリ画面の「設定」→「サスペンド」でサスペンドします。サーバーを持つアプリだけでなく、静的サイトや SPA もサスペンドできます。サスペンド中は、アクセス・Webhook・cron のいずれでも起動せず、静的ファイルも配信されません。Keelson の標準 URL には停止ページが表示され、独自ドメインの配信も止まります。データ・URL・設定は削除されません。 再開はアプリ画面のヘッダーの「再開」から行います。静的サイトや SPA はサスペンド中にデプロイしても停止状態を維持し、明示的に再開したときに配信へ戻ります。静的ファイルの停止と再公開は順次反映されるため、操作後に配信状態が切り替わるまで少し時間がかかることがあります。 ### 優先起動 アプリ画面のヘッダーの「優先起動」を ON にすると、「同時に使えるアプリ数」の枠を常に 1 つ予約します。枠が埋まっていて起動できない、という状態を防げます。 - 枠を予約していても、アプリはアクセスがない状態が続くと停止します。次のアクセス時には起動を待つことがあります - Plus 以上で、枠数より 1 つ少ない数まで設定できます ## ログ 調べたいことに合わせて、次の場所を確認します。 | 調べたいこと | 確認する場所 | 記録される内容 | |---|---|---| | デプロイが失敗した理由 | 「デプロイ」の各デプロイにある「ログを表示」 | デプロイの進行と、失敗時のビルド・起動エラー | | アプリ使用中のエラー | 「ログ」のアプリログ | アプリが出力した処理の記録やエラー(標準出力・標準エラー) | | 利用者がアクセスを拒否された理由 | 「ログ」のアクセスログ | 誰が・いつ・どのパスにアクセスし、許可・拒否されたか | | 定期実行が成功したか | 「定期実行」の実行履歴 | 実行ごとの開始時刻・結果・所要時間・ログ | AI エージェントには、アプリ名・発生時刻・起きたことを伝えて調査を依頼できます。 > このアプリで[日時]に[操作]をするとエラーになりました。状態とログを確認し、原因と対応方法を教えてください。 ### ログの表示範囲と CLI アプリログは Web と定期実行(cron)を切り替えられます。画面には直近 200 行を表示し、エクスポートでは最大 5,000 行を取得できます。アクセスログは、利用者・機械(アプリトークン)・Webhook で絞り込めます。閲覧できる期間は[プラン](https://keelson.dev/ja/docs/workspace/plans-and-limits/)によって異なります。 CLI からは `keelson logs` で取得できます。エージェントが処理しやすい JSON 形式でアプリログを取得するには、`keelson logs app --json` を使います。デプロイ失敗時に確認するログは[トラブルシューティング](https://keelson.dev/ja/docs/deploy/troubleshooting/#どこで止まったかを特定する)にまとめています。 ## デプロイ履歴とロールバック 「デプロイ」タブに過去のデプロイが並び、各デプロイのソースのダウンロードとログの表示ができます。 コードを前のデプロイに戻す操作を「ロールバック」と呼びます。データベースの内容は戻らず、静的サイト / SPA は以前のファイルを再デプロイする必要があります。手順と戻せる範囲は[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/#コードを前の状態に戻す)にまとめています。 「再デプロイ」(アプリ画面ヘッダー)は、最後に成功したデプロイの実行用ファイルを使って起動し直す操作です。シークレットの「適用」も、コードを再アップロード・ビルドせずに再デプロイして反映します([環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/#登録した値をアプリに反映する))。 ## アプリの削除 アプリを廃止するときは「設定」→「危険な操作」から削除できます。ブラウザでの承認が必要で、利用者自身で取り消すことはできません。削除前に取り出すデータと保持期間は[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/#アプリを廃止する)を参照してください。一時的に止める場合は、上の「サスペンド」を使います。 ## 関連ページ - [プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/) - [トラブルシューティング](https://keelson.dev/ja/docs/deploy/troubleshooting/) - [CLI コマンド](https://keelson.dev/ja/docs/reference/cli/) --- # 更新と復元 アプリを安全に更新する手順と、事故が起きたときに何が戻り、何が戻らないか URL: https://keelson.dev/ja/docs/deploy/update-and-restore/ Language: ja --- アプリの変更を反映したり、不具合が起きたときに以前のコードやデータへ戻したりできます。やりたいことに合わせて操作を選びます。 | やりたいこと | 操作 | |---|---| | 変更した内容を反映する | [再度デプロイする](#アプリの変更を反映する) | | 更新前のコードに戻す | [ロールバックする](#コードを前の状態に戻す) | | 誤って変更・削除したデータを戻す | [DB の復元ポイントを使う](#誤って消したデータを戻す) | | 一時的に利用を止める | [サスペンドする](#アプリを廃止する) | | アプリを廃止する | [削除する](#アプリを廃止する) | 操作には、そのアプリの管理権限(`manage`)が必要です。データベースの復元とアプリの削除にはブラウザでの承認も必要です。 **コードを戻しても、データベースやファイルは以前の状態に戻りません。** 詳しい範囲は、後半の[何が戻り、何が戻らないか](#何が戻り何が戻らないか)で確認できます。 ## アプリの変更を反映する AI エージェントには、変更内容と確認してほしい操作を伝えます。 > この変更を Keelson に反映してください。デプロイ前に設定とアップロード対象を確認し、完了後に[操作]ができるか確認してください。 1. 手元の開発環境で変更内容を確認します 2. エージェントにデプロイを依頼します。CLI では `keelson deploy --check --json` で設定とアップロード対象を事前確認し、`keelson deploy` で反映できます 3. 完了したらアプリを開き、変更した操作を確認します。定期実行だけのアプリは実行履歴を確認します([デプロイ後の確認](https://keelson.dev/ja/docs/deploy/verify-deploy/)) 切り替え前に失敗した場合、以前のバージョンへのアクセスは維持されます。ただし `db.migrate` が途中まで実行された場合、その変更は残ります(下の「DB の構造を変える」)。 反映されるもの・されないもの(シークレットは保存後にデプロイまたは「適用」が必要、など)は[デプロイする](https://keelson.dev/ja/docs/deploy/deploy/#反映されるものされないもの)を参照してください。 ## コードを前の状態に戻す コードを以前のデプロイに戻す操作を「ロールバック」と呼びます。対象にできるのは、実行用のファイルをまとめた「コンテナイメージ」が残っている、過去の成功したデプロイです。 エージェントには「[不具合]が起きたので、前のコードに戻せるか、データへの影響も含めて確認してください」と依頼できます。CLI の操作は次のとおりです。 ```bash keelson rollback # 直前の成功したデプロイに戻す keelson rollback # 指定したデプロイに戻す ``` - ビルドし直さず、対象デプロイのイメージと `keelson.yaml` の設定でアプリを起動します - 対象にできるのは、イメージを持つ完了済みのデプロイだけです。**静的サイト / SPA のデプロイと、古い方式で作られたデプロイはロールバック先にできません** - シークレットは現在の値が使われます - 対象デプロイの `keelson.yaml` に `db.migrate` があれば、ロールバックでも切り替え前に実行されます。DB に一切触れない操作ではありません - **データベースは戻りません。** 更新時に DB の構造(スキーマ)を変えていた場合、戻したコードがその構造で動くか確認が必要です。列の追加でも制約や既定値によって影響が出るため、エージェントに互換性の確認を依頼します。必要に応じて DB の復元も検討します - デプロイ進行中は実行できません デプロイの一覧はコンソールの「デプロイ」タブにあり、各デプロイのソースをダウンロードできます。 **静的サイト / SPA** を戻すには、以前の成果物をもう一度デプロイします。Git で前のコミットに戻して手元でビルドし直すか、「デプロイ」タブから以前のデプロイのソース(`assets.dir` の中身と `keelson.yaml`)をダウンロードして、そのまま `keelson deploy` します。 ## 誤って消したデータを戻す Managed SQLite(`db.mode: libsql`)のデータは、コンソールのアプリ画面にある「復元ポイント」から戻します。 1. 復元ポイントのタイムラインから時点を選びます。日次バックアップ、手動で保存した状態(スナップショット)、指定した時刻への復元(PITR)のいずれかです(プランごとの保持世代数と復元窓は[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)) 2. 選択した過去の復元ポイントを**ダウンロード**して、中身を確認することもできます。この操作で取得するのは、現在の DB ではありません 3. **復元**を実行します。ブラウザでの承認が要ります 4. 復元後、アプリを開いてデータを確認します 復元で起きること: - **その時点以降の書き込みはすべて消えます。** 消したデータだけを戻す操作ではありません。現在のデータも残しておきたい場合は、復元を実行する前に現在の DB の手動スナップショットを作成し、そのスナップショットをダウンロードします。復元後に必要な変更を移す作業は、エージェントに相談できます - 復元前の状態は 72 時間保持され、その間は復元を取り消せます - 復元は 1 つのアプリの DB だけに効きます。他のアプリには影響しません - Files / Media のファイルと外部 DB は対象外です 大きな変更の前に手動スナップショットを作ると、戻す時点を残せます(1 アプリ 5 回/日)。 ## DB の構造を変える 保存する項目の追加など、DB の構造を更新する処理を「マイグレーション」と呼びます。コードを戻したときにも動くよう、エージェントには次の確認を依頼します。 > DB の構造を変更する場合は、更新前のコードでも動くか、失敗後に再実行しても問題がないかを確認してください。復元が必要になる変更は、実行前に影響と戻し方を教えてください。 ### マイグレーションの実装時の注意 `db.migrate` に書いたコマンドは、デプロイやロールバックで新しいバージョンへ切り替える前に実行されます。 - 失敗すると以前のバージョンへのアクセスは維持されます。ただし、**途中まで実行された DB の変更は自動では戻りません**。`keelson logs deploy ` のログと DB の状態を確認してから修正します - 同じ処理を繰り返しても重複した変更が起きないようにします。この性質を「冪等性」と呼びます。適用済みの変更を記録する仕組みや `IF NOT EXISTS` などを使い、途中で失敗した場合も確認します - 列やテーブルを追加する場合も、旧コードとの互換性を確認します。列の削除や型の変更など影響の大きい変更は、直前にスナップショットを作成し、利用の少ない時間帯に行う方法を検討します ## アプリを廃止する 「止める」と「消す」は別の操作です。 | 操作 | 何が起きるか | 戻せるか | |---|---|---| | **サスペンド**(アプリ画面の「設定」→「サスペンド」) | アクセス・Webhook・cron のいずれでも起動しない。URL には停止ページが出る。データ・URL・設定は残る | 「再開」でいつでも戻せる | | **削除**(「設定」→「危険な操作」) | アプリ本体・URL・デプロイ履歴・シークレットが消える。ブラウザでの承認が要る | **戻せない** | 削除の前に取り出しておくもの: - **DB のデータ** — 現在のデータが必要なら手動スナップショットを作り、その復元ポイントからダウンロード - **Files のファイル** — アプリにダウンロード処理を用意して取り出します - **Media のファイル** — アプリが記録したファイル ID から閲覧用リンクを作り、削除前に保存します。Files / Media とも、コンソールや CLI には一覧・ダウンロード機能がありません([ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/#ファイルの管理と容量)) - **ソースコード** — Git、または「デプロイ」タブの各デプロイからダウンロード - **シークレットの値** — 保存後は再表示されません。登録時の保管先や発行元で、必要な値を確認します 削除後、DB のバックアップ・Files・非機密の構成メモ(アプリ名、URL、cron 定義、環境変数とシークレットの**名前**)は 7 日間隔離保持されますが、これは誤削除への裁量対応であり、復元の保証ではありません。 契約が終了した場合のアプリの扱いは[料金と契約の運用](https://keelson.dev/ja/docs/workspace/billing/#解約後のアプリとデータ)を参照してください。 ## 何が戻り、何が戻らないか 表の「ロールバック」はコードを前のデプロイに戻す操作、「DB の復元」は Managed SQLite を復元ポイントに戻す操作です。 | 対象 | ロールバックで戻るか | DB の復元で戻るか | 備考 | |---|---|---|---| | コード(イメージ) | **戻る** | 戻らない | ビルドし直さず、対象デプロイのイメージを起動する。静的サイト / SPA は対象外 | | `keelson.yaml` の設定(`env`、`crons`、`assets`、`health`) | **戻る** | 戻らない | 対象デプロイ時点の設定が使われる | | シークレットの値 | 戻らない | 戻らない | 常に**現在の**値が使われる。コンソールで手で戻す | | Managed SQLite のデータ | 戻らない | **戻る** | 日次バックアップ、手動スナップショット、PITR(時刻復元) | | `db.migrate` で加えたスキーマ変更 | 戻らない | **戻る** | 復元ポイントの時点の DB 構造になる | | Files SDK のファイル | 戻らない | 戻らない | バックアップの対象外。アプリ側で保持する | | Media SDK のファイル | 戻らない | 戻らない | 上書き不可。差し替えは新しいファイルを保存する | | 外部 DB(PostgreSQL など) | 戻らない | 戻らない | 外部サービス側のバックアップで戻す | | 外部サービスへの変更(Slack 投稿、メール送信、決済) | 戻らない | 戻らない | ロールバックでは取り消されない。再実行時の重複に注意 | | アプリ権限、IP 制御、公開 URL | 戻らない | 戻らない | デプロイと独立した設定。手で戻す | ## 関連ページ - [アプリの状態とログ](https://keelson.dev/ja/docs/deploy/app-status-and-logs/) — サスペンド、デプロイ履歴、ログ - [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/#バックアップと復元) - [トラブルシューティング](https://keelson.dev/ja/docs/deploy/troubleshooting/) --- # トラブルシューティング デプロイやアプリが失敗したときに、どこを見て何をするか URL: https://keelson.dev/ja/docs/deploy/troubleshooting/ Language: ja --- デプロイに失敗したときや、アプリが期待どおりに動かないときの確認方法をまとめています。AI エージェントには、起きたこととエラーメッセージを伝えて、原因の調査を依頼できます。 ## 症状から探す | 症状 | 確認する項目 | |---|---| | デプロイできない | [どこで止まったかを特定する](#どこで止まったかを特定する) | | アプリを開けない | [アクセス権限](#利用者がアクセスできませんと言う)、[利用枠](#稼働枠が空いていない503)、[応答の時間制限](#504-gateway-timeout) | | 更新が見えない | [画面の更新](#更新したのに見た目が変わらない)、[シークレットの反映](#シークレットを変えたのに反映されない) | | データが残らない | [データの保存先](#データが消える) | | 定期実行やバックグラウンド処理が動かない | [定期実行の確認](#cron-が動かない)、[処理方法の確認](#バックグラウンド処理が動かない) | ## AI エージェントに調査を頼む > このアプリで[操作]をすると[症状]が起きます。発生したのは[日時]です。状態とログを確認し、原因と対応方法を教えてください。 エラーコード(`code`)、メッセージ(`message`)、対処のヒント(`hint`)が表示されていれば、一緒に伝えます。サービス側の障害など、アプリの修正では解決しない場合は、[サポートに問い合わせる](#サポートに問い合わせる)の情報をまとめます。 ## どこで止まったかを特定する コンソールでは、アプリ画面の「概要」に失敗の要約、「デプロイ」の「ログを表示」にデプロイログ、「ログ」にアプリログがあります。まず概要を確認し、必要に応じてエージェントに詳細を調べてもらいます。 ### CLI とログの詳細 `deploy_id` はデプロイを識別する ID で、CLI の出力やコンソールの「デプロイ」タブで確認できます。 ```bash keelson status # アプリと直近デプロイの状態 keelson diagnose # 失敗したデプロイの診断 keelson logs deploy # 進行ログと失敗したデプロイの詳細 keelson logs app # アプリの標準出力・標準エラー ``` 起動中にアプリが終了した場合も、`keelson logs deploy` や `keelson diagnose` から保存済みの起動ログを確認できます。エラーが起きたコードの位置や、必要な設定が足りないことなどが記録されます。
保存されるログの範囲 失敗したデプロイでは、ビルドや起動の詳細が保存されます。依存パッケージや Dockerfile、シークレット、設定、マイグレーションのエラーを後から調べるときにも使えます。起動時の例外の記録(traceback)やプロセスエラーは、保存済みの起動ログを確認します。 成功したデプロイのビルド出力は保存されません。進行ログも保存済みの失敗詳細もない場合は、ログがない理由が表示されます。
| 止まった場所 | 見るもの | よくある原因 | |---|---|---| | アップロード前(CLI の事前チェック) | コマンドの出力 | Go アプリに `go.mod` がない、Node アプリに pnpm / yarn 用ロックファイルしかない、`command` に `pip install`、`db.mode` がない、`env` の値が引用符なし | | 検証 | `code` と `message` | `workers` / `databases` が残っている、予約名、プラン上限 | | ビルド | デプロイログ | 依存の解決失敗、`package.json` と `package-lock.json` の不一致、非公開のパッケージ配布先(private registry)、cgo が必要な Go パッケージ、ビルドスクリプトのエラー | | 起動 | `keelson logs deploy ` の保存済みのアプリの起動ログ | `0.0.0.0` で listen していない、`PORT` のハードコード、未設定のシークレットで例外 | | ヘルスチェック | 保存済みのアプリの起動ログ、その後にアプリログ | アプリが起動中に終了、`/` が 5xx、起動に 120 秒以上かかる | | マイグレーション | デプロイログ | `db.migrate` の SQL エラー。以前のバージョンへのアクセスは維持されますが、**マイグレーションが加えた DB の変更は自動では戻りません**。DB の状態を確認してから直します | | 動いているが期待どおりでない | アプリログ、アクセスログ | 下の「よくある失敗」 | ## よくある失敗 ### デプロイ中に Ctrl-C を押した Ctrl-C で止まるのは、このクライアントによる監視だけです。デプロイはサーバー側で続いています。 そのまま新しいバージョンへ切り替わることがあるため、CLI に表示された `deploy_id` で進行状況を確認します。 ```bash keelson status ``` 新しいバージョンを使わない場合は、デプロイの完了後に以前のコードへ戻します。コンテナイメージが残っている過去の成功したデプロイには、次のコマンドで戻せます。DB の変更は戻りません。 ```bash keelson rollback --app ``` 静的サイト / SPA はロールバックの対象外です。以前のファイルを再デプロイします。手順は[更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/#コードを前の状態に戻す)を参照してください。 戻せるデプロイがない場合など、いったん利用を止めたいときは、デプロイ完了後にサスペンドします。 ```bash keelson app stop --app ``` ### ローカルでは動くが Keelson で落ちる 手元と Keelson で設定や保存先が異なる可能性があります。エージェントには、次の点を確認してもらいます。 - **手元からの接続だけを受け付けている** — 待ち受けアドレスを `localhost` から `0.0.0.0` に変える - **接続を受け付けるポート番号をコードで固定している** — `PORT` 環境変数から読む - **ローカルにしかないファイルに依存している** — `.env`、ローカルの DB ファイル、`.gitignore` 済みのファイル。`keelson deploy --check --json` の `archive.excluded` で、何が除外されたか分かります - **環境変数が未設定** — ローカルの `.env` にだけある値は Keelson にはありません。`secrets` に宣言して値を設定する - **ローカルの SQLite ファイルを使っている** — `/data` も `/tmp` も再起動後にデータが残りません。Managed SQLite への移行を検討する ### Node アプリのロックファイルが拒否される Keelson の Node ビルダーは npm を使うため、依存を固定するには npm 用の `package-lock.json` が必要です。エージェントに、プロジェクトのルートで `npm install` を実行して `package-lock.json` を生成し、依存関係の整合性を確認してから再デプロイするよう依頼します。生成したファイルはソースコードと一緒に管理します。 `pnpm-lock.yaml` や `yarn.lock` は削除しなくてかまいません。`package-lock.json` と同居していてもデプロイでき、ビルドには `package-lock.json` が使われます。 ### データが消える 保存先がアプリのサーバー内のファイルになっていないか確認します。`/tmp`、`/data`、アプリディレクトリのファイルは、再起動・再デプロイ・アイドル停止で失われます。[データベース](https://keelson.dev/ja/docs/building-apps/persistent-storage/)か [Files / Media SDK](https://keelson.dev/ja/docs/building-apps/files-and-media/) に置きます。 ### バックグラウンド処理が動かない サーバー側でレスポンスを返した後に続ける処理は、最後まで実行されることが保証されません。また、アプリ内のタイマーは、アプリの停止中には動きません。 エージェントに、そのリクエストで必要な処理は応答を返すまでに完了させ、定期的な処理は Keelson の定期実行ジョブへ移すよう依頼します。後でまとめて処理する場合は、未処理の内容を DB に保存する方法もありますが、次の実行まで待ち時間が生じます。ブラウザ側のタイマーは、この制約の対象外です。詳しくは[アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)を参照してください。 ### 定期実行(cron)が動かない - スケジュールがプランの最小間隔より短くないか(デプロイ時に拒否されます) - 前回の実行が終わっていないか(重複実行はスキップされます) - 月間実行回数の上限に達していないか(当月はスキップ) - アプリがサスペンドされていないか - 「定期実行」タブの実行履歴で、スキップの理由を確認できます ### 更新したのに見た目が変わらない ブラウザに古いファイルが残っている可能性があります。デプロイの完了を確認し、ページを強制再読み込みします(Mac: `Cmd + Shift + R` / Windows: `Ctrl + Shift + R`)。 静的サイトの更新は配信先へ順次反映されるため、完了後も少し時間がかかることがあります。変わらない場合は、更新先のアプリとアップロードしたファイルが合っているか、エージェントに確認を依頼します。 ### 利用者が「アクセスできません」と言う 1. ワークスペースのメンバーか(招待が未承諾でないか) 2. ブロックされていないか 3. アプリの閲覧権限があるグループに入っているか 4. 登録されたアカウントでログインしているか 5. IP 制御で拒否されていないか(403 画面に送信元 IP が出ます) 詳細は[メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/#アクセスできないときの確認)。 ### 「稼働枠が空いていない」(503) 「同時に使えるアプリ数」の上限です。直近 5 分にアクセスがあったアプリと、優先起動を設定したアプリが枠を使っています。予約していない枠を使うアプリへのアクセスが途絶えてから約 5 分待つか、重要なアプリに[優先起動](https://keelson.dev/ja/docs/deploy/app-status-and-logs/#優先起動)を設定するか、プランを上げます。 ### 504 Gateway Timeout 応答までに時間がかかりすぎた場合などに表示されます。Keelson では、応答開始まで 120 秒、ストリーミングを含む全体で 300 秒、ストリーミングの応答間隔で 120 秒の上限があります([HTTP の時間上限](https://keelson.dev/ja/docs/workspace/plans-and-limits/#http-の時間上限))。 エージェントに、時間のかかっている処理を調べ、処理を短くする・結果を少しずつ返す・定期実行に分ける方法を検討してもらいます。ストリーミングでも時間上限はなくなりません。 504 が表示されても、サーバー側では保存や送信が完了している場合があります。再操作する前に結果を確認します。実装では、同じ依頼を繰り返しても重複して保存・送信しない仕組み(冪等性)が必要です。 ### Webhook が 401 / 403 になる - パスが `auth.endpoints` に宣言されているか(`/api/webhooks/` か `/api/external/` で始まる必要があります) - メソッドが宣言と合っているか - トークンのスコープと許可 IP が合っているか [外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/)。 ### シークレットを変えたのに反映されない シークレットは保存しただけでは、動いているアプリに反映されません。コードも更新する場合はデプロイし、値だけを反映する場合はコンソールの「適用」を押します。「適用」は、コードを再アップロード・ビルドせずに再デプロイします([環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/#登録した値をアプリに反映する))。 ## サポートに問い合わせる `deploy.platform.error` のようにプラットフォーム側のエラーが出た場合や、上記で解決しない場合は、[お問い合わせ](https://keelson.dev/ja/contact/)から連絡してください。 次を添えると、やり取りの往復が減ります。 | 添えるもの | 取り方 | |---|---| | ワークスペースの slug | `keelson workspaces list --json` の `slug`(URL は名前の変更前のものが残る場合があります) | | アプリの slug | `keelson.yaml` の `slug`、または `keelson apps list --workspace <ワークスペース slug> --json` の `slug` | | `deploy_id` | `keelson status --json` の出力、またはコンソールの「デプロイ」タブ | | エラーの `code` と `message` と `hint` | CLI の出力をそのまま。`--json` を付けるとまとめて取れます | | 起きた日時とタイムゾーン | ログを引くときに使います | | 利用者が開けない場合は、その人のメールアドレスと 403 画面に出た IP | [利用者が「アクセスできません」と言う](#利用者がアクセスできませんと言う) | アプリのソースコードやシークレットの値は送らないでください。必要になれば、こちらから範囲を指定して依頼します。 料金・契約・請求書についての問い合わせも同じ窓口です([料金と契約の運用](https://keelson.dev/ja/docs/workspace/billing/))。 ## 関連ページ - [エラーコード](https://keelson.dev/ja/docs/reference/error-codes/) - [アプリの状態とログ](https://keelson.dev/ja/docs/deploy/app-status-and-logs/) - [CLI コマンド](https://keelson.dev/ja/docs/reference/cli/) # ユーザーと権限 --- # 認証とログイン アプリを利用できる人の制限と、利用者のログイン方法・流れ URL: https://keelson.dev/ja/docs/access-control/auth-and-login/ Language: ja --- Keelson では、社内アプリを利用できる人を、ワークスペースのメンバーのうち閲覧権限を持つ人に限定できます。利用者はアプリの URL を開き、Keelson のログイン画面でログインします。URL を知っているだけではアプリを開けません。 ログイン画面やログイン状態の管理は Keelson が用意するため、アプリ側で作る必要はありません。利用できる人の設定は[チームにアプリを共有する](https://keelson.dev/ja/docs/access-control/share-with-team/)で説明しています。 ## ログインの方法 アプリの利用者は、次のいずれかでログインします。 - **Google アカウント** - **Microsoft アカウント** - **メールアドレス**(ログイン用の使い捨てコードをメールで受け取る) ワークスペースに登録されているメールアドレスでログインする必要があります。複数のアカウントを使い分けている場合は、登録されたアカウントを選んでください。 ワークスペースを作成する(コンソールにサインアップする)ときは、Google または Microsoft アカウントが必要です。 ## ログインの流れ 1. アプリの URL を開きます。 2. ログインしていなければ、Keelson のログイン画面が表示されます。 3. Google / Microsoft アカウント、またはメールで受け取ったコードでログインします。 4. 元のアプリに戻り、閲覧権限があればアプリが表示されます。 ログイン状態が保持されている間は、同じワークスペースの別のアプリも、ログインし直さずに開けます。それぞれのアプリの閲覧権限は必要です。 開けない場合は[アクセスできないときの確認](https://keelson.dev/ja/docs/access-control/members-and-permissions/#アクセスできないときの確認)を参照してください。 ## ログインした人の情報をアプリで使う アプリでは、ログインした人の名前を表示したり、その人のデータに絞って表示したりできます。AI エージェントには「Keelson が渡す利用者情報を使って、本人のデータだけを表示できるようにして」と依頼できます。 Keelson は、サーバー側のコードに利用者情報を渡します。その情報を使って、どのデータを表示・更新できるかを判断する処理はアプリ側で実装します。詳しくは[ログイン中のユーザー情報を使う](https://keelson.dev/ja/docs/building-apps/using-identity/)を参照してください。
利用者情報の受け渡し(HTTP ヘッダー) 認証を通ったリクエストには、Keelson が利用者情報を HTTP ヘッダーという付加情報として付けます。主なヘッダーは次のとおりです。 | ヘッダー | 内容 | |---|---| | `X-Keelson-User-Id` | 利用者の ID | | `X-Keelson-User-Email` | メールアドレス | | `X-Keelson-User-Name` | 名前 | | `X-Keelson-User-App-Perms` | そのアプリの権限 | クライアントが送った同名の利用者情報ヘッダーはエッジで除去され、認証ゲートウェイがプラットフォームの DB から取得した値を付けます。ブラウザから送られた `Authorization` と `Cookie` も除去されます。利用者の確認には、Keelson が付けた情報を使います。
## 判定の順序 ブラウザからアプリを開くと、Keelson がログイン状態や権限を確認します。アプリの手前でこの確認を行う仕組みをプロキシと呼びます。 ```text ブラウザ │ ▼ Keelson ① ログインしているか ② ワークスペースの有効なメンバーか ③ このアプリの閲覧権限があるか ④ IP 制御の条件を満たすか │ ▼ アプリ すべての条件を満たしたリクエストが届く ``` - ①を満たさない場合は、ログイン画面へ移動します。 - ②③を満たさない場合は、「アクセスできません」の画面になります。 - ④を満たさない場合は、アクセスが拒否されたことを示す画面(HTTP 403)になり、接続元の IP アドレスが表示されます。 IP 制御は、接続元のネットワークでアクセスを制限する設定です。**静的サイト・SPA・ハイブリッドアプリの静的ファイルには、IP 制御が適用されません。** ログイン・メンバー・閲覧権限の確認は行われます。詳しくは[IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/)を参照してください。 ## ログインなしで呼ばれる経路 外部サービスからの通知(Webhook)や API 呼び出しでは、ブラウザでログインする代わりに、アプリトークンや送信元の署名で呼び出し元を確認します。 AI エージェントには、連携したいサービスと受け取りたい通知・データを伝えて、設定と実装を依頼できます。ログインなしで受け付けるパスとメソッドは、`keelson.yaml` の `auth.endpoints` に設定します。詳しくは[外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/)を参照してください。 ## 関連ページ - [メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/) - [グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/) - [IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/) --- # メンバーとロール アプリを使う人・作る人・管理する人の役割と、メンバーの参加・無効化 URL: https://keelson.dev/ja/docs/access-control/members-and-permissions/ Language: ja --- アプリを一緒に使う人を、ワークスペースのメンバーとして追加できます。アプリを使う人、作って更新する人、メンバーや設定を管理する人に合わせて、役割を選びます。この役割を「ロール」と呼びます。 アプリを使うにはメンバーであることが必要です。利用できるアプリは、所属グループに割り当てられた[アプリごとの権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/)で決まります。 ## ロール アプリを使うだけの人には App User、作って更新する人には Developer を選びます。メンバーやワークスペースの設定を管理する人には Admin、請求や Owner の管理も担う人には Owner を割り当てます。 | ロール | 主な用途・できること | |---|---| | **Owner** | ワークスペースの責任者。Owner を含むメンバー管理、設定、請求を扱う | | **Admin** | チームの管理者。Owner 以外のメンバー管理とワークスペースの設定を扱う | | **Developer** | アプリを作ってデプロイ・更新する。メンバー管理やワークスペースの設定変更はできない | | **App User** | 閲覧権限のあるアプリを使う。コンソールでの管理操作は行わない | Owner・Admin・Developer の人数は、プランの開発・管理用の人数枠(Developers 席)に数えられます。App User はこの人数枠に含まれず、人数無制限です。詳しくは[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)を参照してください。 ロールは「メンバー」画面から Owner / Admin が変更できます。Owner ロールの付与・変更は Owner だけができます。ワークスペースには最低 1 人の Owner が必要です。 ## メンバーの参加方法 | 方法 | 参加するまでの流れ | |---|---| | [招待](https://keelson.dev/ja/docs/workspace/invite-members/) | Owner / Admin がメールアドレスを指定し、招待された本人がリンクを開いて招待を承諾する | | 参加 URL | 許可されたメールドメインの人が URL を開き、ログインして参加する。管理者の承認は不要 | | ワークスペースを探して参加申請(Discover) | 許可されたメールドメインの人が申請し、Owner / Admin が承認する | メールドメインは、メールアドレスの `@` より後ろの部分です。会社のメールドメインを許可すると、そのアドレスを持つ人が参加 URL や Discover を使えるようになります。設定は[ドメインと参加ポリシー](https://keelson.dev/ja/docs/workspace/domain-join/)で説明しています(Team プラン以上)。ドメイン自動参加で入ったメンバーのロールは App User です。 ## メンバーの無効化 退職などでワークスペース内のすべてのアプリへのアクセスを止めたいときは、Owner / Admin が「メンバー」画面でそのメンバーを**無効化**します。異動などで利用できるアプリだけを変えたい場合は、[所属グループやアプリの権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/)を変更できます。 - 無効化がアクセス判定に反映されるまで、時間がかかることがあります。保存直後にすべてのアクセスが止まるとは限りません。 - アカウントの削除ではありません。「再有効化」で戻せます。 - 自分自身と、最後の Owner は無効化できません。Admin は Owner を無効化できません。 ## ロールとアプリの権限の関係 ロールに応じて、次のグループに自動的に所属します。これらはシステムグループと呼ばれ、所属メンバーを手動では変更できません。 | ロール | 自動的に所属するグループ | |---|---| | **Owner** | `owners` `developers` `everyone` | | **Admin** | `admins` `developers` `everyone` | | **Developer** | `developers` `everyone` | | **App User** | `everyone` | 新しいアプリには、`everyone`(全メンバー)に閲覧権限、`developers`(Owner / Admin / Developer)に管理権限が割り当てられます。管理権限には閲覧も含まれます。 アプリを利用・管理できるかは、このグループへの権限の割り当てで決まります。ロールを変更すると自動所属グループも変わるため、アプリへのアクセスにも影響します。特定のチームに利用を限定する手順は[チームにアプリを共有する](https://keelson.dev/ja/docs/access-control/share-with-team/)を参照してください。 ## アクセスできないときの確認 利用者はまず、招待・登録されたメールアドレスでログインしているかを確認します。メンバーの状態は Owner / Admin に、アプリの権限はそのアプリを管理する人に確認を依頼できます。 1. **登録されたアカウントでログインしているか** — 複数の Google / Microsoft アカウントを使い分けている場合は、メールアドレスを確認します。 2. **メンバーになっているか** — 「メンバー」画面で確認します。招待が未承諾なら、本人に承諾してもらいます。 3. **無効化されていないか** — 「メンバー」画面の「無効化済み」で確認できます。 4. **アプリの閲覧・管理権限があるか** — アプリ画面の「権限」で、その人の所属グループへの割り当てを確認します。 5. **IP 制御で拒否されていないか** — IP 制御による拒否画面には、接続元の IP アドレスが表示されます。適用範囲は[IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/)を参照してください。 ## 関連ページ - [グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/) - [メンバーを招待する](https://keelson.dev/ja/docs/workspace/invite-members/) - [ドメインと参加ポリシー](https://keelson.dev/ja/docs/workspace/domain-join/) - [認証とログイン](https://keelson.dev/ja/docs/access-control/auth-and-login/) --- # チームにアプリを共有する 営業メンバーとアプリ管理者が使えるように設定し、URL を共有してアクセスを確認する URL: https://keelson.dev/ja/docs/access-control/share-with-team/ Language: ja --- アプリを使う人を特定のチームに限定して、URL を共有できます。このページでは、営業チームのメンバーと、アプリを管理する人が使えるように設定します。 招待とグループ作成には Owner / Admin、アプリの権限変更にはそのアプリの管理権限が必要です。全プランで利用できます。 ここで設定するのは、アプリを開ける人の範囲です。「自分の申請だけ見える」「上司だけ承認できる」といった業務上の権限は、アプリ側で実装します。 ## 1. メンバーを招待する 「メンバー」→「招待」で、営業チームのメールアドレスを入力し、ロールは **App User** を選びます。アプリを使うだけの人向けのロールで、開発・管理用の人数枠(Developers 席)には含まれません。 相手はメールのリンクを開き、招待されたアドレスと同じアカウントでログインして、招待を承諾します。詳細は[メンバーを招待する](https://keelson.dev/ja/docs/workspace/invite-members/)を参照してください。すでに参加している人を再度招待する必要はありません。 社員が多い場合は、Team プラン以上で[ドメイン自動参加](https://keelson.dev/ja/docs/workspace/domain-join/)を使うと、招待なしで参加できます。 ## 2. グループを作る グループは、アプリの権限をまとめて割り当てるためのメンバーの集まりです。「メンバー」→「グループ」で「営業」グループを作り、営業チームのメンバーを追加します。 グループには、表示名とは別に、設定やコマンドで指定する名前(キー)を付けます。この例では `sales` を使います。キーは作成後に変更できませんが、表示名とメンバーは変更できます。 ## 3. アプリを使えるグループを設定する アプリ画面の「権限」タブを開きます。閲覧権限はアプリを開いて使う権限、管理権限はアプリをデプロイしたり設定を変更したりする権限です。**管理権限には閲覧も含まれます。** 新しいアプリでは、`everyone`(全メンバー)に閲覧、`developers`(Owner / Admin / Developer)に管理が割り当てられています。「営業」に閲覧を追加するだけでは、`everyone` の閲覧が残り、全員が開ける状態が続きます。 1. 閲覧グループから **`everyone` を外します**。 2. 閲覧グループに **`sales` を加えます**。 3. この例では、管理グループを `developers` のままにして保存します。 これで、営業メンバーと `developers` のメンバーがアプリを開ける設定になります。営業以外の App User は開けません。すでに権限を変更したアプリでは、ほかの閲覧・管理グループが残っていないかも確認します。 管理する人の範囲も変えたい場合は、[グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/)を参照してください。そのアプリの管理権限を持つ人は、閲覧グループに入っていなくてもアプリを開けます。 設定の保存後、アクセス判定への反映には時間がかかることがあります。ログイン中の利用者についても、反映後は変更した権限で判定されます。 ## 4. URL を渡す アプリ画面の URL(`https://<ワークスペース>--<アプリ>.keelson.run`)をコピーして、チャットやメールで共有します。App User はコンソールでアプリの URL を確認できず、招待メールにもアプリの URL は含まれません。 「招待されたメールアドレスでログインしてください」と添えると、複数のアカウントを使う人にも伝わります。 ## 5. 共有相手と対象外の人で確認する 共有したい人が開けることと、閲覧・管理のどちらの権限も持たない人が開けないことを確認します。 | 確認 | 期待する結果 | |---|---| | 営業グループの利用者が URL を開く | ログイン後にアプリが表示される | | 営業グループに入っていないアプリ管理者が URL を開く | ログイン後にアプリが表示される | | 営業グループに入っておらず、ほかのグループ経由でも閲覧・管理権限を持たない App User が URL を開く | ログイン後に「アクセスできません」の画面になる | | ログインしていない人が URL を開く | Keelson のログイン画面になり、アプリは表示されない | 対象外の利用者に確認を頼めない場合は、自分の別のメールアドレスを App User として招待し、営業グループに追加せずに試せます。 保存した設定は、アプリ一覧の「アクセス範囲」で確認できます。全員に閲覧を許可していなければ、人数とグループが表示されます。実際に開けるかどうかは、上の手順で確認します。 ## うまくいかないとき | 症状 | 確認すること | |---|---| | 営業の人が開けない | 招待を承諾しているか、`sales` に所属しているか、登録されたメールアドレスでログインしているかを確認します | | 営業以外の人も開ける | `everyone` やほかの閲覧グループが残っていないか、その人が管理グループに所属していないかを確認します | | 保存した設定でアクセスが変わらない | 反映に時間がかかることがあります。少し待って再読み込みし、「権限」タブの保存内容と、確認に使ったアカウントを見直します | メンバーの無効化や IP 制御など、その他の確認項目は[アクセスできないときの確認](https://keelson.dev/ja/docs/access-control/members-and-permissions/#アクセスできないときの確認)を参照してください。 ## AI エージェントに設定を依頼する場合 グループ作成やアプリの権限設定は、CLI を使える AI エージェントにも依頼できます。対象のワークスペース、アプリ名、共有する人のメールアドレス、管理権限を残す人を伝えます。操作には、コンソールで設定する場合と同じ権限が必要です。 > アプリ `sales-tool` を、営業チームとアプリ管理者が使えるように設定してください。招待済みの tanaka@example.com と suzuki@example.com を「営業」グループ(キー: `sales`)に追加し、閲覧は `sales`、管理は `developers` に設定してください。設定後に、閲覧・管理を許可したグループを教えてください。 AI エージェントによる設定後も、手順 5 のアカウントごとのアクセスを確認します。
CLI で設定する例 招待の承諾が済んだメンバーを、作成したグループに追加します。次のコマンドは、コンソールで行う手順 2・3 と同じ設定です。コンソールで設定済みの場合は実行不要です。 ```bash keelson groups create sales --name "営業" keelson groups members add sales tanaka@example.com suzuki@example.com keelson access set --app sales-tool --view sales --manage developers ``` `access set` には、残したい閲覧・管理グループを指定します。この例では閲覧を `sales`、管理を `developers` に設定します。
## アプリの中で「本人の分だけ」にする ここまでの設定で、アプリを開ける人の範囲を決められます。さらに「自分の申請だけを見せたい」場合は、AI エージェントに次のように依頼できます。 > Keelson が渡すログイン中の利用者情報を使い、本人の申請だけを表示してください。他人の申請の URL や ID を指定しても、取得・更新できないようにし、その確認も行ってください。 利用者ごとの画面表示に加えて、データを取得・更新するサーバー側でも権限を確認する処理が必要です。AI エージェントには、別の利用者のデータを取得・更新できないことをどう確認したかも報告してもらうと、実装結果を確認できます。 判定には、Keelson が付けた利用者 ID(`X-Keelson-User-Id`)やグループ情報を使います。ブラウザから送られた値だけで本人と判断しないようにします。実装は[ログイン中のユーザー情報を使う](https://keelson.dev/ja/docs/building-apps/using-identity/)を参照してください。
ワークスペース・アプリ・業務上の権限の違い | 権限 | 設定する人・場所 | 例 | |---|---|---| | ワークスペースの管理権限(ロール) | Owner / Admin が付与。Owner の付与・変更は Owner のみ | メンバーを招待できるか、請求を扱えるか | | アプリの閲覧・管理権限(view / manage) | そのアプリの管理権限を持つ人が、グループに割り当てる | アプリを開けるか、デプロイ・設定変更ができるか | | アプリ内の業務上の権限 | アプリ側で実装する | 自分の申請だけ見られるか、上司として承認できるか | アプリの管理権限は、デプロイや設定変更を行う人のための権限です。業務上の承認者と同じ人とは限りません。ロールの詳細は[メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/)を参照してください。
## 関連ページ - [グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/) — 権限の仕組みと CLI - [メンバーを招待する](https://keelson.dev/ja/docs/workspace/invite-members/) - [IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/) — 接続元のネットワークでも制限する - [アプリ URL とドメイン](https://keelson.dev/ja/docs/deploy/public-url/) # ワークスペースと契約 --- # メンバーを招待する メールアドレスでメンバーを招待し、招待を管理する URL: https://keelson.dev/ja/docs/workspace/invite-members/ Language: ja --- 作ったアプリを同僚に使ってもらうときは、メールアドレスを指定してワークスペースに招待します。アプリを使うだけの人と、作成や更新も行う人で、招待時に選ぶロールが異なります。 招待は **Owner または Admin** が行えます。全プランで利用できます。相手が招待を受け入れ、「メンバー」画面で参加を確認できれば完了です。 ## ロールの選び方 アプリを作る・管理する人の人数枠を「Developers 席」と呼びます。App User はこの枠を使いません。 | 招待する相手 | ロール | Developers 席 | |---|---|---| | アプリを使う人 | **App User** | 消費しない | | アプリを作ってデプロイする人 | **Developer** | 消費する | | メンバー管理も任せる人 | **Admin** | 消費する | | ワークスペースの共同責任者 | **Owner** | 消費する | Admin は Owner ロールで招待できません。Developer と App User は他のユーザーを招待できません。 Developer 以上のロールで招待すると、招待を出した時点で Developers 席を 1 つ確保します(相手が招待を受け入れる前でも)。席が上限に達していると、これらのロールでは招待できません。App User は席に関係なく何人でも招待できます。 ## 招待する(Owner / Admin) 1. コンソールの「メンバー」を開き、「メンバーを招待」を選びます 2. メールアドレスを入力します(1 回に最大 50 件) 3. ロールを選びます 4. 「招待を送信」を選びます 招待された人に、リンク付きのメールが自動で送られます。リンクはコンソールにも表示されるので、メールが届かない場合は直接共有できます。 有効期限は作成から **3 日間(72 時間)** です。 ## 招待を受け取った人 1. メールのリンクを開きます 2. **招待されたメールアドレスと同じ** Google / Microsoft アカウント、またはメールのワンタイムコードでログインします 3. 「参加」を選び、招待を受け入れます 別のメールアドレスでログインしている場合は、招待されたアドレスでログインし直します。 参加後に使えるアプリは、[アプリごとの権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/)で決まります。既定では全メンバーが全アプリを使えます。 ## アプリの URL を共有する 招待した人は、使ってほしいアプリの URL をチャットやメールで相手に送ります。招待メールには、アプリの URL は含まれません。 App User はコンソールを開けず、アプリの一覧も表示されません。参加後の画面には、アプリの URL を招待した人に確認する案内が表示されます。 ## 招待の管理 「メンバー」画面では、招待を受け入れる前の人は「保留中」、参加した人は「アクティブ」と表示されます。 - **取り消し** — まだ受け入れられていない招待を無効にします - **再送** — まだ受け入れられていない招待に新しいリンクを発行します。古いリンクは無効になり、有効期限は再送時から 3 日間(72 時間)です - 期限切れ・取り消し済みの招待は、同じアドレスで新しく作り直します ## うまくいかないとき | 症状 | 確認すること | |---|---| | 招待が作れない | Owner / Admin か。既に参加済みでないか。Developer 以上なら席が空いているか | | メールが届かない | 迷惑メールフォルダ。届かなければコンソールのリンクを直接共有 | | 招待を受け入れられない | 招待されたアドレスでログインしているか。期限切れ・取り消しになっていないか | | 参加したのにアプリが開けない | アプリの閲覧権限、ログイン中のアカウント、IP 制御 | ## 招待以外の参加方法 自社ドメインのユーザーを招待なしで参加させるには、[ドメインと参加ポリシー](https://keelson.dev/ja/docs/workspace/domain-join/)を設定します(Team 以上)。 ## 関連ページ - [メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/) - [プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/) — Developers 席 --- # グループとアプリ権限 誰がどのアプリを使えるか・管理できるかを決める URL: https://keelson.dev/ja/docs/workspace/groups-and-app-access/ Language: ja --- 「経理のアプリは経理チームに」「社内のお知らせは全員に」のように、アプリを使える人をグループで指定できます。アプリの更新や設定変更を行う人も、別に指定できます。 - **必要な権限 / プラン**: グループの作成・メンバー変更は Owner / Admin。アプリの権限変更は、そのアプリの `manage` を持つ人。全プラン - **完了条件**: 対象の人でアプリが開け、閲覧・管理のどちらの権限も持たない人では「アクセスできません」になる 目的別の手順は[チームにアプリを共有する](https://keelson.dev/ja/docs/access-control/share-with-team/)にあります。 ## 権限は 2 種類 | 権限 | できること | |---|---| | **閲覧(view)** | 実行中のアプリを開いて使う | | **管理(manage)** | アプリのデプロイ、設定変更、シークレット編集、権限の変更。閲覧も含む | 権限はユーザー個人ではなく**グループ**に割り当てます。グループのメンバーを変えると、そのグループを割り当てたアプリの利用者・管理者も変わります。 ロール(Owner / Admin / Developer / App User)は、ワークスペースで行える操作を決めます。アプリを使えるかどうかは、上の閲覧・管理権限で決まります。ただし、[IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/)の設定は Owner / Admin が行い、アプリの管理権限だけでは変更できません。 ## 既定の割り当て アプリを作ると、次が自動で割り当てられます。 | グループ | 権限 | |---|---| | `everyone`(全メンバー) | 閲覧 | | `developers`(Owner / Admin / Developer) | 管理 | つまり何もしなければ、ワークスペースの全員がアプリを使え、開発者ロールの人が管理できます。絞りたいアプリだけ変更します。 **特定のグループだけに絞るときは、`everyone` の閲覧を外す必要があります。** 「経理」グループに閲覧を足しただけでは、`everyone` の閲覧が残っているので全員が開けたままです。また `manage` には閲覧が含まれるので、管理グループ(既定では `developers`)のメンバーは閲覧グループに入っていなくても開けます。 ## グループ 「メンバー」→「グループ」で管理します。 **システムグループ** — ロールから自動的に決まります。編集できません。 | キー | メンバー | |---|---| | `owners` | Owner | | `admins` | Admin | | `developers` | Owner / Admin / Developer | | `everyone` | 全メンバー | **カスタムグループ** — 「経理」「営業」「店舗スタッフ」など、業務の単位で作ります。キー(`経理` のような識別子。日本語も可)は作成後に変更できません。表示名とメンバーは変更できます。アプリに割り当てられている間は削除できません。 ## アプリに権限を割り当てる アプリ画面の「権限」タブで、閲覧グループと管理グループを選びます。 - 管理グループは最低 1 つ必要です(空にはできません。メンバーがいないグループだけにもできません) - 自分の管理権限を外す操作は、他の管理グループに有効なメンバーがいる場合でも確認を求められます - 保存した変更は、ログイン中のユーザーも含め、通常 2 分以内に反映されます ## よくある構成 | やりたいこと | 設定 | |---|---| | 全員が使える社内ツール | 既定のまま | | 経理チームとアプリを管理する開発者が使える | 閲覧: `keiri`、管理: `developers` | | 利用は全員、設定変更は管理者だけ | 閲覧: `everyone`、管理: `admins` | ## アプリ内の業務上の権限 「上司だけが申請を承認できる」「部署ごとに見せる情報を変える」といったルールは、アプリ側に実装します。アプリを更新するための管理権限とは別に、誰がどの情報を見たり変更したりできるかを決めます。 AI エージェントには、たとえば「経理グループだけが経費の一覧を見られるようにして」と依頼します。作成後は、対象のグループの人と、それ以外の人で表示や操作を確認します。 実装では、部署などのグループは `attributes.groups`、アプリの管理権限は `X-Keelson-User-App-Perms` の `manage` で確認できます。詳しくは[認証情報をアプリで使う](https://keelson.dev/ja/docs/building-apps/using-identity/)を参照してください。 ## アプリ一覧での見え方 アプリ台帳の「アクセス範囲」に、全員に公開されていれば「全員」、限定されていれば対象の人数とグループが表示されます。 ## CLI で設定する AI エージェントに設定を依頼するときは、グループに含める人と、アプリを使う人・管理する人を伝えます。次は CLI での操作例です。 ```bash keelson groups list keelson groups create keiri --name "経理" keelson groups members add keiri tanaka@example.com suzuki@example.com keelson access show --app my-app keelson access set --app my-app --view keiri --view admins --manage admins keelson access set --app my-app --view none # 閲覧を空にする。管理権限を持つ人は利用可能 ``` ## 関連ページ - [メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/) - [認証情報をアプリで使う](https://keelson.dev/ja/docs/building-apps/using-identity/) - [IP 制御](https://keelson.dev/ja/docs/workspace/ip-allowlist/) --- # ドメインと参加ポリシー 自社ドメインのユーザーを招待なしで参加させる URL: https://keelson.dev/ja/docs/workspace/domain-join/ Language: ja --- 社員が多い場合は、同じ会社のメールアドレスを持つ人が、個別の招待メールなしで参加できるようにすると便利です。社内に参加リンクを配る方法と、Keelson の「参加」画面から申請してもらう方法があります。 設定と申請の承認は **Owner または Admin** が行います。**Team プラン以上**で利用できます。 ## 参加方法を選ぶ | 参加方法 | メンバーになるタイミング | |---|---| | 社内で共有された参加リンクを開く | 対象のメールアドレスでログインし、「参加」を選んだとき。管理者の承認は不要 | | Keelson の「参加」画面から申請する | Owner / Admin が申請を承認したとき | どちらの方法でも、参加時のロールは **App User** です。Owner / Admin が後からロールを変更できます。 ## 利用できるメールアドレス 参加できる人は、メールアドレスの `@` より後ろの部分(メールドメイン)で決まります。たとえば `name@example.co.jp` のドメインは `example.co.jp` です。 - 設定する Owner / Admin と、ワークスペース作成者のメールドメインが一致している必要があります - Gmail や Outlook.com のように、誰でも取得できるメールサービスのドメインは登録できません - 同じドメインを複数のワークスペースで利用できます(部署ごとのワークスペースなど) 参加リンクを有効にすると、操作した Owner / Admin のメールドメインが自動で登録されます。事前に手動で追加する必要はありません。登録内容は「設定」→「セキュリティ」→「アクセス制御」で確認できます。手動で追加する場合も、自分とワークスペース作成者のメールドメインに一致するものだけを登録できます。 ## 参加リンクを有効にして共有する 1. 「設定」→「セキュリティ」→「チーム参加リンク」を開きます 2. 参加リンクを有効にします 3. URL をコピーして社内のチャットや案内ページで共有します 対象のメールアドレスを持つ人がリンクを開き、ログインして「参加」を選ぶと、その場でメンバーになります。「メンバー」画面で参加を確認できます。 ## 参加申請を承認する 参加リンクを有効にすると、対象のメールドメインでログインした人の「参加」画面にもワークスペースが表示されます。この画面で「参加をリクエスト」を選ぶと、Owner / Admin に申請が届きます。 申請は「設定」→「セキュリティ」の「保留中の参加リクエスト」から承認または却下します。申請しただけではメンバーにならず、承認されるまでアプリにアクセスできません。 ## 参加後にアプリの URL を共有する 参加リンクは、ワークスペースに参加するための URL です。使ってほしいアプリの URL は別途共有します。App User にはコンソールのアプリ一覧が表示されないためです。 参加後に使えるアプリは、[アプリごとの権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/)で決まります。 ## リンクを変更・無効化する - 「リセット」で現在の URL を無効にし、新しい URL を発行できます。共有先を見直したいときに使います - 参加リンクを無効にすると、個別の招待で参加する方式に戻ります。既に参加したメンバーには影響しません ## 参加ポリシー 設定の詳細では、参加方法を「参加ポリシー」と呼びます。参加リンクの有効・無効に連動するため、ポリシーを直接選ぶ操作はありません。 | ポリシー | 動作 | |---|---| | **招待のみ**(既定) | Owner / Admin の個別の招待で参加する | | **自動参加** | 対象のメールドメインの人は参加リンクから承認なしで参加できる。「参加」画面から申請した場合は管理者の承認が必要 | ## 関連ページ - [メンバーとロール](https://keelson.dev/ja/docs/access-control/members-and-permissions/) - [メンバーを招待する](https://keelson.dev/ja/docs/workspace/invite-members/) - [プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/) --- # IP 制御 許可したネットワークからのアクセスだけを受け付ける URL: https://keelson.dev/ja/docs/workspace/ip-allowlist/ Language: ja --- アプリをオフィスや会社の VPN からだけ使えるようにします。利用者のログインとアプリの権限に加えて、接続元のネットワークを確認します。この仕組みを IP 制御と呼びます。 対象は、サーバー側で動く Web アプリと、画面の配信と処理を分けたハイブリッドアプリの API 部分です。**静的サイト、SPA、ハイブリッドアプリの静的ファイル、Media の配信 URL には適用されません。** 詳しくは[適用範囲](#適用範囲)を参照してください。 - **必要な権限 / プラン**: アクセス元の作成、ワークスペースの既定、アプリごとの設定のいずれも Owner / Admin。アプリの `manage` 権限だけでは変更できません。全プラン - **完了条件**: 許可したネットワークからはアプリが開け、それ以外からはアクセスできない旨の画面(接続元の IP アドレスが表示される)になる ## 仕組み IP 制御は「**アクセス元**」という単位で設定します。アクセス元は、許可するネットワークのアドレスを、名前を付けてまとめたものです。たとえば「東京オフィス」という名前で、複数の IP アドレスやアドレスの範囲を登録できます。範囲の指定には、`203.0.113.0/24` のような CIDR という書き方を使います。 1. ワークスペースでアクセス元を作る 2. ワークスペースの**既定**として適用するアクセス元を選ぶ(空なら制限なし) 3. アプリごとに「既定を引き継ぐ」か「このアプリ専用のアクセス元を選ぶ」かを決める 新しいアプリは既定を引き継ぎます。ワークスペースの既定を変更すると、それを引き継ぐアプリにまとめて適用できます。専用のアクセス元を設定したアプリには、その専用設定が使われます。 ## 設定する ### アクセス元を作る(Owner / Admin) コンソールの「設定」→「セキュリティ」→「アクセス元の管理」で「アクセス元を登録」を選びます。 - **名前** — 「福岡オフィス」「VPN」など - **IP / CIDR** — 1 行に 1 つ。IPv4 / IPv6 両方に対応。単一 IP(`203.0.113.10`)も範囲(`203.0.113.0/24`)も書けます。「現在の IP を追加」で自分の送信元を入れられます - **ワークスペースの既定に追加** — チェックすると、作成と同時に既定に含まれます ネットワーク管理者には「このアプリをオフィスと会社の VPN から利用できるようにしたい」と伝え、登録する固定 IP アドレスやアドレス範囲を確認します。 自宅や携帯回線では IP アドレスが変わることがあり、登録後にアクセスできなくなる場合があります。 ### アプリごとの設定(Owner / Admin) アプリ画面の「設定」→「セキュリティ」で選びます。 | モード | 動作 | |---|---| | **ワークスペースの既定を引き継ぐ** | 既定のアクセス元を適用する。既定が空なら制限なし | | **このアプリ専用のアクセス元** | 既定を置き換え、選んだアクセス元(1 つ以上)だけを適用する | 「制限なし」にしたいアプリがある場合は、既定を空にしたうえでそれを引き継ぐか、制限したいアプリだけに専用のアクセス元を設定します。 設定はデプロイなしで反映されます。通常は 2 分以内に反映されます。障害中の変更は復旧後に反映されます。 ## 拒否されたとき 許可されていないネットワークからブラウザで開くと、ログイン後に「このアプリは、許可されたアクセス元からのみ利用できます」という画面と、現在の接続元の IP アドレスが表示されます。 会社の VPN への接続が必要かを確認します。アクセス元への追加が必要な場合は、表示された IP アドレスを Owner / Admin に伝えます。 ## 適用範囲 - 対象は、コンテナで動く Web アプリと、ハイブリッドアプリの API 部分への、ログインユーザーのアクセスです - **静的サイト、SPA、ハイブリッドアプリの静的ファイル、Media の配信 URL(`/__keelson/media/<ファイルID>`)には適用されません**。Media ではログインとアプリの閲覧権限が確認されます([ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/)) - アプリトークンと Webhook には、ワークスペースやアプリの設定ではなく、トークンごとの許可 IP が適用されます([外部システムとの連携](https://keelson.dev/ja/docs/building-apps/external-integrations/)) ## 技術的な詳細 判定は **ログイン → アプリの権限 → IP** の順で行われます。IP 制御は、ログインとアプリの権限確認に追加される制限です。 許可されていないネットワークからのアクセスには HTTP 403 を返します。ブラウザでページを開く場合は案内画面を、ページ内の通信(fetch / XHR)や API 呼び出しには JSON を返します。 ## 関連ページ - [認証とログイン](https://keelson.dev/ja/docs/access-control/auth-and-login/) - [グループとアプリ権限](https://keelson.dev/ja/docs/workspace/groups-and-app-access/) --- # プランと制限 プランごとの上限と、上限に達したときの挙動 URL: https://keelson.dev/ja/docs/workspace/plans-and-limits/ Language: ja --- プランを選ぶときや、アプリの追加・更新ができなくなったときに、利用上限を確認できます。料金は[料金ページ](https://keelson.dev/ja/pricing/)、プラン変更・解約・請求書などの操作は[料金と契約の運用](https://keelson.dev/ja/docs/workspace/billing/)を参照してください。 まず、次の 3 つを確認すると、必要なプランを選びやすくなります。 - **同時に使えるアプリ数** — 同時に利用する Web アプリの数です。保存してあるアプリの総数とは異なります - **アプリを作る・管理する人数(Developers)** — Owner / Admin / Developer の人数枠です。アプリを使うだけの App User は数えません - **ストレージ** — 保存したファイルなどの合計容量です。データベースの容量は別に扱います ## プラン別の上限 | | Starter | Plus | Team | |---|---|---|---| | 同時に使えるアプリ数 | 1 | 2 | 4 | | Developers(Owner / Admin / Developer の席) | 1 | 2 | 3 | | 定期実行 実行回数 / 月 | 1,000 | 5,000 | 15,000 | | 定期実行ジョブの設定数 / アプリ | 3 | 5 | 10 | | 定期実行できる最短の間隔 | 60 分 | 15 分 | 5 分 | | 定期実行 1 回あたりの実行時間上限 | 3 分 | 5 分 | 10 分 | | ビルド回数 / 月 | 100 回 | 300 回 | 1,000 回 | | ビルド時間 / 月 | 500 分 | 1,500 分 | 5,000 分 | | 同時ビルド数 | 1 | 1 | 2 | | 日次バックアップの保存数 | 1 世代 | 3 世代 | 7 世代 | | 指定した時刻に復元できる期間(PITR) | 24 時間 | 7 日 | 14 日 | | ストレージ(ワークスペース合計) | 10 GB | 20 GB | 50 GB | | データベース容量(DB ごと) | 固定上限なし | 固定上限なし | 固定上限なし | | 優先起動 | — | ○ | ○ | | カスタムドメイン | — | — | 最大 10 件 | | アクセスログの閲覧範囲 | 30 日 | 90 日 | 180 日 | | アプリログの閲覧範囲 | 7 日 | 14 日 | 30 日 | Enterprise プランは準備中です。上記を超える要件は[お問い合わせ](https://keelson.dev/ja/contact/)ください。 アプリを実行できる形に準備する処理を「ビルド」、決まった時刻や間隔で動かす処理を「定期実行ジョブ(cron)」と呼びます。バックアップの「1 世代」は、保存されたバックアップ 1 回分です。 ## 全プラン共通 - アプリの利用者数(App User)は無制限 - 有料プランではアプリの保存数は無制限。上限がかかるのは「同時に動かせる数」だけです。トライアル中は保有数と同時に動かせる数にそれぞれ上限があります(下の「トライアル中の制限」を参照) - 認証・アクセス制御・IP 制御 - 日次バックアップ、手動スナップショット(1 アプリ 5 回/日)、PITR、バックアップのダウンロード - Managed SQLite(アプリ / ワークスペース単位で DB を分離) - 14 日間の無料トライアル(1 アカウント 1 回)。Starter / Plus はカード登録なしで開始できます ## トライアル中の制限 - 静的サイトとしてデプロイ済みのアプリを除き、作成できるアプリは 3 個までです。未デプロイのアプリやサーバーを使うアプリはこの上限に数えます。4 個目の作成は拒否されます - 同時に動かせるアプリは、プランを問わず 3 個までです。トライアル中はこの上限がプランの稼働アプリ枠となり、追加アプリのアドオンも加算されません。そのため Team は 4 個から 3 個に減ります - ビルドは 1 日 7 回までです - ビルドはトライアル期間の通算で 30 回までです。この 30 回は通算のため、月が変わってもリセットされません - ビルド時間と同時ビルド数は、ご契約プランの値がそのまま適用されます - 有料プランへ移行すると、保有アプリ数の上限は外れ、稼働アプリ枠はプランの値と追加アプリのアドオンを合わせた数に戻ります ## 上限に達したときの挙動 | 上限 | 挙動 | |---|---| | 同時に使えるアプリ数 | 空き枠が必要なアプリの起動・デプロイができなくなります。稼働中のアプリには影響しません。枠が空いていない状態でスリープ中のアプリにアクセスすると、起動できないことを知らせる案内ページ(HTTP 503)が表示されます。優先起動を設定していないアプリの枠は、最後のアクセスから約 5 分で解放されます | | Developers | 開発者の席を使う招待や、新たに席を使うロール変更ができなくなります。App User の招待や、使用する席数を増やさないロール変更はできます | | 定期実行 実行回数 | 当月の残りの実行はスキップされ、翌月にリセットされます | | 定期実行ジョブの設定数・間隔・実行時間 | `keelson.yaml` がプランに合わない場合、デプロイできません。AI エージェントに、表示された上限に合わせて設定の見直しを依頼します | | ビルド回数 / ビルド時間(月間) | 新しいビルドが拒否されます。どちらの枠も翌月にリセットされます。トライアル中の通算 30 回はリセットされないため、続けるには有料プランへの移行が必要です | | 同時ビルド数 | 上限に達している間、実行中のビルドが終わるまで新しいビルドは拒否されます | | ストレージ | すぐには停止しません。超過時はサポートから連絡します | | データベース容量 | プランごとの固定上限はありません。ただし、基盤側の技術上限は適用されます。また、平常の業務利用を著しく超える負荷や、プラットフォームの安定運用・他のお客様の利用・当社の合理的な運用コストに影響を及ぼす利用を検知した場合、アプリの実行を制限または停止することがあります。緊急時は事前の通知なく制限することがあります | ## アドオン(Team 以上) 有料契約中は、必要な枠や容量を追加できます。追加の操作や請求は[料金と契約の運用](https://keelson.dev/ja/docs/workspace/billing/)を参照してください。トライアル中は追加できません。 | アドオン | 単位 | |---|---| | 追加ストレージ | +50 GB | | 同時に使えるアプリ数の追加 | +1 枠 | | 追加 Developers | +1 席 | ## 用語 ### 同時に使えるアプリ数 Web アプリが起動・利用のために確保する枠の数です。通常のアプリは、最後のアクセスから約 5 分で枠が自動的に解放されます。アクセスが続いている間は枠を使います。 - スリープ中・サスペンド中のアプリは枠を消費しません - 定期実行ジョブだけのアプリは枠を消費しません(Web アプリとは別に実行されます) - 静的サイトは枠を消費せず、作成できる本数にも上限はありません - **優先起動**を設定したアプリは、アクセスがなくても枠を常に予約します。Plus 以上で、利用できるアプリ枠の合計より 1 本少ない数まで設定できます。トライアル中は上記のトライアル用の枠数が基準になります 起動と停止の仕組みは[アプリが動くタイミング](https://keelson.dev/ja/docs/building-apps/how-apps-run/)を参照してください。 ### Developers アプリを作る・管理する人の人数枠を「Developers 席」と呼びます。Owner / Admin / Developer のメンバーが 1 人につき 1 席を使います。App User は数えません。 Owner / Admin / Developer の招待は、相手が受け入れる前でも、有効期限内は 1 席を予約し、使用量に含まれます。不要になった招待は取り消すと予約が外れます。
操作によって異なる席数の数え方 Owner / Admin / Developer として新しく招待するときは、これらのロールの参加済みメンバーと、有効期限内の未受諾の招待を合計して上限を判定します。招待の受諾時や、新たに開発者の席を使うロール変更では、これらのロールの参加済みメンバーだけを数えます。既に席を使っているメンバーのロール変更など、席数が増えない変更はこの上限で制限されません。
### ストレージ デプロイ用に保存したアプリのファイル(アーティファクト)、Files / Media SDK のファイル、スナップショットの合計容量です。ワークスペース全体で集計し、ログは含みません。Managed SQLite の容量はこの集計枠とは別に管理され、プランごとの固定上限はありません。 ## HTTP の時間上限 画面の表示やデータの保存など、アプリに送る 1 回のリクエストには時間の上限があります。長い処理がある場合は、AI エージェントに上限内で完了する処理方法を相談できます。 | 項目 | 上限 | |---|---| | 応答を開始するまで(最初のレスポンスヘッダ) | 120 秒。超えるとタイムアウト(HTTP 504) | | 1 リクエストの合計(結果を少しずつ返すストリーミングを含む) | 300 秒 | | ストリーミングで次のデータを返すまでの間隔(チャンク間隔) | 120 秒 | タイムアウトが表示されても、アプリ側では保存などの処理が完了している場合があります。AI エージェントには「同じ操作を繰り返しても、申請や注文が二重に登録されないようにして」と依頼してください。 技術的には、HTTP 504 が返ってもアプリ側の処理が取り消されたとは限りません。Keelson は `POST` リクエストを自動再送しませんが、利用者やクライアントが再送する可能性があります。そのため、同じリクエストを繰り返しても結果が重複しない実装が必要です。 定期実行ジョブの時間上限は上のプラン別一覧、ビルドの時間上限は [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/#依存関係のインストール)を参照してください。 ## 関連ページ - [定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/) - [データベース(Managed SQLite)](https://keelson.dev/ja/docs/building-apps/persistent-storage/) - [メンバーを招待する](https://keelson.dev/ja/docs/workspace/invite-members/) --- # 料金と契約の運用 プラン変更、トライアル、解約、請求書、ワークスペースの削除、データの持ち出し URL: https://keelson.dev/ja/docs/workspace/billing/ Language: ja --- プランを変更したいとき、支払い方法や請求書を確認したいとき、Keelson の利用を終了したいときの手順を案内します。各プランの数値上限は[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)、料金は[料金ページ](https://keelson.dev/ja/pricing/)を参照してください。 - **必要な権限**: Owner または Admin。ワークスペースの削除は Owner だけ - **場所**: コンソールの「設定」→「課金と使用量」。ワークスペースの削除は「設定」→「危険な操作」 ## 料金はいつから発生するか - 各アカウントは 1 回だけ 14 日間の無料トライアルを使えます。Starter / Plus はカード登録なしで開始でき、**終了までにカードを登録しなければ課金されずに自動終了**します。Team はトライアル開始時にカード登録が要ります(期間中に解約すれば課金なし) - カード登録済みの場合、トライアル終了日が初回請求日になり、以降は契約日ベースで毎月請求されます - トライアルを使い切ったアカウントが 2 つ目のワークスペースを作る場合は、決済完了と同時に課金が始まります - 通貨は請求先の国で決まります(日本は JPY 税込、それ以外は USD 税抜)。初回契約で固定され、後から変えるにはサポートへの連絡が要ります - 請求書払い・銀行振込は未対応です 利用者(App User)の人数は料金に影響しません。 ## トライアル中の制限と終了時の挙動 トライアル中は、保有アプリ数・同時に動かせるアプリ数・ビルド回数に、プラン共通の上限があります。具体的な数値と数え方は、[トライアル中の制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/#トライアル中の制限)で確認できます。 | 終了時の状態 | 起きること | |---|---| | カード登録済み | そのまま有料プランに移行し、初回請求が発生する。保有アプリ数の上限は外れ、稼働枠はプランの値に戻る | | カード未登録(Starter / Plus) | 課金されずに自動終了する。以後、新しいデプロイ・アプリの起動・定期実行はブロックされる。アプリとデータはすぐには削除されない([解約後のアプリとデータ](#解約後のアプリとデータ)) | トライアル中のプラン変更は、アップグレード・ダウングレードとも直ちに適用され、料金は発生しません。 ## プランを変更する 「課金と使用量」→「プラン変更」から選びます。確定前に金額が表示されます。 | 変更 | 適用 | 請求 | |---|---|---| | アップグレード | 直ちに | 現在のプランの未使用期間分を差し引き、新しいプランの残り期間分を変更時に請求する。次回の請求日からは新プランの満額 | | ダウングレード | 現在の請求期間の終わりに | 日割り精算はしない。それまでは現在のプランのまま使える | ダウングレードは予約として表示され、「予約を取り消す」で切り替え前なら取り消せます。 現在の使用量が変更先の上限を超えている場合は警告が出ます。超えたまま切り替えると、次のようになります。 - **同時に使えるアプリ数**: スリープ中のアプリは、使用量が上限内に減るまで起動できない - **Developers 席**: 上限内に収まるまで、Developer 以上のロールでの招待や、App User から Developer 以上への変更ができない - **定期実行の回数**: 当月の残りはスキップされる - **ストレージ**: 超過してもすぐには止まらない「ソフト上限」です。デプロイ時に警告が出て、サポートから連絡します。継続的に大きく超過している場合は制限の対象になります - **カスタムドメイン**(Team のみ): 登録済みのものは残るが、追加・再登録ができない ## アドオンを増減する(有料契約中の Team 以上) 「課金と使用量」→「アドオン」で、追加アプリ枠(+1)、追加 Developers 席(+1)、追加ストレージ(+50 GB)を数量で指定します。**トライアル中は変更できません**(トライアル終了後に追加できます)。増やした分は、残りの契約期間に応じた金額が登録済みの支払い方法へすぐに請求されます。減らした場合の差額は次回以降の請求に充当されます。 ## 支払い方法と請求書 「課金と使用量」の「請求書」に最近の請求書が並び、各行から Stripe の請求書ページと PDF を開けます。 支払い方法の変更、請求先情報の編集、過去の請求書の一覧は、「課金を管理」ボタンから開く決済サービス Stripe の契約管理画面(カスタマーポータル、別タブ)で行います。ポータルで解約もできますが、Keelson のコンソールから解約する方が、終了日と影響を確認したうえで進められます。 決済に失敗した場合(支払い遅延)は、Stripe が再試行する間、サービスは通常どおり使えます。再試行が終わっても支払われないと契約が停止し、新しいデプロイ・アプリの起動・定期実行がブロックされます。「支払い方法を更新」から更新してください。 ## データの持ち出し 利用を終了する場合は、**契約が終了するまでに、必要なデータを取り出します。** ワークスペースやアプリを削除する場合は、削除操作の前に行います。解約の申し込み後も契約終了日までは利用できるため、その間に準備できます。 | データ | 取り出し方 | |---|---| | Managed SQLite のデータ | コンソールのアプリ画面「復元ポイント」から、復元可能な期間内の時点を選んでダウンロード。データを書き出したファイル(SQLite の dump)を取得できます。契約終了後の猶予期間中もダウンロードできます | | Files SDK のファイル | アプリにファイル一覧とダウンロード処理を用意し、アプリが動いているうちに取り出します | | Media SDK のファイル | アプリに保存したファイル ID からリンクを用意し、そのアプリを閲覧できるメンバーがログインして取り出します | | ソースコード | Git。または「デプロイ」タブの各デプロイからダウンロード | | 環境変数とシークレット | シークレットの値はコンソールに表示されません。必要なら元の管理場所から控えます | | アクセスログ・アプリログ | 「ログ」タブからエクスポート(アプリログは最大 5,000 行) | Files / Media には、コンソールや CLI からファイルを一覧表示・ダウンロードする機能がありません。AI エージェントには「保存したファイルを一覧から取り出せる画面を作って。Files はダウンロード処理を、Media は保存済みの ID からリンクを用意して。アプリの閲覧権限がある人だけが使えるようにして」と依頼できます。取り出したファイルが開けることも確認します。使い分けは[ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/)で説明しています。 契約終了後はアプリを起動できなくなるため、**Files / Media の取り出しは契約終了までに済ませます。** ## 解約する 「課金と使用量」→「プランをキャンセル」から、終了日と影響を確認し、「キャンセルを確定」を選びます。 - **現在の請求期間の末日まではプランが有効なまま**です。解約の申し込み後も終了日まで利用でき、残り期間分の返金もありません - 末日までは「再開」でいつでも取り消せます - 末日を過ぎると、新しいデプロイ・アプリの起動・定期実行がブロックされます。アプリやデータはすぐには削除されず、削除の予告と猶予期間があります ## 解約後のアプリとデータ 契約が終了した(解約が末日を迎えた、未払いで停止した、トライアルがカード未登録で終了した)ワークスペースでは、アプリは起動できなくなりますが、すぐには消えません。 1. 対象のアプリが見つかった時点で、Owner / Admin にコンソールとメールで**削除の予告**が届きます。予告には削除予定日が書かれています 2. 猶予は**予告から 30 日**です。猶予中も利用制限は続きますが、コンソールにログインして DB のバックアップをダウンロードできます 3. 猶予中に再契約(プランを選び直す)すると、予告は取り消され、アプリはそのまま残ります。アプリを残して使い続けたい場合は、この期間内に再契約します 4. 猶予後、アプリは自動で削除されます。削除後の扱いは利用者が承認した削除と同じで、DB バックアップ・Files・秘密情報を含まない設定の記録が、通常の利用から切り離された状態で 7 日間保管されます。復元は保証されません DB のバックアップは猶予期間中も取り出せます。Files / Media は契約終了までに取り出す必要があります([データの持ち出し](#データの持ち出し))。 削除予定日は予告で確認できます。契約終了後のデータの取り扱いと、終了までのエクスポートについては、[利用規約の第20条](https://keelson.dev/ja/terms/)もご確認ください。 ## ワークスペースを削除する 「設定」→「危険な操作」→「このワークスペースを削除」。Owner だけが実行でき、ワークスペース名を入力して確認します。 - ワークスペースとすべてのアプリが削除され、メンバーはアクセスできなくなります。コンソールから削除を取り消すことはできません - 各アプリの DB バックアップ・Files・秘密情報を含まない設定の記録は、通常の利用から切り離された状態で 7 日間保管されますが、復元は保証されません - 削除するとログアウトします - 有効な契約がある場合、削除時に契約のキャンセル処理も行われるため、先に解約する必要はありません。ただし、キャンセル処理に失敗する場合があるため、削除後に請求が続いていないことを Stripe のポータル(削除前に「課金を管理」から開けます)または請求書メールで確認してください Keelson のアカウント自体は、コンソール右上のアカウントメニュー →「Account settings」→「Security」の **Delete account** から自分で削除できます。削除されるのは Keelson のアカウントで、ログインに使っていた Google / Microsoft のアカウントは削除されません。所属していたワークスペースのアプリやデータも残ります。 ## 関連ページ - [プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/) — 数値上限と、上限に達したときの挙動 - [更新と復元](https://keelson.dev/ja/docs/deploy/update-and-restore/) — アプリの削除と、削除前に取り出すもの - [料金ページ](https://keelson.dev/ja/pricing/) # リファレンス --- # Keelson Deploy Spec Keelson にアプリをデプロイする際の対応ランタイム、制約、成立条件の正本仕様書 URL: https://keelson.dev/ja/docs/reference/deploy-spec/ Language: ja --- **Spec version:** 2026-09-02 / **Raw text (AI向け):** [`/ja/docs/reference/deploy-spec.txt`](https://keelson.dev/ja/docs/reference/deploy-spec.txt) この文書は、Keelson にアプリをデプロイする際の対応ランタイム・制約・成立条件を定義する正本です。デプロイの可否判断は、この文書に従ってください。 クイックスタートや操作手順は [デプロイする](https://keelson.dev/ja/docs/deploy/deploy/) を参照してください。 --- ## デプロイ成功の定義 Keelson におけるデプロイ成功とは、ビルドが完了することではありません。次の条件をすべて満たした場合にのみ、デプロイは成功とみなされます。 1. アプリのビルドが完了している 2. アプリのプロセスが起動している 3. ヘルスチェックに通過している 4. アプリ URL(`https://<ワークスペース slug>--<アプリ slug>.keelson.run`)が発行されている 5. アプリ URL にアクセスできる状態である ビルドが成功しても、起動に失敗した場合やヘルスチェックに通らない場合は、デプロイ成功ではありません。 --- ## 必須ファイル すべてのデプロイには `keelson.yaml` が必要です。プロジェクトのルートディレクトリに配置します。 最小構成: ```yaml slug: my-app runtime: python-slim command: "python app.py" db: mode: none ``` `db` と `db.mode`(`libsql` または `none`)は必須です。 Flask などのフレームワークを使うアプリには本番用サーバーが必要です。[本番環境向けの設定](#本番環境向けの設定)を参照してください。 各フィールドの詳細は [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/) を参照してください。 --- ## 配置リージョン アプリは作成時に 1 つの論理リージョンへ配置されます。リージョンの論理キーは `jp-tokyo`(日本)と `us-oregon`(米国西海岸)です。クラウド事業者のリージョン名ではなく、この表示名と論理キーを使います。 新規アプリでは `keelson deploy --new --region `、または `keelson.yaml` のトップレベル `region` で配置先を指定できます。優先順位は CLI の指定、`keelson.yaml`、ワークスペースの既定リージョンの順です。rollout 中は一覧にあるリージョンでも新規作成に未開放の場合があり、未開放のリージョンを明示すると拒否されます。 リージョンはアプリ作成後に変更できません。既存アプリへ別のリージョンを指定しても移動は行われず、デプロイは拒否されます。別リージョンを使う場合は、新しいアプリとして作り直してください。 --- ## 対応ランタイム 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 の違い - **slim** — 言語ランタイムと標準ライブラリのみ。ビルドが速く、イメージサイズが小さい - **media** — slim に加え、画像処理(Pillow、sharp 等)や動画処理に必要なシステムライブラリがプリインストールされている ### 対応フレームワーク 特定のフレームワークに依存しません。`command` で起動でき、HTTP サーバーとしてリクエストを受け付けるアプリであれば動作します。 例: FastAPI、Flask、Express、Next.js、Hono、Gin など。 --- ## 非対応ランタイム 以下の言語・ランタイムはサポート対象外です。 - Ruby - Java / Kotlin / Scala - PHP - Rust - .NET / C# - Elixir / Erlang - Swift 非対応ランタイムのアプリは、修正や変換を行っても Keelson へデプロイできません。 --- ## ビルド環境と実行環境の制約 Keelson は固定されたビルド環境・実行環境を提供します。アプリはその環境上でビルドおよび起動できる必要があります。 ### OS・アーキテクチャ - **OS:** Linux - **CPU:** x86_64 (amd64) ### root 権限 アプリは非 root ユーザーとして実行されます。`sudo`、`apt-get install`、システムレベルの変更は実行できません。 ### Dockerfile 使用できません。Keelson はランタイムを選択し、`command` で起動する方式です。Dockerfile の代わりに `keelson.yaml` でランタイムと起動コマンドを指定します。 ### ファイルシステム | パス | 書き込み | 永続化 | 用途 | |---|---|---|---| | `/data` | 不可(Keelson も作らず、アプリからも作れない) | 不可 | アプリは UID 1000 で実行され、root 所有の `/` 直下にはディレクトリを作れません | | アプリディレクトリ | 不可(書き込み先として使えません) | 不可 | ソースコード、依存関係 | | `/tmp` | 可(一時的) | 不可 | 一時ファイル | | その他 | 不可 | — | — | - ローカルファイルへの書き込みはすべてエフェメラルで、再起動・scale-to-zero で失われます - 永続データの置き場所は 3 つだけです: Managed SQLite(`db.mode: libsql`)、Files SDK(アプリ内部の非公開ファイル)、Media SDK(利用者に配信する画像・添付)。いずれもパスではありません - `/data` のファイル SQLite は永続化されません。ファイル SQLite クライアントの使用はデプロイ時に検出され、`db.local_sqlite` で一時用途と宣言しない限り拒否されます ### ポート - Web アプリは環境変数 `PORT` で指定したポートで HTTP リクエストを待ち受けてください - `0.0.0.0` で listen する必要があります。`127.0.0.1` や `localhost` ではリクエストが届きません - HTTPS 終端は Keelson が行います。アプリは HTTP で listen してください ### システムパッケージ Keelson は任意の OS パッケージ追加を前提とした環境ではありません。 - `-slim` ランタイムには最小限のシステムライブラリのみ含まれます - `-media` ランタイムには画像・動画処理に必要な一般的なライブラリが含まれます - それ以外のシステムライブラリが必要な場合、アプリは動作しない可能性があります - `apt-get` 等によるパッケージ追加はできません(非 root のため) ### プロセスモデル - `command` で起動した単一プロセスが基本です - systemd やデーモン管理は使えません - バックグラウンド処理が必要な場合は `crons` を使ってください(`workers` は廃止済みで、宣言するとデプロイが拒否されます) --- ## 依存関係に関する制約 言語ランタイムが対応していても、依存ライブラリやシステム要件によってはデプロイできない場合があります。 ### 言語パッケージマネージャで追加できる依存 以下のパッケージマネージャで管理される純粋な言語パッケージは問題なくインストールできます。 - **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`。ビルド時にシークレットは渡らない。上限 900 秒。 ```yaml # Python command: "python app.py" # Node.js command: "npm start" # Go (Keelson 側で deploy 時に `./app` がビルドされます) command: "./app" ``` ### ネイティブ依存が必要なパッケージ 一部のパッケージは、C ライブラリやシステムレベルの依存を必要とします。 - **`-media` ランタイムで動作するもの:** Pillow、opencv-python、sharp、ffmpeg 関連など、一般的なメディア処理ライブラリ - **動作しない可能性があるもの:** ランタイムに含まれないシステムライブラリに依存するパッケージ ### サポート対象外になる典型パターン | パターン | 理由 | |---|---| | `apt-get install` が必要 | 非 root でパッケージ追加不可 | | 特殊な C ライブラリに依存 | ランタイムに含まれていない可能性 | | GPU を前提とした推論ライブラリ | GPU インスタンス未提供 | | データベースサーバー(PostgreSQL、MySQL、Redis) | 外部サービスとして接続は可能だが、Keelson 上での起動は不可 | | systemd やバックグラウンドデーモン前提 | プロセスモデルが異なる | --- ## デプロイモード デプロイモードは選択するものではなく、`command` と `assets` という持ち物から自動的に決まる導出値です。CLI / API の出力は `deploy_mode` の生ラベルを返すため、対応表で読み替えてください。 | 呼称 | `deploy_mode` 生ラベル | `command` | `assets` | 説明 | |---|---|---|---|---| | Web アプリ | `container` | あり | なし | 通常のアプリデプロイ | | 静的サイト | `edge-static` | なし | あり(`fallback` なし) | 静的ファイルのみ | | SPA | `edge-spa` | なし | あり(`fallback` あり) | SPA(フォールバック付き) | | ハイブリッド | `hybrid` | あり | あり(`fallback` 必須) | 静的ファイル + バックエンド API | --- ## 予約 URL パス Keelson がアプリのホスト上で予約する URL 名前空間は **`/__keelson/*`** の 1 つだけです。それ以外のパスはすべてアプリのものです。`/assets`、`/files`、`/static`、`/uploads`、`/api` のような一般的なパスをプラットフォームが奪うことはありません。 - **`/__keelson/*` はプラットフォーム内部用**です。プラットフォームが配信するアセット・ファイルダウンロード・内部エンドポイントに使われます。この配下にアプリのルートを定義しないでください。 - **ビルド出力の配信ルート直下に `__keelson` ディレクトリを出力しないでください。** 予約パスを含むビルドはビルド時にエラーコード **`reserved_path_conflict`** で拒否されます。ディレクトリ名を変更して再デプロイしてください。 - **それ以外は予約されていません。** `/assets/*`(Vite の既定出力先)などのフレームワーク既定パスは、設定変更なしでそのまま配信されます。 - 関連ルール: `auth.endpoints` のパスは `/__keelson` で始められません(`/api/external/` または `/api/webhooks/` で始める必要があります)。また `slug` に予約語は使えません。 ### フレームワーク静的パス衝突マトリクス(参考) 主要フレームワークが既定で出力する静的パスの一覧です。**いずれも `/__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/*` | しない見込み | 要検証 | --- ## 環境変数とシークレット アプリの起動に必要な API キー、トークン、接続情報は、コードに直接埋め込まず、環境変数またはシークレットとして設定してください。 - `keelson.yaml` の `env` — バージョン管理に含めてよい値 - コンソールのシークレット — API キーやトークンなど、コードに含めたくない値 必要な値が未設定の場合、アプリは正常に起動できないことがあります。 詳細は [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) を参照してください。 ### 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` には使えません。 --- ## 本番環境向けの設定 Keelson のアプリは Cloud Run 上で動作し、通常運用中にも起動と停止が発生します。停止時にはプロセスへ SIGTERM が送られ、10 秒後に SIGKILL が送られます。本番用サーバーを使い、この時間内にドレイン処理を完了してください。 ### フレームワーク別の本番サーバ **Flask:** `app.run()` は Werkzeug 開発サーバーを起動します。ローカル用の `__main__` エントリーポイントの中に残すことはできますが、`debug=False` でもデプロイ先のサーバーにしてはいけません。gunicorn を `requirements.txt` に追加し、次のコマンドを使います。 ```yaml 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 を起動します。 ```yaml 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 のままにします。 ```yaml command: "uvicorn main:app --host 0.0.0.0 --port $PORT" ``` `--reload` は使わないでください。ファイル監視がメモリを消費し、アプリが二重起動することがあります。`main:app` はプロジェクトのモジュール名とアプリケーションオブジェクト名に置き換えてください。 **Next.js:** 開発サーバーではなく、ビルド済みのアプリを起動します。 ```yaml command: "npm run start" ``` package script は次のように設定します。 ```json "start": "next start -p $PORT" ``` `package.json` に `"start": "next dev"` がある場合、回避策を加えるのではなく、その script を修正してください。`next dev` は本番用サーバーではありません。 **Node.js:** Keelson は `NODE_ENV` を自動設定しません。`keelson.yaml` で本番モードを宣言してください。未設定の場合、Express などのフレームワークがスタックトレースを返すことがあります。 ```yaml env: NODE_ENV: "production" ``` **Go:** ビルド済みバイナリを `command: "./app"` で起動します。`ListenAndServe` を停止処理なしで放置せず、`signal.NotifyContext` と `server.Shutdown` を使って新規リクエストの受付を止め、処理中のリクエストを 10 秒の猶予内に完了させてください。 ### デバッグ・開発モードの既定 既定値は本番で安全な向きにします。Python の `DEBUG` は false を既定にします。 ```python DEBUG = os.environ.get("DEBUG", "false").lower() == "true" ``` true を既定にしてはいけません。 ```python DEBUG = os.environ.get("DEBUG", "true").lower() == "true" ``` デバッグ画面は、データベースの認証トークンを含む環境変数を表示することがあります。 ### 本番かどうかの判別 Keelson が値 `keelson` で設定する `KEELSON_MODE` を使って、プラットフォーム上での実行を判別します。 ```python ON_KEELSON = os.environ.get("KEELSON_MODE") == "keelson" ``` 本番設定の不足を即時エラーにする検査は、`ON_KEELSON` が true の場合だけ適用してください。`DEBUG` をプラットフォーム判別に使うとローカルで起動できなくなるため、代用しないでください。 --- ## タイムアウト | 対象 | 制限 | |---|---| | HTTP リクエスト | 120 秒以内にレスポンスを開始(超過で 504)。ストリーミングは開始後、無通信 120 秒・合計 300 秒まで | | 定期実行ジョブ(cron) | 1〜600 秒(既定 300 秒。プラン上限がそれより低ければ切り詰め) | | ビルド | 900 秒 | --- ## 外部通信 - アプリから外部 API やサービスへの通信はデフォルトで可能です --- ## よくある失敗パターン | 症状 | 原因 | 対処 | |---|---|---| | ビルド成功、起動後すぐ落ちる | `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 プレフィックス)がある | ディレクトリ名を変更(予約は `/__keelson/*` のみ、それ以外はアプリのもの) | | 定期ジョブが一度も発火しない(エラーも出ない) | スケジュールがアプリのプロセス内にある(in-process スケジューラ)。予定時刻にはアプリがゼロにスケールしている | `crons` エントリとして宣言する | | UI は成功と表示されたのにメール・通知が届かない | レスポンスを返した後に回した処理が走っていない | レスポンスを返す前に済ませる。または DB のキュー表に書いて `crons` エントリでドレインし、最大 1 間隔ぶん遅れることをユーザーに伝える | ### 失敗時の確認手順 1. **ビルドログを確認** — 依存関係のインストールが成功しているか 2. **実行ログを確認** — 起動時エラーやランタイムエラーがないか 3. **`keelson.yaml` を確認** — `runtime`、`command`、`env` の設定が正しいか --- ## AI エージェントの期待動作 AI エージェントは、Keelson へのデプロイ時に以下の順序で判断してください。 ### 判断フロー 1. **ランタイム確認** — アプリの言語がこの仕様の対応ランタイムに含まれるか確認する 2. **依存関係確認** — ネイティブ依存やシステムライブラリの要件が制約内か確認する 3. **keelson.yaml 確認** — ファイルの有無と設定内容の妥当性を確認する。なければ作成する 4. **環境変数確認** — 必要な環境変数やシークレットが不足していないか確認する 5. **デプロイ実行** — CLI または Skill を使ってデプロイを実行する 6. **完了確認** — ビルド完了だけでなく、起動・ヘルスチェック・URL アクセスまで確認する 7. **失敗時対応** — ログを確認し、修正可能な範囲で対処する。制約違反がある場合は理由を明示して停止する ### 必須ルール - 非対応ランタイムの場合は、デプロイを試行しない。理由を明示して停止する - 必須設定が不足している場合は、必要事項を提示する - ビルド成功のみで完了扱いにしない - 起動失敗時は必ずログを参照する ### 仕様参照の優先順位 1. Web 上の最新 Keelson Deploy Spec(この文書) 2. Web 上の最新 CLI バージョン情報 3. Skill 同梱版の仕様 4. 一般知識・推測 Web 上の正本と Skill 同梱の情報が矛盾する場合は、Web 上の正本を優先してください。 --- ## 関連資料 - [デプロイする](https://keelson.dev/ja/docs/deploy/deploy/) — デプロイの手順と流れ - [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) — API キーや設定値の管理方法 - [アプリ URL](https://keelson.dev/ja/docs/deploy/public-url/) — デプロイ後に発行される URL の仕様 - [keelson.yaml リファレンス](https://keelson.dev/ja/docs/reference/keelson-yaml-reference/) — 設定ファイルの全フィールド定義 - [フレームワーク別の注意点](https://keelson.dev/ja/docs/building-apps/frameworks/) — 本番向けの起動方法 --- # keelson.yaml keelson.yaml の全フィールドの型・既定値・制約 URL: https://keelson.dev/ja/docs/reference/keelson-yaml-reference/ Language: ja --- ## 概要 `keelson.yaml` はプロジェクトルートに置くデプロイ設定ファイルです。ランタイム、起動コマンド、環境変数、データベース、定期実行ジョブ、静的アセットなどを定義します。 デプロイ時に Keelson はこのファイルを読み、ビルドと実行環境を決めます。入門は [keelson.yaml の設定](https://keelson.dev/ja/docs/building-apps/keelson-yaml/)を参照してください。 ### 最小構成 ```yaml slug: my-app runtime: python-slim command: "python app.py" db: mode: none ``` --- ## トップレベルフィールド | フィールド | 型 | 必須 | 既定値 | 説明 | |---|---|---|---|---| | `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` を書くと省略と同じにはならず拒否されます。省略したいときはキーごと書かないでください。 ### 文字列の書き方 `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](#env) を参照)。 --- ## slug アプリの識別子です。アプリ作成時の公開 URL(`https://<ワークスペース slug>--.keelson.run`)の一部になります。 ```yaml slug: my-app ``` ルール: - 小文字英数字とハイフン(`a-z`、`0-9`、`-`)のみ - 1〜63 文字 - 先頭と末尾は英数字 - ハイフンの連続(`--`)は不可 - 予約語: `admin` `api` `assets` `auth` `console` `health` `static` `www` `public_slug` は廃止された互換フィールドで、無視されます。 --- ## description アプリが誰向けで何をするかを示す 1〜2 文です。 ```yaml description: "営業チーム向けの日報・週報作成アプリ。週次サマリーを自動集計します" ``` 前後の空白を除いて 300 文字(Unicode コードポイント)以内。超えるとデプロイが失敗します。アプリ台帳の説明欄に表示され、**説明がまだ空のときだけ**適用されます。コンソールで編集した説明がデプロイで上書きされることはありません。 --- ## type アプリ種別です。省略可能です。 ```yaml type: web ``` 指定できる値は `web` だけです。`type: web` を指定すると、`assets` だけで `command` なしのデプロイができます。 制約: - `type: web` と `crons` は併用できません - Web アプリと cron を両方持つアプリでは `type` を省略します --- ## runtime 実行環境です。静的サイトだけのデプロイでも必須ですが、静的サイトではビルドに使われません。静的サイトは手元や CI でビルド済みの `assets.dir` をそのまま配信します。 ### 対応ランタイム | ランタイム | 言語 | 用途 | |---|---|---| | `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` に切り替えます。 ### 依存関係のインストール コンテナ型とハイブリッド型では、依存パッケージはビルド時に 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 アプリ起動時に実行するコマンドです。文字列(シェル経由)またはリスト(直接実行)で指定します。 ```yaml # 文字列形式(/bin/sh -c で実行) command: "python app.py" # リスト形式(exec で直接実行) command: - python - app.py ``` ルール: - `command`、`crons`、静的 `assets` のいずれかが必要です - cron だけのアプリに `command` は不要です - `type: web` で `assets` がある静的サイトに `command` は不要です - 空文字列・空リストは「起動コマンドなし」として扱われます。通常の Web アプリでは指定が必要です。`crons[].command` は空にできません - 依存関係のインストールは含めません([依存関係のインストール](#依存関係のインストール)を参照) --- ## env 秘密でない環境変数をキーと値で定義します。値はすべて文字列です。 `PORT` は Keelson が実行時に設定します。`env` に書いても無視されます。 **値は必ず引用符で囲むか、ブロックスカラー(`|` / `>`)で書いてください。** 引用符のない値は `env_value_not_string` で拒否され、デプロイは開始されません。数値・真偽値も同様です。 ```yaml 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` ハイフンを含む名前や予約語は、キーを引用符で囲みます。 ```yaml env: NODE_ENV: "production" "MY-VAR": "x" "yes": "x" ``` `KEELSON_` で始まるキー(大文字小文字を区別しない)はプラットフォーム予約で、`env` には設定できません。`env` の重複宣言、`env` 内のキー重複、YAML の merge key(`<<`)も拒否されます。 秘密の値は `env` ではなく [`secrets`](#secrets) で宣言し、値はコンソールまたは CLI で設定します。`env` と同じ名前のシークレットが設定されている場合はシークレットの値が優先され、`env` の変更は反映されません。 --- ## db データベースの扱いを選びます。**`db` と `db.mode` は必須です。** ```yaml 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` の宣言がなければ拒否されます。 ### マイグレーション `db.migrate` は、新しいイメージでトラフィックを切り替える前に 1 回だけ実行されるコマンドです。 ```yaml db: mode: libsql migrate: "python migrate.py" ``` - `mode: libsql` のときのみ有効。文字列で指定します - コンテナ型・ハイブリッド型でのみ実行されます。静的サイトにはコンテナがないため、宣言しても実行されません - 候補リビジョンがヘルスチェックを通った後、トラフィック切り替えの前に、デプロイ対象のイメージ上で実行されます。アプリの起動コードは移行前のスキーマで動く必要があります - 終了コードが 0 以外ならデプロイは `deploy.runtime.migration_failed` で失敗し、旧リビジョンが維持されます - 毎回のデプロイで実行されるため、冪等に書きます(`CREATE TABLE IF NOT EXISTS`、`ON CONFLICT DO NOTHING`) ### 一時的なローカル SQLite 再生成できるキャッシュ用途のファイルだけを `db.local_sqlite` で宣言します。宣言してもファイルは永続化されません。 ```yaml db: mode: none local_sqlite: policy: ephemeral paths: - /tmp/cache.db reason: "外部 API から再構築できる派生キャッシュ" ``` | フィールド | 型 | 必須 | 制約 | |---|---|---|---| | `policy` | string | はい | `ephemeral` のみ | | `paths` | list | はい | 空でないこと。各パスは `/tmp/` 配下か `:memory:` | | `reason` | string | はい | 消えても問題ない理由 | 廃止された `databases` ブロックは常に拒否されます。 --- ## crons 定期実行ジョブを定義します。各ジョブは Web サービスとは別のインスタンスで実行されます。 ```yaml 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 上限のプラン別の値は[プランと制限](https://keelson.dev/ja/docs/workspace/plans-and-limits/)を参照してください。 ### cron 式の例 | 式 | 意味 | |---|---| | `0 * * * *` | 毎時 0 分 | | `*/15 * * * *` | 15 分ごと | | `0 3 * * *` | 毎日 3:00 | | `0 9 * * 1-5` | 平日 9:00 | | `0 0 1 * *` | 毎月 1 日 0:00 | `* * * * *`(毎分)は全プランの最小間隔より短いため拒否されます。実行の挙動と設計は[定期実行ジョブ](https://keelson.dev/ja/docs/building-apps/scheduled-jobs/)を参照してください。 --- ## workers(廃止) `workers`(バックグラウンドワーカー / 定期ドレイン)は廃止されました。トップレベルに `workers` があると、値が空リストや `null` でも `workers_not_supported` で拒否されます。 同じ処理は `crons` で表現します。ドレイン型の処理は、短い間隔のスケジュールを 1 本立て、1 回の実行で未処理分を片付けて終了する形にします。 ```yaml # NG — デプロイが拒否される workers: - name: drain command: "python worker.py" every: 10m # OK — crons で書く crons: - name: drain schedule: "*/5 * * * *" command: "python drain.py" timeout: 120 ``` --- ## assets 静的サイト、SPA、静的ファイル + バックエンド API(hybrid)の配信設定です。 ```yaml 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` が必須 ### アーカイブに含まれるもの 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 系でない名前も対象で、警告されたファイルは除外されず同梱されます。 ### ブラウザキャッシュ ファイル名にコンテンツハッシュが入った JavaScript / CSS(例: `index-B7hK2mQ1.js`)は 1 年間キャッシュされます。Keelson は、ASCII 英数字と `_` からなり英字と数字の両方を含む 8〜64 文字の末尾セグメントをハッシュと認識します。HTML、`style.css` や `app.js` のようなハッシュなしのファイル、画像などは、アクセスのたびに ETag で更新を確認します。 静的サイト(`edge-static` / `edge-spa`)の再デプロイは、新しいファイルがエッジに反映されるまで 25〜30 秒かかります。 --- ## health デプロイ時のヘルスチェックに使うパスです。`/` が重い、DB に依存する、などの場合に軽量なエンドポイントを指定します。 ```yaml health: path: /health ``` - 省略時は `/` を確認します - `/` で始まり、`..` を含まず、`/__keelson` で始まらない 2048 文字以内のパス - HTTP 2xx / 3xx / 404 で合格、それ以外の 4xx と 5xx で不合格。404 が通るため、合格は「起動した」ことの確認であり、そのパスが実装されていることの証明ではありません - 候補リビジョンの内部 URL へ直接送られ、公開ホストや認証は経由しません。公開パスの検証は [`verify`](#verify) で行います --- ## secrets アプリが必要とするシークレットと、必須の組み合わせを宣言します。値はここには書かず、コンソール、CLI、またはデプロイ時の env ファイルで設定します。 ```yaml 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 ` で、アプリ作成・シークレット設定・初回デプロイを 1 回で行えます。既存アプリのシークレット変更は次のデプロイで反映されます。 --- ## auth Webhook の受信など、対話ログインを通さずに外部システムから呼ばれるエンドポイントを宣言します。 ```yaml 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//...` の形の URL を外部サービスに登録する | トークンの発行は `keelson apps tokens create`、URL の組み立ては[外部連携](https://keelson.dev/ja/docs/building-apps/external-integrations/)を参照してください。Stripe の署名だけを送る通常の Webhook や、アプリ独自の API キーだけを送るクライアントは、アプリに届く前に拒否されます。 これらのパスへのリクエストには `X-Keelson-User-Id` が付きません。Keelson の資格情報に加えて、アプリ側でも Webhook 署名や API キーによる検証を行ってください。 --- ## email 受信メールの設定です。 ```yaml email: inbound: enabled: true ``` `email.inbound.enabled` は boolean で、既定は `false` です。受信メールを処理するにはコンテナが必要です。静的サイト(`type: web` + `assets`、`command` なし)で有効にすると、設定は受理されますがデプロイが `deploy.config.invalid` で失敗します。 --- ## verify デプロイ後の検証で追加で確認するパスです。既定では `/` だけを確認します。 ```yaml 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 新規アプリを作るときの配置リージョンを任意で指定します。 ```yaml region: us-oregon ``` クラウド事業者のリージョン名ではなく、Keelson の論理キーを指定します。 | 論理キー | 表示名 | |---|---| | `jp-tokyo` | 日本 | | `us-oregon` | 米国西海岸 | 新規アプリでは CLI の `--region`、`keelson.yaml` の `region`、ワークスペースの既定リージョンの順で優先されます。明示したリージョンが未定義または新規作成に未開放の場合は、別リージョンへ切り替えずに拒否されます。 アプリのリージョンは作成時に確定し、後から変更できません。既存アプリと異なる `region` を指定したデプロイは拒否されます。別リージョンへ移す場合は、新しいアプリとして作り直してください。 --- ## storage `storage` は廃止された `disk_id` だけを受理します。値は無視され、永続ストレージや `/data` の同期を有効にしません。残っていたら削除してください。 | フィールド | 型 | 必須 | 既定値 | 説明 | |---|---|---|---|---| | `disk_id` | string | — | `null` | 無視される旧識別子。小文字英数字とハイフン、1〜32 文字 | --- ## デプロイモード デプロイモードは `command`、`assets`、`fallback` の有無から導出されます。直接は選べません。`keelson status --json` などの出力は `deploy_mode` の生ラベルを返します。 | 呼称 | `deploy_mode` | `command` | `assets` | `fallback` | 説明 | |---|---|---|---|---|---| | Web アプリ | `container` | あり | なし | — | 通常のアプリ | | 静的サイト | `edge-static` | なし | あり | なし | 静的ファイルのみ | | SPA | `edge-spa` | なし | あり | あり | フォールバック付き静的ファイル | | ハイブリッド | `hybrid` | あり | あり | 必須 | 静的ファイル + バックエンド API | --- ## フィールド間の制約 | ルール | 内容 | |---|---| | 実行面が必要 | `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 ```yaml slug: crud-app description: "顧客と案件を管理する社内 CRM" runtime: python-slim command: "python app.py" db: mode: libsql migrate: "python migrate.py" env: PYTHONUNBUFFERED: "1" ``` ### 静的 SPA 手元で `npm run build` などを実行して `dist` を作ってからデプロイします。Keelson 側ではビルドしません。 ```yaml slug: marketing-site type: web runtime: node-slim db: mode: none assets: dir: dist fallback: index.html ``` ### 定期実行のみ ```yaml slug: daily-report runtime: python-slim db: mode: libsql env: PYTHONUNBUFFERED: "1" crons: - name: generate schedule: "0 9 * * *" command: "python report.py" timeout: 120 ``` ### Web アプリ + 定期ドレイン Web アプリが pending 行を Managed SQLite に書き、cron が別インスタンスで処理します。共有する状態はローカルファイルではなく `db.mode: libsql` に置きます。 ```yaml slug: task-drainer runtime: python-slim command: "python app.py" db: mode: libsql env: PYTHONUNBUFFERED: "1" crons: - name: drain schedule: "*/5 * * * *" command: "python drain.py" timeout: 120 ``` ### ハイブリッド(静的ファイル + バックエンド API) ```yaml slug: photo-galleries runtime: node-slim command: "node server.js" db: mode: libsql env: NODE_ENV: "production" assets: dir: dist fallback: index.html api: /api ``` ### Webhook を受ける API ```yaml slug: payment-hooks runtime: node-slim command: "npm start" db: mode: libsql env: 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:///api/webhooks//stripe`)。`methods` は Webhook には適用されないので、POST 以外を拒否したければアプリ側で判定します。 ### Go アプリ ```yaml slug: my-go-app runtime: go-slim command: "./app" db: mode: none ``` Keelson がデプロイ時に Linux 向けにビルドし、バイナリを `./app` に置きます。 --- ## よくあるエラー | 原因 | 対処 | |---|---| | `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` ディレクトリを改名する | --- # 環境変数一覧 Keelson がアプリに自動設定する環境変数 URL: https://keelson.dev/ja/docs/reference/environment-variables/ Language: ja --- Keelson がアプリのコンテナに設定する環境変数の一覧です。いずれも `keelson.yaml` の `env` には書きません。`KEELSON_` で始まる名前はプラットフォーム予約で、`env` / `secrets` には使えません。 ## 常に設定されるもの | 変数 | 内容 | |---|---| | `PORT` | アプリが listen するポート。読むだけで、設定しない | | `TZ` | ワークスペースのタイムゾーン(例: `Asia/Tokyo`) | | `KEELSON_MODE` | `keelson`。「Keelson 上で動いているか」の判定に使う。ローカルでは未設定 | | `KEELSON_APP_ID` | アプリの内部 ID | | `KEELSON_WORKSPACE_ID` | ワークスペースの内部 ID | | `KEELSON_TENANT_ID` | `KEELSON_WORKSPACE_ID` の互換用別名(値は同じ) | | `KEELSON_DEPLOY_ID` | 現在のデプロイの内部 ID | | `KEELSON_APP_URL` | アプリの公開 URL(`https://--.keelson.run`)。絶対 URL が必要な場面で使う。ホストを解決できる場合に設定される | | `KEELSON_DIRECTORY_BASE_URL` | Directory API のベース URL。Identity SDK が使う。`KEELSON_APP_URL` と同じ条件(ホストを解決できる場合)で設定される | 旧 tenant 名の変数も互換のため受け付けます。撤去時期は未定です。 ## 機能を有効にすると設定されるもの | 変数 | 条件 | 内容 | |---|---|---| | `KEELSON_DB_URL` | `db.mode: libsql` | Managed SQLite の接続 URL | | `KEELSON_DB_AUTH_TOKEN` | `db.mode: libsql` | Managed SQLite の認証トークン | | `TURSO_DATABASE_URL` / `TURSO_AUTH_TOKEN` | `db.mode: libsql` | 上 2 つの別名(互換用) | | `KEELSON_FILES_BUCKET` / `KEELSON_FILES_PREFIX` | コンテナ型のデプロイで、ファイル保存先が構成されているとき(通常のデプロイでは自動) | Files SDK が使う保存先。直接は使わない | | `KEELSON_INTERNAL_MEDIA_BASE_URL` / `KEELSON_APP_MEDIA_TOKEN` | コンテナ型のデプロイで、Media 機能が有効なとき(通常のデプロイでは自動) | Media SDK が使うアップロード先と認証。直接は使わない | | `KEELSON_MEDIA_URL_PREFIX` | 上と同じ | Media の配信 URL プレフィックス(`/__keelson/media/`) | | `KEELSON_DIRECTORY_TOKEN` | `keelson apps directory enable` 後 | Directory API のトークン。Identity SDK が使う。サーバー側だけで扱う | | `KEELSON_EMAIL_WEBHOOK_SECRET` | `email.inbound.enabled: true` | 受信メール Webhook の署名シークレット。Email SDK の署名検証が使う | | `KEELSON_EMAIL_API_URL` / `KEELSON_EMAIL_TOKEN` | メール送信が有効なとき | Email SDK の送信先と認証。直接は使わない | | `KEELSON_EMAIL_BASE_URL` | メール送信が有効で、ホストを解決できるとき | Email SDK がゲートウェイ経由で送るときの接続先。直接は使わない | 静的サイト(`command` なし)にはコンテナがないので、これらの変数は注入されません。Files / Media / Email の SDK は静的サイトからは使えません。 ## 設定されないもの - **`NODE_ENV`** — 自動では設定されません。`keelson.yaml` の `env` で `"production"` を宣言してください - **外部 DB の接続情報** — `db.mode: none` のときは何も注入されません。シークレットで渡します ## ローカル開発で使うもの SDK をローカルで動かすときの変数です。Keelson 上では設定しません。 | 変数 | 内容 | |---|---| | `KEELSON_FILES_DIR` | Files SDK のローカル保存先(既定 `./.keelson/files`) | | `MEDIA_DIR` | Media SDK のローカル保存先(既定 `./media`) | | `KEELSON_LOCAL_MODE=1` | Identity SDK をダミーデータで動かす | | `KEELSON_LOCAL_USER_ID` / `KEELSON_LOCAL_USER_EMAIL` / `KEELSON_LOCAL_USER_NAME` | ダミーユーザー | | `KEELSON_LOCAL_WORKSPACE_ID` / `KEELSON_LOCAL_WORKSPACE_ROLE` / `KEELSON_LOCAL_APP_ID` | ダミーのワークスペース・ロール・アプリ | 旧名の `KEELSON_LOCAL_TENANT_ID` と `KEELSON_LOCAL_TENANT_ROLE` も互換のため 受け付けます。撤去時期は未定です。 ## 関連ページ - [環境変数とシークレット](https://keelson.dev/ja/docs/deploy/environment-variables/) — 自分で設定する値 - [ファイルとメディア](https://keelson.dev/ja/docs/building-apps/files-and-media/) - [認証情報をアプリで使う](https://keelson.dev/ja/docs/building-apps/using-identity/) --- # CLI コマンド keelson コマンドの一覧 URL: https://keelson.dev/ja/docs/reference/cli/ Language: ja --- `keelson` CLI の主なコマンドと、スクリプトやエージェントから使うときに知っておくべき挙動をまとめています。通常は AI エージェントが Skill を通じて実行するので、すべてを覚える必要はありません。各コマンドの全フラグと既定値は `keelson <コマンド> --help` で確認できます。 インストールは[クイックスタート](https://keelson.dev/ja/docs/introduction/quickstart/)、更新は `keelson upgrade` で行います。 ## 共通フラグ 対応するコマンドで使えるフラグです。`login` / `logout` / `install-agent` / `dev ...` など一部のコマンドは受け付けません。`app curl` は `--json` と `--quiet` を明示的に拒否します。 | フラグ | 内容 | |---|---| | `--app ` | 対象アプリ。省略時はカレントディレクトリの `keelson.yaml` から解決。`access show` / `access set` / `apps tokens create` / `apps tokens rotate` / `feedback` は省略できない | | `--workspace ` | 対象ワークスペース。`--workspace` → `keelson.yaml` の `workspace` → 前回使った既定 → 所属が 1 つならそれ、の順で決まる。複数に属していて前段で決まらないときだけ必要。同名のワークスペースがあるときは slug か ID で指定 | | `--json` | 結果を JSON で出力。スクリプトやエージェントから使うときに | | `--quiet` | 説明や進捗を抑える。出力の形はコマンドごとに違う(`secrets set` は key ごとに 1 行、`deploys list` は ID ごとに 1 行、`deploy --check` は成功時に何も出さない) | | `--timeout ` / `--retry ` | API 呼び出しのタイムアウト(既定 15 秒)と再試行回数(既定 0) | | `--no-browser` | ブラウザを開かず URL を表示する(`login`、承認が必要な操作) | `--json` でコマンドが失敗すると、標準出力に `{"error":{"code","message","hint","retryable"}}` が返ります。`hint` に従ってください。`retryable` が `false` なら同じコマンドを繰り返しても結果は変わりません。 旧名の `--tenant` と `keelson tenants list` も互換のため受け付けます。撤去時期は未定です。 ## セットアップ | コマンド | 内容 | |---|---| | `keelson login [--no-browser]` | ブラウザでログインし、この端末を紐付ける | | `keelson logout [--all-devices]` | この端末の保存済みログイン情報を削除し、サーバー側のセッションを失効させる。`--all-devices` ですべての端末をログアウト。`KEELSON_TOKEN` で渡したトークンは失効しない | | `keelson whoami` | ログイン中のユーザーと、現在選ばれているワークスペース。ワークスペースの slug を確実に取るには `workspaces list --json` を使う | | `keelson workspaces list [--query ] [--exact]` | 所属ワークスペースの一覧・検索。`--json` の `slug` が `--workspace` に渡す値 | | `keelson doctor [--fix-path]` | PATH・ログイン・Skill の状態を確認。`--fix-path` はシェルの設定ファイルに PATH を追記 | | `keelson install-agent [--global]` | AI エージェントに Skill を入れる。引数なし + `--yes` で入れてある Skill をすべて更新 | | `keelson upgrade` | CLI を最新版に更新 | | `keelson version` | バージョン表示 | | `keelson telemetry status\|off\|on` | [CLI の利用状況データ](https://keelson.dev/ja/docs/reference/telemetry/)の状態確認、停止、有効化 | | `keelson feedback --app [--deploy ] < feedback.json` | CLI や Skill の使い勝手を標準入力の JSON で送る。形式は `keelson feedback --help` | ## デプロイ | コマンド | 内容 | |---|---| | `keelson deploy` | カレントディレクトリのアプリをデプロイ。完了まで待つかどうかは下の表を参照 | | `keelson deploy --new [--region ] [--secrets-from-env-file ]` | アプリを作成して初回デプロイ。env ファイルの値をシークレットとして登録し、そのファイルはアーカイブから除外 | | `keelson deploy --check [--json]` | アップロードせず、設定の検証とアーカイブ内容(除外ファイル、秘匿値らしきファイル)を表示。ローカル検証なので、プランの上限に当たるかどうかまでは分からない | | `keelson deploy --ndjson --yes` | スクリプト向け。進捗を 1 行 1 JSON で流し、完了時に `{"result":"success"\|"failed"}` | | `keelson status [deploy_id] [--wait] [--max-wait ]` | 指定したデプロイ(省略時はアプリの最新デプロイ)の状態。最新デプロイが失敗していても前の成功リビジョンが動いていることはあるので、いま動いているものの状態は `app info` で見る | | `keelson diagnose [deploy_id]` | 失敗したデプロイの診断(id あり。起動失敗時は保存済みのアプリの起動ログを含む)/ 稼働中アプリの診断(id なし) | | `keelson deploys list [--limit] [--offset]` | デプロイ履歴 | | `keelson deploys download [-o ]` | そのデプロイに使ったソースアーカイブをダウンロード(保持期間内のみ) | | `keelson rollback [deploy_id] [--yes]` | 前の成功デプロイ(または指定したデプロイ)に戻す。対象はコンテナイメージを持つ成功デプロイだけで、静的サイトは以前のソースを再デプロイして戻す。ビルドせずに戻すが `db.migrate` は再実行される。受け付けた時点で返るので、返ってきたデプロイ ID を `status --wait` で確認する。`--json` や非対話端末では `--yes` が必要 | ### deploy が完了を待つかどうか | 実行のしかた | 挙動 | |---|---| | 対話端末で `keelson deploy` | 完了まで待つ(既定 30 分。`--watch-timeout` で変更) | | パイプや CI など非対話で `keelson deploy` | 受け付けた時点で返る。待つなら `--watch` | | `--json` | 受け付けた時点で返る。`--watch` と併用不可 | | `--ndjson` | 完了まで待つ(`--no-watch` と併用不可) | | `--no-watch` | 対話端末でも受け付けた時点で返る | 待ち時間の上限を超えても監視をやめるだけで、サーバー側のデプロイは止まりません。`status --wait` で続きを確認できます。 ### NDJSON の読み方 段階の実行中は `{"stage":"health_check","status":"progress",…}` のような行が流れます。進捗行の `status` で成否を判定しないでください。判定は次の 3 つで行います。 - 監視まで進んだ場合、最後に `result` を持つ行が出る - `keelson.yaml` が無い、設定が不正など、監視に入る前の失敗は `{"error":{…}}` の 1 行だけで、`result` 行は出ない - プロセスの終了コード。0 以外は失敗 ## 確認 | コマンド | 内容 | |---|---| | `keelson app curl [-i] [--method] [--data] [--form] [--header]` | 認証済みでアプリにリクエストを送る。GET / HEAD の一時的な失敗は既定で最大 2 回再試行(`--retry 0` で止める)。`--data` を付けるときは `--method` も指定する。`--form` は省略時 POST。`-i` の status / header は標準エラー、body は標準出力。[デプロイ後の確認](https://keelson.dev/ja/docs/deploy/verify-deploy/) | | `keelson preview [--ttl] [--allow-writes] [--json]` | 認証済みの短命な券を発行する | | `keelson app info` / `start` / `stop` / `restart` | アプリの情報表示、起動、サスペンド、再起動。`restart` は完了まで待つ(`--no-watch` で受付後に返る) | `preview` と `app curl` は、いま動いているデプロイを行った本人以外が実行すると、読み取りだけでもブラウザでの承認が要ります。この承認は下の「ブラウザでの承認が必要な操作」とは別の流れで、承認しても操作は実行されません。承認後に同じコマンドへ `--confirmation ` を付けて再実行します(期限 30 分)。 ## ログ | コマンド | 内容 | |---|---| | `keelson logs app [--mode live\|history] [--severity] [--previous] [--limit] [--since]` | アプリの標準出力・標準エラー | | `keelson logs cron [--severity] [--limit] [--since]` | cron の実行ログ | | `keelson logs access [--limit] [--since]` | アクセスログ | | `keelson logs deploy [deploy_id] [--limit] [--since]` | デプロイの進行ログと保存済みの失敗詳細。アプリが起動中に終了した場合は、アプリの起動ログも表示。成功時のビルド出力は保存されないため、表示できるログがなければ理由を表示 | `--since` は `1h` や `1d12h` のような期間(1 秒〜30 日)です。`--json` の各行は文字列ではなく、時刻や severity を持つオブジェクトです。 ## シークレット 値はコマンド引数ではなく標準入力または env ファイルから渡します。 | コマンド | 内容 | |---|---| | `keelson secrets list` | 設定済みの名前と更新日時。値は表示しない | | `echo -n "" \| keelson secrets set [--apply]` | 1 件設定。`--apply` で再デプロイまで要求(受付後に返る) | | `keelson secrets set --from-env-file [--apply]` | env ファイルからまとめて設定。key ごとに保存するので、途中で失敗すると一部だけ保存された状態になる(エラーに保存済みの key が入る) | | `keelson secrets unset ` | 削除 | シークレットは次のデプロイ(または `--apply`)で反映されます。 ## アプリ管理 | コマンド | 内容 | |---|---| | `keelson apps list [--workspace ] [--query ] [--exact]` | アプリ一覧。`--workspace` を省略すると所属する全ワークスペースを対象にする(`keelson.yaml` や前回の既定では絞らない)。`--json` の形は `--workspace` あり(`{apps: […]}`)となし(`{workspaces: […]}`)で違う | | `keelson apps duplicate --name [--copy-secrets] [--enable-schedule]` | アプリを複製。cron のスケジュールは既定で無効のまま複製 | | `keelson apps rename ` | 公開 URL の slug を変える。**旧 URL は 410 を返し、自動リダイレクトはされない**。反映まで時間がかかる。手元の `keelson.yaml` の `slug` も書き換える | | `keelson apps delete [slug]` | アプリを削除。**ブラウザでの承認が必要** | | `keelson quotas` | プランの上限と使用量 | ## 定期実行ジョブ | コマンド | 内容 | |---|---| | `keelson crons list [--include-disabled]` | ジョブ一覧 | | `keelson crons trigger [--wait]` | 今すぐ実行。`--wait` で実行結果まで待つ | | `keelson crons enable ` / `disable ` | 有効化 / 無効化 | | `keelson crons runs list [--cron ] [--limit] [--offset]` | 実行履歴 | | `keelson dev cron run [--file] [--dir]` | `keelson.yaml` の cron をローカルで 1 回実行(スケジューラではない) | ## データベース | コマンド | 内容 | |---|---| | `keelson db apply [file.sql]` | Managed SQLite に SQL を実行(省略か `-` で標準入力)。**既にテーブルなどがある DB へはブラウザでの承認が必要**。テーブル・インデックス・ビュー・トリガーを 1 つも持たない初回の DB には承認なしで適用される | | `keelson snapshots list` | 復元ポイントと実行中の取り出し(exports)の一覧 | | `keelson snapshots create` | 手動スナップショット | | `keelson snapshots download [-o ]` | バックアップのダウンロード。`-o` を省くとダウンロード URL を表示するだけでファイルは書かない | | `keelson snapshots export --at ` | 任意時点(PITR)のエクスポートを作成。完了後に `download` で取得 | | `keelson snapshots restore ` | 復元。**ブラウザでの承認が必要**。72 時間以内なら取り消し可 | | `keelson snapshots restore-status` | 最新の復元の進捗と結果を確認 | | `keelson db revoke-tokens [app] [--yes]` | DB の認証トークンを失効させる(破壊的)。端末内で確認を求める。非対話端末では `--yes`。失効後、新しいリビジョンに切り替わるまで DB は一時的に使えない | | `keelson db recover [app]` / `credential-status [app]` | 認証情報の復旧と状態 | ## アクセス制御 | コマンド | 内容 | |---|---| | `keelson groups list` | グループ一覧 | | `keelson groups create [--name] [--description] [--if-not-exists]` | カスタムグループを作成 | | `keelson groups members list ` | グループのメンバー | | `keelson groups members add\|remove ...` | 既存メンバーの所属を変更(招待ではない) | | `keelson access show --app ` | アプリの閲覧 / 管理グループ | | `keelson access set --app [--view ...\|--view none] [--manage ...] [--allow-self-lockout]` | 権限を設定。指定した側は丸ごと置き換え、指定しなかった側は保持。管理は空にできない。自分の権限が失われる変更は `--allow-self-lockout` が要る | ## 外部連携 | コマンド | 内容 | |---|---| | `keelson apps tokens create --app --name --scope [--scope …] [--allowed-ip …]` | アプリトークンを発行(1 回だけ表示)。`--app` は省略できない | | `keelson apps tokens list` | 一覧(メタデータのみ) | | `keelson apps tokens rotate --app --token-id ` | ローテーション。旧トークンは猶予付きで失効 | | `keelson apps tokens delete ` | 失効 | | `keelson apps directory enable` | Directory API のトークンを発行し、`KEELSON_DIRECTORY_TOKEN` として登録(要再デプロイ) | | `keelson domains list` | カスタムドメインの一覧と状態 | | `keelson domains add\|verify\|remove [--yes]` | カスタムドメインの追加・検証・削除(Team)。`remove` は非対話端末では `--yes` | | `keelson dev email --to ... --subject ...` | ローカルのアプリに受信メールをテスト送信 | `--scope` に指定できる値は次のとおりです。受信用と Directory 用は同じトークンに混在できません。 | scope | 用途 | |---|---| | `api` | 外部システムからアプリの `/api/external/...` を呼ぶ | | `webhook` | 外部サービスからアプリの Webhook を受ける | | `directory:members:read` / `directory:identity:read` / `directory:groups:read` / `directory:group-members:read` | アプリから Directory API を呼ぶ(通常は `apps directory enable` が付与する) | ## ブラウザでの承認が必要な操作 アプリの削除、既存スキーマがある DB への SQL の実行、スナップショットからの復元は、CLI だけでは完了しません。コマンドは承認用 URL を表示し(`confirmation_required`)、ブラウザで承認すると操作がサーバー側で実行されます。コマンドを再実行する必要はありません。承認の期限は 15 分です。 URL を表示したあとの挙動は実行のしかたで変わります。 - 対話端末: 既定で承認と実行の完了まで待つ。`--wait=false` で待たずに返る - `--json` または非対話端末: 既定で待たずに返る。`--wait` を付ければ待つ `preview` / `app curl` の承認は、これとは別の再実行方式です(「確認」の節を参照)。`rollback` / `db revoke-tokens` / `domains remove` はブラウザ承認ではなく端末内の確認で、非対話端末では `--yes` が要ります。 ## 環境変数 | 変数 | 内容 | |---|---| | `KEELSON_TOKEN` | ログインの代わりに使うトークン(CI 向け)。保存済みログインより優先。設定してあると空文字でもエラーになる | | `KEELSON_NO_UPDATE_CHECK=1` / `KEELSON_NO_SKILL_SYNC=1` | 更新確認 / Skill の自動更新を止める(`KEELSON_NO_SKILL_SYNC` は空でなければ `0` でも止まる) | | `KEELSON_NO_TELEMETRY=1` | [CLI の利用状況データ](https://keelson.dev/ja/docs/reference/telemetry/)を止める | | `KEELSON_CONFIG_DIR` | 設定ファイル(`credentials.json` / `config.json`)を置くディレクトリ | | `KEELSON_API_BASE_URL` / `APP_DOMAIN_BASE` | 接続先 API とアプリドメインの上書き(通常は不要) | --- # エラーコード CLI・デプロイ・実行時に表示されるエラーコードと対処 URL: https://keelson.dev/ja/docs/reference/error-codes/ Language: ja --- CLI とデプロイのエラーは `code` と `hint`(対処方法)を伴って返ります。AI エージェントにそのまま渡せば対処できます。`hint` がある場合はこのページより `hint` を優先してください。workspace 名のコードへ移行したエラーでは、旧 tenant 名のコードを互換用の `error.aliases` に載せます。撤去時期は未定です。ここでは人が読むための一覧を、発生する場所ごとにまとめます。 このページは日常的に遭遇するコードの一覧で、全コードの網羅ではありません。掲載していないコードが出たときも、`code` と `hint` の形は同じです。 ## エラーがどこに入っているか 経路によって、理由を読む場所が違います。 | 経路 | 形 | |---|---| | CLI(`--json`) | 標準出力に `{"error":{"code","message","hint","retryable"}}` | | デプロイの失敗(`status` / `diagnose`) | `failure_code` と `hint` | | Keelson API の通常のエラー | `{"detail": "..."}`。入力検証エラーでは `detail` が配列。`code` / `hint` は付かない | | アプリの URL に対する認可の拒否(ゲートウェイ) | ブラウザには HTML の案内。fetch / XHR には `{"detail":"ip-restricted"}` のような JSON と、理由を入れた `X-Keelson-Auth-Error` ヘッダー | | 稼働枠不足・停止中(ゲートウェイ) | 503。`x-keelson-platform-error` ヘッダー(`capacity-full` / `app-suspended`)。稼働枠不足は `X-Keelson-Error-Code: CAPACITY_FULL` も付く | | 存在しない URL・停止中・予約パス(エッジ) | 404 / 410 / 503 / 403 の平文と `x-keelson-platform-error` ヘッダー。ゲートウェイに届かないので `X-Keelson-Auth-Error` は付かない | | Files / Media の配信 | `x-keelson-error` ヘッダーに理由。一部のコードだけ `{error, hint, doc}` の JSON | `retryable` は HTTP のステータスからは決められません。同じ 503 でも `false` のことがあり、ビルドの 429 にはトライアルの累積上限のように待っても解除されないものがあります。 ## デプロイ前のチェック(CLI) アップロード前に報告され、`keelson deploy --check` でも確認できます。エラーはデプロイを止めますが、警告は止めません。依存マニフェストがない場合、Go ではエラー、Python と Node.js では警告になります。 | コード | 原因 | 対処 | |---|---|---| | `missing_dependency_manifest` | 選択したランタイムの依存マニフェストがない | Go ではプロジェクトルートに `go.mod` を置く。Python または Node.js で外部ライブラリを使う場合はマニフェストを置く。標準ライブラリだけのアプリでは依存マニフェストは必須ではありません | | `command_installs_dependencies` | `command` に `pip install` / `npm install` / `go build` がある | 削除し、起動コマンドだけにする | | `runtime_command_mismatch` | `runtime` と `command` の言語が合わない(例: `python-slim` で `node`) | どちらかを直す | | `assets_dir_empty` | `assets.dir` が無い、空、またはパスの大文字小文字が違う | ビルドを実行する。パスを確認する | | `assets_fallback_missing` | `assets.fallback` のファイルが `assets.dir` にない | ビルド出力を確認する | | `db_wiring_fail`(警告) | `db.mode` とコードの DB 接続が食い違う(接続先、ローカル開発用のフォールバック、宣言の不一致など複数の規則がある) | 表示された `hint` に従う。多くは `KEELSON_DB_URL` を読む libSQL クライアントに直す | | `file_wiring_fail`(警告) | 状態ファイルやアップロードをローカルディスクに書いている | Files / Media SDK に置き換える | ## keelson.yaml の検証 | コード | 原因 | 対処 | |---|---|---| | `invalid_keelson_config` | YAML が不正、`db.mode` が `libsql` / `none` 以外、`db.migrate` を `none` と併用、`KEELSON_` で始まる env、`/__keelson` 配下のパス、不明な `runtime`、cron が 10 本超、など | `message` の内容を直す | | `config_missing_field` | 必須フィールドがない(`slug`、`runtime`、`db` など。静的サイトでは `type` と `assets` も) | 追加する | | `env_value_not_string` | `env` の値が文字列でない、YAML が曖昧に解釈するキー、キーの重複、merge key(`<<`) | 値は引用符かブロック文字列にする。曖昧なキー(`on` / `yes` / 数字など)は引用符で囲む。重複は削除する。merge key は展開して書く。重複と merge key は引用符で囲んでも拒否される | | `description_too_long` | `description` が 300 文字超 | 短くする | | `workers_not_supported` | `workers:` がある | 削除して `crons` で書く | | `DB_DATABASES_REMOVED` | `databases:` がある | 削除する。永続データは `db.mode: libsql` | | `SQLITE_LOCAL_SQLITE_INVALID_PATH` | `db.local_sqlite.paths` が `/tmp/` の外 | `/tmp/` か `:memory:` にする | | `CRON_TIMEOUT_EXCEEDS_STANDARD_LIMIT` | `crons[].timeout` が 600 秒超 | 下げる、処理を分割する | | `plan_cron_limit` / `plan_cron_min_interval` / `plan_schedule_timeout` | cron の本数・間隔・timeout がプラン上限を超える | 減らすか、プランを上げる | | `ARTIFACT_SQLITE_FILE_DRIVER` | ファイル SQLite クライアント(`sqlite3`、`better-sqlite3` など)が検出された | libSQL クライアントへ移行。一時用途なら `db.local_sqlite` で宣言 | | `ARTIFACT_EXEC_NODE_CRON` / `ARTIFACT_EXEC_APSCHEDULER` / `ARTIFACT_EXEC_BACKGROUND_TASKS` / `ARTIFACT_EXEC_SET_INTERVAL`(注意) | アプリ内スケジューラが検出された | `crons` に移す | ビルド出力の直下に `__keelson` ディレクトリがあるとビルドが失敗します。このときの `failure_code` は `deploy.build.failed` で、ビルドログに `reserved_path_conflict` が出ます。ディレクトリ名を変えてください。 ## デプロイの失敗 `keelson status` / `keelson diagnose` に `failure_code` として表示されます。 | コード | 原因 | 対処 | |---|---|---| | `deploy.config.invalid` | `keelson.yaml` の内容が不正 | 指摘されたキーを直して再デプロイ | | `deploy.config.secret_missing` | `secrets.required` で宣言したシークレットが未設定 | `keelson secrets set `(値は標準入力)で全て設定してから再デプロイ | | `deploy.artifact.invalid` | アーカイブの問題(ロックファイルなし、ブロック対象の検出) | 指摘された箇所を直す | | `deploy.artifact.assets_invalid` | `assets.dir` / `assets.fallback` で宣言したファイルがアップロードに含まれていない | 手元でビルドしてから再デプロイ | | `deploy.build.failed` | ビルド失敗(依存の解決失敗、ビルドスクリプトのエラー、予約パスの衝突) | `keelson logs deploy ` でビルド出力の末尾を見る | | `deploy.build.timed_out` | ビルドが制限時間内に終わらなかった | 不要な依存を減らす、重い前処理をビルドの外に出す | | `deploy.build.image_too_large` | イメージが大きすぎる | 不要な依存やファイルを減らす | | `deploy.runtime.start_failed` | アプリが起動中に終了、またはコンテナが起動状態にならなかった | `keelson logs deploy ` で保存済みのアプリの起動ログを読み、`PORT` と `0.0.0.0` を確認 | | `deploy.runtime.health_check_failed` | 起動・ヘルス検証の制限時間内に、`/`(もしくは `health.path`)から期待する応答(2xx / 3xx / 404)を得られなかった。アプリが起動中に終了した場合や、401 / 403 / 5xx を返し続ける場合を含む | `keelson logs deploy ` で保存済みのアプリの起動ログを読み、待ち受けポートと `health.path` を確認 | | `deploy.runtime.migration_failed` | `db.migrate` が 0 以外で終了。旧リビジョンが配信を継続 | マイグレーションを直して再デプロイ。途中まで適用された DB の変更は自動では戻らない | | `deploy.verify.failed` | `verify` のパスが取得できない、または JS / CSS の Content-Type が不一致 | パスとビルド出力を確認。詳細は `failure_logs` の `verification_*` コードに出る | | `deploy.plan.limit_exceeded` | プランの上限超過 | 減らすか、プランを上げる | | `deploy.plan.cron_count_exceeded` | cron の本数がプラン上限を超えている | 減らすか、プランを上げる | | `deploy.plan.cron_interval_too_short` | cron の間隔がプランの最小間隔より短い | 間隔を伸ばすか、プランを上げる | | `deploy.plan.schedule_timeout_exceeded` | 明示した `crons[].timeout` がプラン上限を超えている | timeout を下げるか、プランを上げる | | `deploy.app.suspended` | アプリまたはワークスペースが Keelson 側の制限措置を受けている | サポートへ連絡する。利用者や管理者による再開では解除されない | | `deploy.app.operation_in_progress` | このアプリで別の操作が進行中だったため、デプロイを開始できなかった | 別の操作が完了してから再デプロイ | | `deploy.platform.temporarily_unavailable` | 一時的な障害 | 待ってから再試行する。追加で 3 回まで。それでも失敗するなら `deploy_id` を添えてサポートへ | | `deploy.platform.error` | プラットフォーム側のエラー | 再試行しても直らない。`deploy_id` を添えてサポートへ | | `deploy.cancelled` | デプロイが取り消された | 必要なら再デプロイ | | `deploy_in_progress`(409) | 別のデプロイまたはアプリ操作が進行中 | 進行中の操作が完了してから同じコマンドを再実行 | | `build_rate_limit_exceeded` / `build_guardrail_exceeded`(429) | ビルド回数・ビルド時間・同時実行・連続失敗の上限 | メッセージが解除条件を示す。連続失敗は原因を直して記載の時刻を待つ。**トライアルのビルド枠は累積で、待っても解除されない**ので、その場合はプランを変更する | | `saved_config_unsupported`(409) | 再デプロイ / ロールバック対象の `keelson.yaml` が現在のスキーマに合わない | 直して通常のデプロイをする | ## 定期実行ジョブの失敗 `keelson crons runs list` と `keelson logs cron` に出ます。 | コード | 意味 | |---|---| | `cron.failed.command_failed` | コマンドが 0 以外で終了した | | `cron.failed.timed_out` | `timeout` を超えた | | `cron.failed.terminated_no_callback` | 実行が終了したが結果が報告されなかった | | `dispatch_failed` | 実行の起動に失敗した | | `cron.skipped.schedule_disabled` | ジョブが無効化されている | | `cron.skipped.quota_exceeded` | プランの実行枠を超えた | | `cron.skipped.due_to_lock` / `cron.skipped.lease_held` | 前回の実行がまだ終わっていない | | `cron.skipped.missed_run` | 予定時刻を過ぎたため飛ばした | | `cron.skipped.app_suspended` | アプリが停止中 | | `cron.skipped.plan_downgrade` | プラン変更で実行できなくなった | ## バックアップと復元 `keelson snapshots ...` のエラーです。名前が `snapshot_export_` で始まるものは `snapshots export` の同じ条件です。 | コード | 意味 | 対処 | |---|---|---| | `snapshot_plan_not_included` | 手動スナップショットがプランに含まれない | プランを変更する | | `snapshot_no_managed_db` | Managed SQLite を使っていない | `db.mode: libsql` で DB を作ってから | | `snapshot_db_name_invalid` / `snapshot_db_name_unknown` | DB 名が不正、または存在しない | `hint` に出る名前を使う | | `snapshot_already_running` / `snapshot_export_already_running` | 前の処理が実行中 | 終わってから再試行 | | `snapshot_rate_limited` / `snapshot_export_rate_limited` | 回数上限 | `hint` の時刻まで待つ | | `snapshot_export_invalid_timestamp` | 復元可能な範囲の外の時刻 | 範囲内の時刻を指定する | | `snapshot_app_deleting` / `snapshot_export_app_deleting` | アプリが削除中 | — | | `snapshot_launch_failed` / `snapshot_export_launch_failed` | 起動に失敗 | 再試行。続くならサポートへ | | `snapshot_disabled` / `snapshot_storage_unconfigured`(export 系も同様) | プラットフォーム側で無効 | サポートへ | | `snapshot_not_ready` | まだダウンロードできない(`X-Keelson-Error-Code` ヘッダー) | 完了を待つ | ## CLI のエラー | コード | 意味 | 対処 | |---|---|---| | `not_logged_in` | 未ログイン | `keelson login` | | `multiple_workspaces` / `workspace_ambiguous` / `workspace_not_found` / `no_workspaces` | ワークスペースを特定できない | `--workspace `。`keelson workspaces list --query` で検索 | | `app_not_found` | アプリが見つからない | `slug` を確認。新規なら `--new` | | `app_manage_required` | アプリは存在するが、管理権限がない | 現在の管理者に、管理権限を持つグループへ自分を追加してもらう。ワークスペースの OWNER / ADMIN なら `keelson groups members add <グループ> <メール>` で自分を追加する | | `app_deleting` | 削除中のアプリ | 完了を待つ | | `forbidden` | 権限がない。`CONSOLE_ONLY_OPERATION` ならコンソール限定の操作 | ロール・アプリ権限を確認 | | `confirmation_required` | ブラウザでの承認が必要な操作 | 表示された URL を開いて承認。削除・SQL・復元は承認と同時に実行されるので再実行は不要。`preview` / `app curl` は承認後に `--confirmation ` を付けて同じコマンドを再実行する | | `confirmation_expired` / `confirmation_rejected` | 承認の期限切れ(削除・SQL・復元は 15 分、`preview` / `app curl` は 30 分)/ 却下 | コマンドをやり直す | | `deploy_failed` | デプロイ失敗 | `keelson diagnose ` | | `sql_failed` | `db apply` の SQL エラー。ロールバック済み | SQL を直す | | `usage`(`access set`。API の 409 `detail.reason` が `last_manage_binding_removed` / `no_effective_manager` / `self_lockout`) | 管理グループが空になる、有効な管理者がいなくなる、自分の権限が失われる | 管理グループを残す。`--allow-self-lockout` で解除できるのは自分が外れる場合だけで、管理グループや有効な管理者がゼロになる変更は解除できない | | `transient` | 一時的なネットワークエラー | `--retry` を付けて再試行 | | `skill_outdated`(`meta.skill_outdated`。`doctor` の警告でもある) | Skill が CLI より古い。コマンドは失敗しない | `keelson install-agent --yes` | ## 利用者がブラウザで見るもの | 表示 | 状態 | 対処 | |---|---|---| | ログイン画面 | 未ログイン | ワークスペースに登録されたアカウントでログイン | | 「アクセスできません」(403) | メンバーでない、ブロック済み、アプリの閲覧権限がない | 管理者にメンバー登録・権限を依頼 | | 「このアプリは、許可されたアクセス元からのみ利用できます」(403) | IP 制御で拒否。画面に送信元 IP が表示される | 管理者にその IP のアクセス元への追加を依頼 | | 「アプリの稼働枠が空いていないため起動できません」(503) | 同時に使えるアプリ数の上限 | 枠を使っている別のアプリへのアクセスが約 5 分途絶えると空く。使われ続けていれば空かないので、管理者がアプリの停止・優先起動・プラン変更で調整する | | 「アプリを起動しています」 | スリープからの起動中 | 数秒待つ(自動で再読み込み) | | 「このアプリは停止中です」(503) | サスペンド中、または Keelson 側の制限措置 | 管理者が再開する。再開しても直らない場合は制限措置なのでサポートへ | | 「App not found」(404) | URL が間違っている、またはアプリが削除された | URL を確認 | | 410 Gone | 公開 URL が変更された(旧 URL は 30 日間予約) | 新しい URL を案内 | | 504 | アプリが 120 秒以内に応答ヘッダーを返し始めなかった。ストリーミングの全体時間ではない | 処理を短くする、cron に逃がす | | 501 | WebSocket は未対応 | SSE やポーリングに変える | API や XHR から同じ状況になると、ゲートウェイの拒否では JSON の `detail` と `X-Keelson-Auth-Error` ヘッダーに理由(`ip-restricted`、`app-view-denied` など)が入ります。稼働枠不足と停止中は `x-keelson-platform-error` ヘッダー(`capacity-full`、`app-suspended`)です。 ## 外部連携(アプリトークン / Webhook) 詳しい理由は `X-Keelson-Auth-Error` で返ります。IP 許可範囲による拒否でも、互換性のため JSON の `detail` は `machine-forbidden` または `webhook-forbidden` のままです。 `machine-forbidden` と `webhook-forbidden` は、アプリが存在しない場合、トークンが別のアプリのものである場合、経路が消失した場合を意図的にまとめ、応答からアプリの存在を判定できないようにしています。 | `X-Keelson-Auth-Error` | 原因 | |---|---| | `invalid-app-token` | トークンが無効、または失効済み | | `machine-scope-denied` | トークンのスコープ(`api` / `webhook`)がパスと合わない | | `machine-endpoint-denied` | `auth.endpoints` で宣言されていないパス・メソッド | | `machine-forbidden` / `webhook-forbidden` | アプリが存在しない、トークンが別のアプリのもの、または経路が消失した | | `machine-ip-not-allowed` | アプリトークンの許可 IP の外から呼ばれた | | `invalid-webhook-secret` | Webhook シークレットが一致しない | | `webhook-scope-denied` | トークンに `webhook` スコープがない | | `webhook-ip-not-allowed` | Webhook トークンの許可 IP の外から呼ばれた | `/api/webhooks/email` などプラットフォーム予約のパスへの Webhook は、ゲートウェイより手前のエッジが 403 の平文で拒否します。このときのヘッダーは `X-Keelson-Auth-Error` ではなく `x-keelson-platform-error: auth-webhook-endpoint-blocked` です。 --- # CLI の利用状況データ Keelson CLI が収集する情報と停止方法 URL: https://keelson.dev/ja/docs/reference/telemetry/ Language: ja --- Keelson は、どの操作が成功しているかを把握し、信頼性の問題を見つけて CLI を改善するために、CLI の利用状況データを収集します。この機能は既定で有効です。 ## 収集するもの - サブコマンド名 - 終了コードと、利用できる場合は公開済みの失敗符号 - コマンドの所要時間 - 使用したフラグの名前(値は含みません) - 対話端末(TTY)で実行されたかどうか - CLI のバージョン - CLI を起動したエージェントの種別(判別できない場合は不明として記録) - 一覧系コマンドでは、結果が 0 件、1 件、複数のいずれかだけ - 重複を除くためのイベントごとの識別子 - コマンドを実行した日時 - セッション識別子。端末側で作る乱数で、コマンドが 30 分記録されないと作り直されます。保存されるイベントの行には、アカウント、ワークスペース、アプリの識別子は含まれません。イベントの送信にはログイン済みの資格情報を使い、送信回数はアカウント単位で数えるため、送信経路自体は匿名ではありません。 ## 収集しないもの - アプリのソースコードやデプロイアーカイブの中身 - ログ、標準出力、標準エラーの本文 - 環境変数の値やフラグに渡した値 - ファイルパス、ワークスペース名、アプリ名 - `keelson.yaml` の本文 - AI エージェントとの会話 ## 利用状況データを止める 設定を保存して停止するには、次を実行します。 ```sh keelson telemetry off ``` 環境変数で停止するには、次を設定します。 ```sh KEELSON_NO_TELEMETRY=1 ``` 環境変数は保存済みの設定より優先されます。環境変数が設定されている間は、`keelson telemetry on` を実行しても有効にできません。停止すると未送信のイベント記録は削除され、現在の状態はいつでも `keelson telemetry status` で確認できます。 停止するのはイベントの記録と送信、および `X-Keelson-Client` ヘッダーです。通常の `User-Agent` ヘッダーには、停止後も `keelson-cli/` として CLI のバージョンが含まれます。 ## 初回送信時の告知 初めて利用状況データを送信する直前に、対話端末で実行している場合だけ 1 行の告知を表示します。対話端末ではない自動実行では表示しません。 ## `keelson feedback` との違い `keelson feedback` は、利用者が提供するフィードバックを共有するための別の仕組みです。明示的に実行し、フィードバック共有が有効な場合にだけ送信します。フィードバック共有は既定で無効です。CLI の利用状況データを有効または無効にしても、フィードバック共有の設定は変わりません。