ストレージとデータ
TODO(内部向け・リリース前に対応して削除)
Section titled “TODO(内部向け・リリース前に対応して削除)”Keelson のストレージの考え方
Section titled “Keelson のストレージの考え方”Keelson のアプリには、2種類のファイルシステム領域があります。
| 領域 | 永続性 | 用途 |
|---|---|---|
| アプリディレクトリ(ソースコード等) | 揮発(置き換わる) | アプリのコード、依存パッケージ |
/data | 揮発(再起動・scale-to-zero で失われる) | 一時的なスクラッチ領域 |
/data に書いたファイルは永続化されません(再起動・再デプロイ・scale-to-zero で失われます)。永続的な関係データは Keelson Managed SQLite(db.mode: libsql) を使ってください。汎用ファイルの永続 I/O は後続のデータファイル SDK で提供予定です。
ファイルの保存(アプリデータファイルとメディア)
Section titled “ファイルの保存(アプリデータファイルとメディア)”アプリはファイルを保存できます。保存が完了した時点でデータは永続化されています(バックグラウンド同期はありません)。
- アプリデータファイル — アプリが名前を付けて更新するファイル(実行状態・設定・小さなキャッシュなど)。書き込みはファイル全体を対象とし、完了した時点で反映されます。これらのファイルはアプリの内部用で非公開です。
- メディア — 画像や PDF などのアップロード・生成メディアは専用の保存先にアップロードされ、ID で参照して URL で配信できます。
リクエストごとに読み書きする構造データには、マネージドデータベースを利用してください。
データの置き場所
Section titled “データの置き場所”永続データは Keelson Managed SQLite(libSQL) に置きます。ローカルの /data は揮発(一時領域)で、再起動・再デプロイ・scale-to-zero で失われます。
- アプリデータ(顧客・案件・ログなど) — Managed SQLite(
db.mode: libsql) - アップロードファイル / 生成済みレポート — 現時点では永続化の口はなく、後続のデータファイル SDK で提供予定(
/dataは一時領域なので永続保存には使えない) - 再生成可能なキャッシュ / 一時ファイル —
/tmpまたは/data(どちらも揮発)
/data は永続化に使わない
Section titled “/data は永続化に使わない”/data は揮発(一時領域)で永続化されないため、失って困るものは置かないでください。用途別の置き場所:
- 永続データ(業務データ・DB) — Keelson Managed SQLite(
db.mode: libsql) - アップロード / 巨大なバイナリ — 外部のオブジェクトストレージ(S3 互換サービスなど)へアプリから直接保存
- 一時ファイル — 処理中だけ必要なファイルは
/tmpまたは/data(どちらも揮発)を使い、処理後に削除 - 再生成可能なキャッシュ —
node_modulesやビルド成果物は永続化不要 - 大規模ログ — アプリログは Keelson のログ機能で閲覧できます
Keelson Managed SQLite(推奨)
Section titled “Keelson Managed SQLite(推奨)”新規アプリでは Keelson Managed SQLite の利用を推奨します。プラットフォームがアプリごとに専用のマネージド SQLite(libSQL)データベースを自動でプロビジョニングし、テナント / アプリ単位で DB レベルに分離します。
- セットアップ不要 — 接続情報(
KEELSON_DB_URL/KEELSON_DB_AUTH_TOKEN)が環境変数で自動注入されます。契約・設定は不要で無料枠内で使えます - テナント分離 — 各アプリのクレデンシャルは自分の DB だけにスコープされ、他アプリ / 他テナントの DB には到達できません
- 即時耐久 — 書き込みはプライマリへライトスルーされ、コミット時点で永続化されます(データ損失窓なし)
- 国内配置 — プライマリは東京に配置されます
- 時刻復元(PITR) に対応(保持期間はプラン依存)
libSQL クライアントを利用できる JS/TS・Python アプリでそのまま使えます。利用するには keelson.yaml で db.mode: libsql を明示指定します(db.mode のスキーマ既定は none で、Managed SQLite はオプトインです)。
外部データベースを使う(db.mode: none)
Section titled “外部データベースを使う(db.mode: none)”自動で用意されるデータベースは設定不要・無料枠内で使えますが、Postgres・MySQL・外部の libSQL など自分で契約したデータベースを使いたい場合は keelson.yaml で db.mode: none を指定し、接続情報を secrets として自分で設定します。プラットフォームは外部 DB の接続情報を注入しません(自分で用意した接続情報がそのまま有効になります)。
ファイル SQLite を前提とするフレームワーク(Django 等)を載せる場合も、この外部データベース経路(db.mode: none + 外部 Postgres など)を使います。ファイル SQLite のまま永続化する経路は提供していません。
ファイル SQLite は永続化されません
Section titled “ファイル SQLite は永続化されません”/data に SQLite ファイルを直接置く構成は永続化されません。ファイル SQLite は再起動・scale-to-zero で失われ、デプロイ時に検出して fail-closed で失敗させます。better-sqlite3 や sqlite3 のようなファイル SQLite クライアントを使っているアプリは、libSQL クライアントへ移行して Keelson Managed SQLite(db.mode: libsql) を利用してください。再生成可能な一時 SQLite は db.local_sqlite(/tmp / :memory:)として明示宣言できます。
ファイルアップロードを扱う
Section titled “ファイルアップロードを扱う”アップロードファイルの永続保存の口は現時点では提供していません。 /data は揮発(一時領域)で、再起動・再デプロイ・scale-to-zero で失われるため、アップロードファイルの保存先には使えません。汎用ファイルの永続 I/O は後続のデータファイル SDK で提供予定です。それまでは、外部のオブジェクトストレージ(S3 互換など)へアプリから直接保存する構成を検討してください(Keelson はアウトバウンド接続を許可します)。
バックアップと復元
Section titled “バックアップと復元”日次スナップショット
Section titled “日次スナップショット”Keelson は Managed SQLite(libSQL) のスナップショットを毎日自動で取得します。保持日数はプランによって異なります。
| プラン | スナップショット保持 |
|---|---|
| Starter | 1日分 |
| Plus | 3日分 |
| Team | 7日分 |
| Business | 14日分 |
手動スナップショットは、SQLite 管理画面から任意のタイミングで取得できます(全プラン)。
バックアップ対象
Section titled “バックアップ対象”| 対象 | バックアップされるか |
|---|---|
| Managed SQLite(libSQL)のデータ | される(日次スナップショット + 時刻復元) |
/data 配下のファイル | されない(/data は揮発・永続化されない) |
| アプリのソースコード | されない(デプロイ時に毎回送信される) |
| 環境変数 | されない(ダッシュボードで管理) |
アプリのコードは Git などのバージョン管理で保持し、永続データは Managed SQLite に置いてスナップショットで保護してください。
スナップショットからの復元が必要な場合は、ダッシュボードから操作できます。復元はアプリ単位で行われ、他のアプリのデータには影響しません。
外部データベースや外部ストレージを使うべき場合
Section titled “外部データベースや外部ストレージを使うべき場合”Managed SQLite(libSQL)は多くの社内アプリに十分ですが、以下のケースでは外部サービスの利用を検討してください。
| ケース | 理由 | 選択肢 |
|---|---|---|
| データ量が数 GB を超える | SQLite のパフォーマンスが低下する可能性 | PostgreSQL(アドオンで専用 DB を利用可能) |
| 同時書き込みが非常に多い | SQLite はライター1つの制約がある | PostgreSQL、MySQL |
| BI や基幹系と直接連携する | データを外部システムから参照する必要がある | 共有の PostgreSQL、データウェアハウス |
| 厳密な運用要件がある | ポイントインタイムリカバリや複雑なレプリケーションが必要 | マネージド PostgreSQL |
| 大容量ファイルを大量に扱う | ストレージ容量を超える可能性 | S3 互換オブジェクトストレージ |
よくある設計パターン
Section titled “よくある設計パターン”小規模業務アプリ
Section titled “小規模業務アプリ”顧客管理や在庫管理など。データは Managed SQLite(db.mode: libsql) に保存する。
db: mode: libsqlバッチ処理・日次集計
Section titled “バッチ処理・日次集計”CSV の取込・加工や定期集計を行うアプリ。集計結果は Managed SQLite に保存し、/tmp(揮発)を中間ワークとして使う。永続化したい中間生成物は Managed SQLite か外部オブジェクトストレージに置く。
AI アプリ
Section titled “AI アプリ”社内 RAG や AI チャットのバックエンド。ナレッジのメタデータ・埋め込みは Managed SQLite に保存する。参照ドキュメント等の大きな添付は外部オブジェクトストレージ(S3 互換)へアプリから直接保存する(/data は揮発)。
よくある失敗
Section titled “よくある失敗”ファイルにデータを保存して消える
Section titled “ファイルにデータを保存して消える”ローカルファイル(/tmp・アプリディレクトリ・/data を含む)に書き込んだデータは永続化されず、再起動・再デプロイ・scale-to-zero で失われます。永続化したいデータは Managed SQLite(libSQL) に置いてください。
# NG — ローカルファイルは揮発(/data も含めて永続化されない)db_path = "./data.db"db_path = "/tmp/data.db"db_path = "/data/main.db"
# OK — Managed SQLite(libSQL)に接続するimport libsqlconn = libsql.connect(database=os.environ["KEELSON_DB_URL"], auth_token=os.environ["KEELSON_DB_AUTH_TOKEN"])ファイル SQLite を使う
Section titled “ファイル SQLite を使う”better-sqlite3 / sqlite3 などのファイル SQLite クライアントで /data にファイル DB を作る構成は永続化されず、デプロイ時に検出して失敗します。libSQL クライアントへ移行して Managed SQLite(db.mode: libsql)を使ってください。
バックアップの仕組みを誤解する
Section titled “バックアップの仕組みを誤解する”スナップショットは日次で自動取得されますが、保持日数はプランによって異なります。重要なデータを扱う場合は、プランの保持日数を確認し、必要に応じてアプリ側でもエクスポート機能を用意してください。
/data を肥大化させる
Section titled “/data を肥大化させる”不要になったファイルを削除せずに放置すると、ストレージ容量を圧迫します。ストレージ容量にはスナップショットやログも含まれるため、アプリデータだけで上限いっぱいにならないよう注意してください。
ファイル SQLite をハードコードする
Section titled “ファイル SQLite をハードコードする”sqlite3.connect("/data/main.db") や better-sqlite3 のようにローカルのファイル SQLite を使う構成は、/data が揮発なので永続化されず、デプロイ時に検出して失敗します。libSQL クライアントへ移行してください。
サンプルコード
Section titled “サンプルコード”Python: Managed SQLite(libSQL)に保存する
Section titled “Python: Managed SQLite(libSQL)に保存する”import os, libsql
def get_db(): 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 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """) return conn
conn = get_db()conn.execute("INSERT INTO items (name) VALUES (?)", ("サンプルアイテム",))conn.commit()keelson.yaml:
slug: my-appruntime: python-slimcommand: "pip install --user -r requirements.txt && python app.py"db: mode: libsql # KEELSON_DB_URL / KEELSON_DB_AUTH_TOKEN が注入されるenv: PORT: "8080"Node.js: Managed SQLite(libSQL)に保存する
Section titled “Node.js: Managed SQLite(libSQL)に保存する”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 DATETIME DEFAULT CURRENT_TIMESTAMP )`);await db.execute({ sql: "INSERT INTO items (name) VALUES (?)", args: ["サンプルアイテム"] });Managed SQLite が向いているケース
Section titled “Managed SQLite が向いているケース”- 社内アプリの業務データ — 顧客情報、案件、在庫など、libSQL で十分な規模
- AI で生成したアプリをすぐに動かしたい — 外部 DB の設定なしで
db.mode: libsqlだけで永続 DB が使える - 小さなアプリを複数動かしたい — アプリ / テナントごとに DB が分離されている
Managed SQLite が向いていないケース
Section titled “Managed SQLite が向いていないケース”- データ量が数十 GB を超える — ストレージ容量とパフォーマンスの両面で外部 DB を検討
- 複数システムからの同時アクセスが必要 — Managed SQLite はアプリ内からのアクセスが基本
- ポイントインタイムリカバリが必須 — スナップショットは日次のため、より細かい復元が必要なら外部 DB を検討
- BI ツールや基幹システムとの直接連携 — 外部からクエリできるデータベースが必要
よくある質問
Section titled “よくある質問”ストレージの容量上限はどのくらいですか?
Section titled “ストレージの容量上限はどのくらいですか?”プランによって異なります(Starter: 10 GB 〜 Business: 100 GB)。この容量には Managed SQLite のデータ、スナップショット、アーティファクトの合計が含まれます(ローカル /data は揮発で容量対象外)。追加ストレージはアドオンで購入できます。
再デプロイするとデータは消えますか?
Section titled “再デプロイするとデータは消えますか?”/data に書いたデータは消えます。 /data は揮発(一時領域)で、再起動・再デプロイ・scale-to-zero で失われます。永続データは Keelson Managed SQLite(db.mode: libsql) に置いてください(再デプロイ後も保持され、日次スナップショットの対象です)。
SQLite 以外のデータベースは使えますか?
Section titled “SQLite 以外のデータベースは使えますか?”Keelson Managed SQLite(libSQL)を第一推奨とします。外部の PostgreSQL や MySQL に接続することも可能です(アウトバウンド接続は許可されています)。/data 上のファイル SQLite は永続化されないため、libSQL クライアントへ移行してください。
他のアプリから /data にアクセスできますか?
Section titled “他のアプリから /data にアクセスできますか?”できません。/data はアプリごとに完全に分離されています。アプリ間でデータを共有する必要がある場合は、API 経由でやり取りしてください。
バックアップからの復元にかかる時間はどのくらいですか?
Section titled “バックアップからの復元にかかる時間はどのくらいですか?”データ量によりますが、一般的な社内アプリの規模であれば数分で完了します。
AI への依頼例
Section titled “AI への依頼例”「データベースは Keelson Managed SQLite(libSQL)を使い、
db.mode: libsqlを宣言してください」
「DB 接続は環境変数
KEELSON_DB_URL/KEELSON_DB_AUTH_TOKENから読み取り、libSQL クライアントで接続してください(ファイル SQLite は使わない)」
「アップロードファイルなど永続保存が必要なものは、外部オブジェクトストレージ(S3 互換)へ直接保存してください(
/dataは揮発)」