Skip to Content
IoT アプリ開発ファイルストレージ

ファイルストレージ

すべてのアプリのデータバックエンドは、テーブルと並んでプライベートなオブジェクトストレージを備えています。データバックエンドが時系列の行を保持するのに対し、ファイルストレージは行に収まらないものすべてを保持します:カメラフレーム、PDFレポート、ファームウェアのバイナリ、音声クリップ、エクスポートなどです。

この2つは組み合わせて使うように設計されています。ファイルを保存すると永続的なURLが返され、想定される使い方は、そのURLを同じ流れでテーブルのカラムに書き込むことです — そうすればダッシュボードのウィジェットが追加の作業なしに画像を表示します:

info = await ironflock.files.put("part-1.jpg", jpeg_bytes, content_type="image/jpeg") await ironflock.publish_to_table("inspections", part_id="1", photo_url=info.url)

クライアントAPIの全容 — 読み取り、一覧取得、使用量、共有リンク、ラージオブジェクト、エラーコード — はSDKリファレンスに記載されています。このページはプラットフォーム側を扱います:ストレージがどのように宣言され、管理され、共有され、運用されるかです。

仕組み

  1. 任意で、.ironflock/data-template.ymlfiles:セクションを宣言します。
  2. ユーザーがプロジェクトにアプリをインストールすると、IronFlockはそのアプリ専用のプライベートなストレージ領域をプロビジョニングします — プロジェクトデータベースをプロビジョニングするのとまったく同じようにです。
  3. エッジコードは、SDKのfiles APIを通じてオブジェクトを保存・読み取りします。
  4. アプリをアンインストールすると、そのストレージは完全に削除されます:データベーススキーマが破棄されるのと同様に、すべてのオブジェクトとすべての資格情報が消えます。

データベースと同様に、ストレージはプロジェクトごとです。同じアプリを2つのプロジェクトにインストールすると、完全に分離された2つのストレージ領域が用意され、アプリ開発者であるあなたはそのどちらにもアクセスできません — データは、あなたのアプリを実行しているユーザーのものです。

設定ゼロも有効な設定です:files:セクションを持たないアプリでも、defaultという名前空間が1つ用意されるため、files.put(...)はすべてのアプリで最初から動作します。

データテンプレートでのストレージの宣言

files:セクションは、data-template.yml内でdata:の隣に置きます:

files: description: Camera frames and generated inspection reports. # Storage budget the app SUGGESTS for itself, in bytes (here 5 GiB). # The project user can override it; their setting is what gets enforced. quotaBytes: 5368709120 namespaces: - name: frames description: Raw camera frames, one JPEG per inspected part. contentTypes: ["image/jpeg"] maxObjectBytes: 20971520 retention: { deleteAfter: 30 days } - name: reports description: Generated PDF inspection reports. contentTypes: ["application/pdf"] private: true

名前空間

名前空間は、ポリシーを伴うキーのプレフィックスです。個別のストレージバケットではありません — アプリのすべての名前空間は、そのアプリの単一のストレージ領域の中に存在し、名前空間の名前は単に各オブジェクトのストレージパスの最初のセグメントになります。

この区別が、名前空間をいつ宣言すべきかを教えてくれます:

  • ファイルを整理したいだけ? default名前空間の中で、キーのパス — 2026/03/part-1.jpg — を使ってください。フォルダ形式のキーが通常のケースです。
  • あるオブジェクト群に異なるルールが必要? 名前空間を宣言してください。ルールこそが、名前空間が付け加える唯一のものです。

名前空間が持てるルール:

フィールド意味
name小文字、数字、ハイフンで、先頭は文字。syssystemironflockironflock-*は予約済み
descriptionユーザーに表示され、AIエージェントが読み取れます
private名前空間をクロスアプリアクセスから除外します。デフォルトはfalse(共有) — テーブルとまったく同じです
contentTypes許可されるMIMEタイプ。グロブも可(image/*)。デフォルト:任意
maxObjectBytes単一オブジェクトの最大サイズ。最大5 GiB。デフォルトは100 MiB
retention.deleteAfterこれより古いオブジェクトは自動的に削除されます(30 days2 weeks1 year、…)

ストレージ予算

quotaBytesは名前空間ごとではなく、アプリ全体に対して一度だけ宣言されます。名前空間はキーのプレフィックスにすぎないため、プレフィックスごとの予算を課す対象が存在しません — クォータはアプリの単一のストレージ領域に適用され、オブジェクトストア自身が、直接アップロードを含むすべての書き込み経路でそれを強制します。

2つの数値が存在し、その違いは意図的なものです:

  • 提案クォータ — テンプレートが要求する値です。アプリが最初にインストールされたときに適用されます。
  • 強制クォータ — プロジェクトユーザーが設定した値です。ユーザーがアプリのストレージ設定で予算を変更すると、ユーザーの値が優先され、アプリを再デプロイしてもリセットされません。

テンプレートに何も指定がない場合は、プラットフォームのデフォルトが適用されます(開発バックエンドは1 GiB、本番バックエンドは10 GiB)。

保持期間

名前空間のdeleteAfterの期間を超えたオブジェクトは自動的に削除されます — テーブルのdropAfterポリシーのファイル側の対応物です。保持処理は、オブジェクトストアがサポートしている場合はストア内部で実行され、サポートしていない場合(オンプレミスアプライアンス)は日次のプラットフォームジョブとして実行されるため、宣言された保持期間はどこでも同じように動作します。

永続的なURLとダッシュボード

保存されたすべてのオブジェクトは、https://files.ironflock.com/f/<backend>/<namespace>/<key>という形式の安定したURLを持ちます。3つの特性により、これはテーブルのカラムに書き込むのにふさわしいものになっています:

  • 期限切れになりません。 このURLは純粋なアドレスであり、オブジェクトが存在する限り有効なままです。
  • 公開リンクではありません。 すべてのリクエストは認証プロキシを通過し、リクエスト元がサインイン済みで、かつこのデータバックエンドに対するREAD権限を持っているかどうかが確認されます — これは1つ1つのリクエストごとに再確認されます。ユーザーのアクセスを取り消すと、そのユーザーがすべてのファイルを取得する能力が即座に取り消されます。
  • <img>で表示できます。 ブラウザはセッションクッキーを自動的に送信するため、ダッシュボードのウィジェットは、JavaScriptを一切使わずに、このURLを<img src><video src>、あるいはダウンロードリンクで利用できます。

プロジェクトの外部にいる誰かにファイルを渡す場合は、代わりにSDKのshare_urlが有効期限付きのベアラーリンクを発行します — どちらをいつ使うべきかについてはオブジェクトの共有を参照してください。

ラージファイル

6 MiBまでの転送は、メッセージングシステムを経由する1回の呼び出しとして行われます。それより大きいものは、HTTPSでデバイスとオブジェクトストレージの間で直接転送されます — SDKが自動的に切り替え、ディスクとの間でストリーミングするため、数ギガバイトのファイルであってもメモリに収まる必要はありません。単一アップロードの上限は5 GiBです。

直接転送のパスでは、デバイスがメッセージングルーターだけでなく、オブジェクトストレージのホスト(s3.ironflock.com)にも到達できる必要があります。工場のプロキシがルーターのみを許可している場合、ラージ転送は一般的なエラーではなく明示的なコードPRESIGN_UNREACHABLEで失敗します — また、デバイスのクロックが15分以上ずれている場合はCLOCK_SKEWで失敗しますが、これは資格情報ではなくNTPを確認するよう促すものです。

アプリ間でのファイル共有

クロスアプリのファイルアクセスは、クロスアプリのテーブルアクセスと同じ同意に乗ります。スイッチは1つだけです:プロジェクトユーザーがアプリBにアプリAのデータへのアクセスを許可すると(アプリの設定にあるdata_access同意)、その付与はAのテーブルAの非プライベートなファイル名前空間の両方をカバーします。それを取り消すと、両方が取り消されます。

提供側としてあなたのアプリが制御するのは、名前空間ごとのprivateフラグです:

  • private: false(デフォルト) — データアクセスの付与を持つアプリはそれを読み取れます(書き込むことは決してできません)。
  • private: true — 付与があっても、名前空間は他のアプリから一切見えません。

これは他のアプリのデータの利用とまったく同じです:名前空間とテーブルのデフォルトは同一です。プロジェクトユーザーの付与がなければ何も共有されません — private:は、すでに同意を得た読み手に見える範囲を狭めるだけであり、同意そのものではありません。

ユーザーの視点

プロジェクトユーザーは、2つの場所であなたのアプリのストレージを確認・管理します:

  • データビューは、すべてのアプリのテーブルとビューの隣にファイルの項目を表示します — 保存されたすべてのオブジェクトを、サイズ・種類・更新日とともに検索可能な形で一覧し、ファイルごとにダウンロードできます。
  • アプリのストレージ設定は、使用量(バイト数とオブジェクト数)、アプリの提案の隣に表示される強制予算、予算を変更するためのコントロール、そしてすべてのファイルを削除アクションを表示します — すべてのテーブルを空にする操作のファイル側の対応物です。削除はアプリ名を入力して確認し、元に戻すことはできません。
  • AI アシスタントは、ユーザーに代わってこれらのファイルを一覧表示・検索・読み取りできます。同じ DATABACKEND/READ の権限チェックが適用されるため、ユーザー自身が開けないファイルが現れることはありません。検索対象はファイルパスであって内容ではありませんが、テキストファイル・画像・PDF は読み取れます。アーカイブなどのバイナリ形式は読み取れません。

テーブルと同様に、これはユーザーのデータです:ユーザーは、あなたを介さずにそれを検査し、上限を設定し、削除できます。

直接S3アクセス

SDKの範囲を超えたあらゆる用途 — DuckDBを使うアナリスト、夜間のrcloneバックアップ、BIパイプラインなど — に対して、プロジェクトユーザーはアプリのストレージ設定からアプリごとの読み取り専用S3資格情報を発行できます。

各資格情報は、その1つのアプリのストレージ領域にスコープが限定されます:アプリA向けに発行された資格情報は、構造的にアプリBのファイルには機能しません — Bのストレージポリシーがそれを一切名指ししないからです。1つのプロジェクトは、アプリごとに複数の資格情報を保持できます(利用者ごとに1つ:CIジョブ、バックアップスクリプト、ノートPCなど)。1つを取り消しても、他の資格情報は動作し続けます。これはローテーションの手立てでもあります:キーが漏洩した場合は、2つ目の資格情報を発行し、利用者をそちらに移し、1つ目を取り消します — 他のどの利用者も影響を受けません。

シークレットは、作成時に一度だけ表示されます。発行には、対象アプリのデータバックエンドへの読み取りアクセスが必要です — そもそもファイルを読み取れるようにするのと同じ権限であり、資格情報が誰かの権限範囲を広げることはありません。

# rclone rclone config create myapp s3 provider=Other \ endpoint=https://s3.ironflock.com \ access_key_id=ifs-key-3317-x7k2m secret_access_key=<shown once> rclone ls myapp:if-1042-3317
# DuckDB CREATE SECRET (TYPE S3, KEY_ID 'ifs-key-3317-x7k2m', SECRET '<shown once>', ENDPOINT 's3.ironflock.com'); SELECT * FROM read_parquet('s3://if-1042-3317/exports/*.parquet');

ストレージ設定には、クライアントを向けるべきエンドポイントと正確なバケット名が表示されます。トップレベルのバケットの一覧(引数なしのaws s3 ls)は、設計上何も返さない点に注意してください — この資格情報はバケットを所有しておらず、1つのバケットへのアクセスを付与されているだけです。上記のように、バケットを直接指定してください。

オンプレミスアプライアンス

ファイルストレージはオンプレミスアプライアンスでも同一に動作しますが、アプライアンスの設計に起因する3つの違いがあります:

  • ファイルは、アプライアンス自身のアドレス(/files/...)の下でsame-originとして配信されます — 追加のDNS名も追加の証明書も不要で、プレーンHTTPのインストールでも動作します。永続的なURLと<img src>は、クラウドとまったく同じように振る舞います。
  • アプライアンスのストレージバックエンドは、別のストレージホストへリダイレクトするのではなく、プラットフォームを通じてファイルのダウンロードをストリーミングするため、ストレージサービスが第2のオリジンとして公開されることはありません。
  • アプライアンスでは直接S3資格情報は利用できません — 組み込みのオブジェクトストアは、資格情報ごとのアクセス付与を表現できないためです。そのため、そこではストレージ設定にこのセクションは表示されません。SDKを通じたラージファイルの動作や宣言された保持期間を含め、それ以外はすべて同じように動作します。

エアギャップされたアプライアンスは、すべてのファイルトラフィックをローカルで配信します:アプリのロゴ、ダッシュボードの画像、ファイルのダウンロードに、インターネット接続は不要です。

制限の一覧

制限由来
インライン転送(1回の呼び出し)6 MiB実行時に報告されます。サーバー側で引き上げられる場合があります
単一オブジェクトデフォルト100 MiB、最大5 GiB名前空間ごとのmaxObjectBytes
単一アップロード5 GiBオブジェクトストアの単一PUTの上限。マルチパートはまだ利用できません
ストレージ予算デフォルトで開発1 GiB/本番10 GiBテンプレートが提案し、ユーザーが決定します
キーの長さと文字UTF-8、/区切りのパス../、制御文字、予約済みプレフィックスは拒否されます
Last updated on