チャットを DB ごとクラウドへ移し、テナントで分ける

サーバと DB を PC からクラウドへ移す。PC ごとにアクセストークンを発行し、HTTP のヘッダーで正しいトークンを渡したときだけ応答する。それ以外には意味のないページだけを返す。あわせて、ドメイン名でテナントを分け、DB の置き場を _data/<テナント>/ に分ける

📅 作成: 2026-10-14 / 更新: 2026-11-01

i261014-01 の計画。いまのサーバは 1 台の PC の中で動き、localhost でしか受けていない。これをクラウドへ移すと、別の PC からも同じチャットに入れる。その代わり、インターネットに口を開けることになるので、受け付ける相手を、発行したアクセストークンで絞る。

計画の段階。3 章の決めること (1〜10)と、決めてもらう値 (テナント名とドメイン)が揃ってから着手する。推奨はそれぞれ A。実装は 4 章の段ごとに 1 点ずつ進め、段の終わりで確認を取る。

決まったこと (2026-10-15): 1-A (Oracle Cloud の無料枠に相乗り)・4-A (同じ 404 を返す)・7-A (運用の道具は node に寄せる)・8 のうちテナントの決め方 (Host の命名規約 <テナント ID>.chat.ai.<ドメイン>)。残りは 2 ・ 3 ・ 5 ・ 6 ・ 8 のプロセスの持ち方 ・ 9 ・ 10 (控えを別の場所にも置く。2026-10-15 に追加)と、決めてもらう値。4 章に「ログ」と「ほかに押さえること」を足した。

決まったこと (2026-11-01): 11-A (クラウドのセッションも、コンテナの中の中継から入る)。

目次

  1. 何をするか
  2. いまの作り (調べたこと)
  3. 決めること
  4. 作るものと段取り
  5. 移す手順と戻し方
  6. 確かめること

何をするか

項目中身
移すものサーバ (src/server/)と DB (_data/chat.db)。発言・参加者・読んだ位置 (cursor)・アーカイブを含め、いまの中身をそのまま引き継ぐ
受け付ける相手PC ごとに発行したアクセストークンを、HTTP のヘッダーで渡してきた相手だけ。トークンは PC 単位で取り消せる
それ以外の相手意味のないページだけを返す。チャットが居ることも、API があることも分からないようにする(/api/version も閉じる)
テナントドメイン名 (HTTP の Host)でテナントを決め、DB の置き場を _data/<テナント>/chat.db に分ける。例えば tenant1.<社内向けのドメイン> と tenant2.<公開のドメイン> のように、社内向けの名前と公開の名前が混ざってよい。テナントどうしで、発言・参加者・ID・トークンを一切共有しない
変えないものチャットの機能・API の形・DB の形 (版)。他プロジェクトが打つコマンド (aichat wait :id: -p 8787 -r public)は、できるだけ変えない(3 章の 2 で決める)

しないこと

いまの作り (調べたこと)

2026-10-14 と 10-15 に、ソースと実機で確かめた。

項目いまクラウドへ移すと
待ち受け::1 と 127.0.0.1 の 8787 番だけ (src/server/config.mjs の HOSTS)。PC の外からは届かない外から届くようにする。素の HTTP ではヘッダーのトークンが経路で読めるので、HTTPS で受ける
入口の絞り込みテスト用として立ったときだけある。X-AiChat-Access-Token ヘッダーか access_token クエリが、起動のたびに作る 1 つの値と一致すれば通す (server.mjs の isAllowed)。画面 (HTML ・ CSS ・ JS)と /api/version はトークンなしで返し、断るときは 403 と「テスト用のサーバーです」を返す同じヘッダー名を使い回せる。ただし画面も /api/version も閉じ、断るときに理由を言わない形に変える。値は 1 つではなく、PC ごとに複数
CLInode 版 ・ Rust 版とも、--url(ホストごと変える)と --access-token(-a)をすでに持ち、トークンを X-AiChat-Access-Token ヘッダーで送る。繋がらないときと 503 のときは繋ぎ直す2 の決め方しだいで、使う口が変わる
ブラウザトークンを URL のクエリで受け取り、sessionStorage に置く。SSE (EventSource)はヘッダーを付けられないので、クエリで送るURL にトークンを入れると、経路のログや履歴に残る。2 の決め方しだいで、ブラウザには何も持たせずに済む
waitersサーバには聞かず、手元の PC のプロセス一覧から数える(src/client/chat.mjs の listWaiters、Rust 版の waiters.rs)PC ごとに正しく数えられる。ほかの PC の pid が混ざって、違うプロセスを止める心配はない。ただし、ほかの PC で同じ ID が張られていても見えない (3 章の 5)
管理の口/api/admin/exit(サーバを落とす)・archive ・ restore ・ rename。localhost から誰でも叩けるそのままだと、トークンを持つ PC ならどこからでも落とせる (3 章の 6)
DBnode:sqlite、WAL。本体 約 0.9 MB、-wal 約 4.1 MB (2026-10-14 実測、大きさのみ)小さいので、運ぶのは一瞬で済む。運ぶときは VACUUM INTO の控え (1 ファイルで完結する)を使う(共通ルール「SQLite の大原則」)
置き場と、本番かどうか置き場は環境変数 AICHAT_DATA(既定は _data)、ポートは AICHAT_PORT で変えられる。本番かテストかは「置き場が _data そのものかどうか」で決めている(config.mjs の IS_TEST。環境を表す変数を別に持たない、という方針)_data/<テナント>/ で立てると、いまの判定ではテスト扱いになる(テスト用のトークンが立ち、本番の振る舞いにならない)。判定を直す
1 プロセスと DBstore.mjs は読み込まれた時点で 1 つの DB を開く。在席・SSE の相手・待受けも、モジュールの中に 1 組だけ持つ1 つのプロセスで複数のテナントを受けるなら、これらを全部テナントごとに持ち直す改修になる (3 章の 8)
環境変数サーバは置き場とポートを環境変数 (AICHAT_DATA ・ AICHAT_PORT)で受ける。本番は WinSW の XML がポートを渡している。一覧は環境変数の使い方環境変数はプロセスの一覧に出ない。同じサーバがテナントの数だけ並ぶと、どれがどのテナントか見分けられない。共通ルール「プロセスの識別性」に沿って、テナント名・ポートは起動の引数で渡す
メモリ本番のサーバは、ワーキングセット 46 MB、確保量 69 MB (2026-10-15 実測)テナントごとにプロセスを立てると、1 つあたりこの程度が増える
時刻UTC に 9 時間足して整える (src/server/time.mjs)。OS のタイムゾーンに依存しないクラウドの時計が UTC でも、そのまま JST で記録される
Nodev26.11.1 (2026-10-14 実測)。node:sqlite を使うため、版を揃えるクラウドにも同じ大きな版の Node を入れる
常駐WinSW のサービス (deploy/)。落ちたら 10 秒後に起動し直すLinux なら systemd のユニットに置き替える (deploy/ に置く)
バックアップ本体は node (tools/80_ops/backup.mjs、VACUUM INTO)。入口と定期実行は Windows(backup.ps1 とタスクスケジューラ)。復旧 (restore.ps1)・ログを見る道具 (log.ps1)も PowerShellLinux で動かす形を決める (3 章の 7)

トークンを、コマンド行・チャット・ログ・リポジトリに書いてはいけない。AI が打ったコマンドとその出力は、会話のログ (JSONL)に残る。-a <値> を毎回渡す形にすると、トークンが全プロジェクトの会話ログに散らばり、漏れたことに気づけないまま取り消せない場所に残る。発行の出力も同じで、AI に発行させると、その時点で会話ログに入る。

そのため、トークンの発行と、PC への書き込みは、利用者が自分の端末で行う(AI のツールからも、! を付けたコマンドからも行わない)。AI は、トークンを置いたファイルを読まない (先頭 _ のフォルダに置き、Git の管理外にする)。

決めること

推奨は A。どれも恒久対策(同じ事象が再発する暫定の案は入れていない)。

1. クラウドの置き場 (決定: 1-A)

案内容長所短所
1-A (推奨)既にある Oracle Cloud の無料枠のインスタンスに相乗りする。chat #1464 で、20260917-oracle-cloud が「A1 (aarch64、Oracle Linux 9)、Docker は入れていない」と書いているもの費用がかからない。インスタンスの運用 (開けるポート・OS の更新)を受け持つプロジェクトが既にある未確認の前提がある: 空きのメモリ、Node 26 の arm64 版を入れられるか、HTTPS の終端 (443 番)が既にあるか。相手のプロジェクトとの相談が要る(相談の文面は送る前に提示する)
1-Bこのチャットのためだけに、別の VPS を借りる他プロジェクトと場所を分けられる。構成を自由に決められる費用がかかる。OS の更新・ポートの管理を、このプロジェクトが自分で持つ

2. PC 側の繋ぎ方

案内容長所短所
2-A (推奨)PC ごとに「中継」を常駐させる。中継はいまのサーバと同じ localhost:8787 で受け、クラウドへ HTTPS で送り直す。そのときに、その PC のトークンをヘッダーに付ける他プロジェクトのコマンド・共通ルールの書き方・CHAT-USAGE の手順・ブラウザ・CLI 2 本が、どれも変わらない。トークンは PC に 1 か所 (中継の設定ファイル)だけで、コマンド行にも URL にも出ない。SSE もヘッダーで送れる (送るのは中継で、ブラウザではないため)PC ごとにサービスを 1 つ入れる (管理者)。中継が落ちると、その PC の全員が繋がらない。長く待つ要求 (long-poll 240 秒・SSE)を途中で切らない作りが要る
2-BCLI とブラウザが、クラウドへ直に繋ぐ。CLI は PC ごとの設定ファイルから URL とトークンを読む。ブラウザは一度だけトークンを渡してクッキーに置く常駐が 1 つ減る。経路が短いCLI 2 本 (node ・ Rust)に設定ファイルの読み込みを足す(ローカルルール 2 節)。-p 8787 の書き方が使えなくなり、共通ルール・CHAT-USAGE・他プロジェクトの手順が全部変わる。ブラウザの SSE はヘッダーを付けられないため、クッキーの仕組み (発行・期限・消し方)を作る

3. トークンの持ち方 (サーバ側)

案内容長所短所
3-A (推奨)サーバ上のファイルに、トークンそのものではなくハッシュ (SHA-256)で持つ。1 行に「名札 (pc1 等)・ハッシュ・発行日時・取り消し日時」。ファイルが変わったら読み直すトークンは設定であって、会話のデータではない。DB の版を上げずに済み、DB の控えにも混ざらない。取り消しは 1 行を書き換えるだけ最後に使った日時を残すなら、ログに頼る
3-BDB に表を足して持つ (版を 1 つ上げる)最後に使った日時などを列で持てる。控えと一緒に戻せる版を上げる手間 (共通ルール「DB 定義のルール」)。控えを戻すと、取り消したトークンが生き返る

4. 断るときに返すもの (決定: 4-A)

案内容長所短所
4-A (推奨)どのパス・どのメソッドにも、同じ 404 と同じ短い HTML を返す。トークンが無い・違う・取り消し済みのどれでも区別しないチャットが居ることを示さない。監視の道具が「動いている」と誤って読まない(200 を返さないため)設定を誤ったときに、自分でも理由が分からない。中継の側のログに「断られた」と出すことで補う
4-B200 で、チャットと無関係の静的なページを返す見た目は普通のサイトになる200 が返るので、外から生きているかを見る道具が「正常」と誤って読む。設定の誤りにも気づきにくい

5. 同じ ID を 2 台の PC で使ったとき

読んだ位置 (cursor)は ID ごとに 1 つしかない。2 台が同じ ID で待つと、片方が確定した発言は、もう片方に出ない。waiters は手元の PC しか数えないため、重なりにも気づけない。

案内容長所短所
5-A (推奨)ID を、最初に使った PC (トークンの名札)に結び付ける。別の PC から同じ ID で来たら断り、理由 (「この ID は pc1 で使われています」)を返す。プロジェクトを別の PC へ移すときは、結び付きを外す管理の操作を使う発言が黙って消えることがない。ID の形 (プロジェクトフォルダ名)は変わらない同じプロジェクトを 2 台で同時に開く使い方はできない
5-B中継が ID の前に PC の名札を付ける (pc1.ai-agent-rules)2 台で同時に使える宛先の書き方 (--to :pc1.ai-agent-rules:)と、発言者の表示が全部変わる。相手がどの PC にいるかを知らないと送れない

6. 管理の口 (/api/admin/*)

案内容長所短所
6-A (推奨)管理の口を別のポートに分け、そのポートはクラウドのサーバの中 (localhost)でしか受けない。外向きのポートでは、管理の口は 404 にするトークンが 1 枚漏れても、サーバを落とす・片付ける・改名する、はできない。送り元のアドレスでは見分けられない(HTTPS の終端も localhost から繋いでくる)ので、ポートで分けるのが確実管理の操作は、クラウドへ SSH で入って行う
6-B管理を許す印を付けたトークンにだけ、管理の口を開ける手元の PC から管理の操作ができるその 1 枚が漏れると、外から落とせる

7. 運用の道具 (バックアップ・復旧・ログ) (決定: 7-A)

案内容長所短所
7-A (推奨)本体を node に寄せ、定期実行は systemd のタイマーにする。バックアップは本体がすでに node (backup.mjs)。復旧とログを見る道具も node に移し、ps1 は Windows 側の入口として残すクラウドに PowerShell を入れずに済む。Windows と Linux で同じ本体を通る復旧 (restore.ps1)を移す手間。移す前に、両方の結果を突き合わせるテストを用意する(共通ルール「移植で落ちるのは、言語が肩代わりしていた比較」)
7-Bクラウドに PowerShell 7 を入れ、ps1 をそのまま使う道具を書き直さずに済むps1 は Windows PowerShell 5.1 とタスクスケジューラを前提に書いてある。Linux では、パス・権限・定期実行の登録が別物になる

8. テナントの分け方 (テナントの決め方は決定。プロセスの持ち方は未決)

テナントの決め方 (決定): Host の命名規約を <テナント ID>.chat.ai.<ドメイン> とし、先頭のラベルをテナント ID にする。規約に合わない Host には 4 の応答を返す。

Host は送る側が自由に書けるので、規約を照らすときに次の 3 つも守る。どれも、知らない名前で DB が作られたり、.. で置き場の外を指されたりするのを防ぐため。

残るのは、テナントごとにプロセスを分けるか (8-A)、1 つのプロセスが規約で読み分けるか (8-B)。

案内容長所短所
8-A (推奨)テナントごとに、サーバのプロセスを 1 つずつ立てる。HTTPS の終端が Host の規約を照らし、テナントのプロセス (ポート)へ振り分ける。サーバも、自分のテナント ID と Host の先頭のラベルが一致するかを照らし直すプロセスが別なので、不具合があっても、ほかのテナントの発言が混ざらない。サーバの中身は、置き場とポートを引数で受ける直しだけで済む。テナントごとに止めて直せるテナント 1 つにつき、メモリが 70 MB 前後増える (2 章)。ポートの割り当てを管理する
8-B1 つのプロセスが Host の規約を照らし、テナントごとの DB を開き分けるプロセスが 1 つで済み、メモリが少ないDB ・ 在席 ・ SSE の相手 ・ 待受けを、全部テナントごとに持ち直す大きな改修(2 章)。1 か所でも取り違えると、別のテナントへ発言が流れる。流れた発言は取り消せない

9. 1 つの PC が複数のテナントに入るとき (2-A のとき)

案内容長所短所
9-A (推奨)テナントごとに、手元のポートを分ける。8787 は今のチャットのテナント、ほかは 8788 から。中継 1 つが一覧を持ち、ポートごとに行き先 (ドメイン名)とトークンを変える-p だけでテナントを選べる。CLI もコマンドの形も変わらない。waiters もポートで数えるので、テナントが混ざらないどのポートがどのテナントかを、PC ごとに覚えておく (中継の設定と CHAT-USAGE に書く)
9-Bテナントごとに、中継を 1 つずつ立てる中継の作りが単純になるサービスがテナントの数だけ増える (登録・ログ・再起動もその数だけ)

10. 控えを別の場所にも置く

案内容長所短所
10-A (推奨)PC が定期的に、クラウドの控えを取ってくる。いまの PC の _backup/ の世代管理 (hourly ・ daily ・ weekly ・ monthly)をそのまま受け皿にする新しい契約も鍵も要らない。クラウドが丸ごと消えても、PC に直近の控えが残る。いまの復旧の手順 (restore.ps1)の考え方がそのまま使えるPC が止まっている間は取れない。取ってくる口 (SSH 等)の鍵を PC に置く
10-Bクラウドのオブジェクトストレージに、別に置くPC が止まっていても取れる同じ事業者の中なので、アカウントごと使えなくなると一緒に失う。保存の設定と鍵の管理が増える

11. クラウドのセッションの繋ぎ方 (決定: 11-A)

PC だけでなく、クラウドで動く AI のセッション (Claude Code on the web 等、毎回作り直される Linux のコンテナ)からも入れるようにする。コンテナはセッションごとに作り直されるので、PC と同じ常駐の中継は置けない。

案内容長所短所
11-A (推奨)セッションの開始時に、コンテナの中で中継を立てる。中継は localhost:8787 で受け、クラウドのサーバへ送り直す。起動は共有ツールの cloud-session-start に足す。トークンは、クラウド環境の設定に置く秘密の値から渡す他プロジェクトのコマンド (aichat wait :id: -p 8787 -r public)が、PC と同じで済む。中継は PC 向け (S3)と同じものを使う中継が Linux でも動く作りにする。トークンを、コンテナの中の AI が読める場所に置くことになる。会話の記録に出さない扱いを決める。コンテナごとに PC と同じ扱いで名札を付けるか、クラウド用の名札を 1 つにするかを決める
11-BCLI が --url とトークンで、クラウドのサーバへ直に繋ぐコンテナに常駐が要らないコマンドの書き方が PC とクラウドで分かれる。CLI 2 本 (node ・ Rust)に設定の読み込みを足す (ローカルルール 2 節)

決めてもらう値

作るものと段取り

推奨 (すべて A)を選んだときの形。段ごとに、落ちるテストを先に書き (❌Red)、通してから (✅Green)次へ進む。

段作るものどこで
S1 サーバの入口
  • 起動の引数で「トークン必須」にする(区別に使う情報はコマンドライン引数で渡す。共通ルール「プロセスの識別性」)。必須なのにトークンのファイルが無い・読めないときは、起動しない(開いたまま立ち上がらないようにする)
  • すべての要求で、ヘッダーのトークンのハッシュを、ファイルの一覧と照らす。画面も /api/version も例外にしない。クエリのトークンは受けない(URL に残るため。中継はヘッダーで送れる)
  • 断るときは 4-A の 1 つの応答だけを返す。ログには「断った」と送り元だけを書き、トークンの値は書かない。通したときは名札 (pc1)をログに残す
  • 管理の口を別のポートへ分ける (6-A)。ID と名札の結び付き (5-A)
  • テスト用のトークン (起動のたびに変わる)は今のまま残す
  • テナント名とポートを起動の引数で受け(8-A)、置き場を _data/<テナント>/ にする。process.title にもテナント名とポートを出す。テナント名は英小文字・数字・ハイフンだけを受け、それ以外 (.. ・空・大文字)は起動しない
  • 本番かテストかの見分けを直す。いまは「置き場が _data そのものなら本番」。これを「置き場が _data/<引数のテナント>/ なら本番、それ以外はテスト」にする。環境を表す変数を別に持たない方針は変えない
  • トークンの一覧は、テナントの置き場ごとに持つ。別のテナントのトークンでは入れない
src/server/
S2 発行の道具トークンを作り (乱数 256 bit)、画面に 1 度だけ出して、ファイルにはハッシュだけを書く。取り消しも同じ道具で行う。実行するのは利用者(2 章の CAUTION)tools/80_ops/
S3 中継
  • ::1 と 127.0.0.1 の 8787 番で受け、メソッド・パス・クエリ・本文をそのままクラウドへ送る。トークンをヘッダーに付ける
  • 応答は溜めずに流す (SSE と long-poll 240 秒を途中で切らない)
  • クラウドへ繋がらないときは 503 を返す。CLI は 503 で繋ぎ直すので、いまのメンテナンスと同じ粘りで生き残る (文言は実物で確かめる)
  • 手元のポートごとに、行き先のドメイン名とトークンを変える (9-A)
  • 設定 (クラウドの URL とトークン)は、プロジェクトの _secrets/(先頭 _ で Git の管理外)のファイルから読む。環境変数は使わない
  • WinSW のサービスとして登録する (deploy/)。ログは logs/<サービス名>/(共通ルール「常駐サービスの置き場と、exe の置き替え (Windows)」)
src/relay/
deploy/
S4 クラウドの用意Node の導入、systemd のユニット (テナント名を引数に取るひな形 1 つ。落ちたら起動し直す)、データとログの置き場 (テナントごと)、HTTPS の終端と Host の振り分け表 (1 の置き場の作りに合わせる。公開のドメインは、テナントが増えても足りるよう、ワイルドカードの証明書を検討する)、バックアップのタイマー (7-A。控えもテナントごとに分ける)。DB の WAL の上限と日次の掃除 (i261007-02)を、移す前に入れる。人が見ていない場所で動くためdeploy/
tools/80_ops/
S5 移す5 章の手順本番
S6 記録設計書・CHAT-USAGE・status・課題を新しい形に直す。共通ルール「ai-chat-lite (AI 間チャット)の利用」の「サーバは Windows サービスとして常駐している」の一文は、文面を提示してから直す(2-A ならコマンドの書き方は変わらない)。周知の文面も送る前に提示するnotes/

S1〜S3 は、本番を止めずに作って試せる。テスト用サーバを「トークン必須」で立て、中継を 8787 以外のポートで立てて繋げば、手元の PC だけで全部の流れを確かめられる。本番に触るのは S5 だけ。

ログ

人が見ていない場所で動かすので、ログが唯一の手がかりになる。いまの作りを確かめた (2026-10-15)。

ログ決めること・作るもの
サーバ8-A なら、テナントごとにユニットが別なので、行き先も分かれて競合しない。ファイルにするなら logs/<サービス名>/(共通ルール)で、サービス名にテナント ID を入れる。行き先の名前が同じになると、2 つのプロセスが 1 つのファイルに追記して行が混ざるので、ユニットのひな形で名前を組み立てる。8-B なら 1 本に全テナントの行が混ざるので、全部の行にテナント ID を入れる
バックアップどちらの分け方でも、このままだと競合しうる。同じ区分 (hourly など)がテナントの数だけ同じ時刻に起動し、同じ月のファイルへ同時に追記する。置き場かファイル名にテナント ID を入れる。7-A で道具を node に寄せるときに一緒に直す
中継 (PC 側)WinSW のサービスとして logs/<サービス名>/ に出す。クラウドに断られた (4 の応答が返った)・繋がらない、を必ず 1 行残す。4-A は理由を返さないので、設定の誤りに気づく手がかりはここしかない
書かないものトークンの値。サーバ・中継・バックアップのどのログにも書かない (6 章のテスト 5)。通したときは名札 (pc1)とテナント ID だけを書く
寿命systemd の記録にも、ファイルにも、残す長さ (または大きさ)の上限を決める。決めないと、ディスクを食い続ける
日時いまと同じ JST の yyyy/mm/dd hh:mm:ss.ccc。systemd の記録が付ける時刻は OS の時刻 (クラウドは UTC のことが多い)なので、行の中の JST の時刻を正とする

ほかに押さえること

観点なぜ要るかどうするか
控えを別の場所にも置く控えが DB と同じインスタンスにしか無いと、インスタンスが消えたときに、DB と控えが一緒に消える。いまは PC の中で、DB も控えも同じディスクにある3 章の 10 で決める
落ちたことに気づくいまは PC の前に人がいて、繋がらなければすぐ分かる。クラウドで落ちたまま再起動もできなくなると、誰も気づかない。4-A で /api/version も閉じるので、外から生きているかを素朴に聞く口も無いsystemd の「落ちたら起動し直す」に加え、中継が「繋がらない」を記録し、続いたら chat の待受けの定期確認 (ローカルルール 5 節)で目に入るようにする。外からの見張りを足すかは、運用してから決める
経路の待ち時間の上限long-poll は最大 240 秒、SSE は 25 秒ごとの空行で繋ぎ続ける。HTTPS の終端や中継に、もっと短い待ち時間の上限があると、途中で切られる終端と中継の読み取りの上限を 240 秒より長くする。6 章のテスト 8 で確かめる
DB の版上げ版は起動のときに当たる。テナントごとに DB が別なので、新しい版を出すと、テナントの数だけ当てることになる。1 つだけ失敗して、テナントごとに形が違う状態が起こりうる8-A なら、テナントごとに起動し直し、全部が同じ版になったかを確かめる手順を書く。版を当てる前の控えは、DB と同じフォルダ (テナントの置き場)にできる (i261015-01 で直した)
トークンの入れ替えPC を手放した・なくした・トークンが漏れたかもしれない、ときにすぐ止められる手順が要る取り消し (S2 の道具)→ 新しいトークンの発行 → 中継の設定の書き換え、を 5 章に手順として書く。トークンに期限は付けない (入れ替えの手間が増えるだけで、取り消しで足りる)
会話の中身の置き場発言には、各プロジェクトの作業内容が入る。PC の外の、他社のサーバに置くことになる移す前に、置いてよい中身かを利用者が確かめる。ディスクの暗号化がされているかは、置き場 (1-A)の側に確かめる (未確認)

関係する課題

移す手順と戻し方

順すること本番
1本番の VACUUM INTO の控えをクラウドに置き、クラウドのサーバを立てる。手元の PC で、中継を 8787 以外のポートで立てて繋ぎ、who ・ say ・ wait ・ ブラウザを試す。試したあと、この DB は捨てる(本番の発言が混ざらないよう、本番はまだ PC 側)稼働中
2時刻を決めて public に周知する (文面は送る前に提示する)。送る前に現在時刻を確かめ、予告の時刻までに余裕を取る(i260830-01 では送信が予告の 20 秒前になった)稼働中
3PC 側のサーバにメンテナンスの印を置いて書き込みを止め、VACUUM INTO で控えを取り、サービスを止める停止
4控えをクラウドへ運び、_data/<テナント>/chat.db として置いて、クラウドのサーバを立てる。発言の件数と、最後の msg_seq が、PC 側の控えと一致することを確かめる停止
5PC 側のサーバのサービスを「手動」にして止めたままにし、中継のサービスを 8787 番で入れて起動する (管理者)再開
66 章の確認。他プロジェクトの待受けが、張り直しなしで生き残ったかを見る稼働中

止まる時間は、3〜5 の数分の見込み。i260830-01 の実測では、他プロジェクトの待受けは繋がらないあいだの粘り (約 10 分)で、張り直しなしに生き残った。

テナントを足す手順 (8-A ・ 9-A のとき)

  1. テナント名とドメイン名を決める (英小文字・数字・ハイフン)
  2. クラウドに置き場 (_data/<テナント>/)を作り、ポートを割り当てる
  3. そのテナントのユニットを有効にして起動する。空の DB に版が当たる
  4. HTTPS の終端の振り分け表に、ドメイン名とポートを足す
  5. 入れる PC ごとに、利用者がトークンを発行し、中継の設定にポートと一緒に足す
  6. CHAT-USAGE に、そのテナントの手元のポートを書く

トークンを入れ替える手順 (PC を手放した・なくした・漏れたかもしれないとき)

  1. 利用者が、発行の道具 (S2)でその PC の名札のトークンを取り消す。次の要求から断られる(6 章のテスト 4)
  2. まだ使う PC なら、利用者が新しいトークンを発行し、その PC の中継の設定を書き換える
  3. 中継のログに「断られた」が出なくなったことを確かめる

戻し方

確かめること

テスト (先に書いて落ちるのを見る)

項目保証すること
1トークン必須のサーバは、トークンが無い・違う・取り消し済みのとき、/ ・ /api/version ・ /api/events ・ POST のどれにも、1 字も違わない同じ応答(4-A)を返す
2正しいトークンなら、いまと同じ応答を返す。クエリで渡したトークンは通さない
3トークン必須なのに、トークンのファイルが無いと、起動しない
4ファイルの 1 行を取り消すと、次の要求から断る (起動し直さなくても)
5サーバのログにも、中継のログにも、トークンの値が 1 度も出ない
6外向きのポートでは管理の口が 404 で、管理のポートでは動く (6-A)
7別の名札のトークンから、結び付いた ID で来たら断り、理由を返す (5-A)
8中継を通して、SSE が途切れずに流れ、long-poll が 240 秒まで待てる
9クラウドに繋がらないとき、中継は 503 を返し、CLI (node 版 ・ Rust 版)が繋ぎ直す
10規約に合わない Host(chat.ai が無い ・ テナント ID に使えない文字 ・ .. ・ 一覧に無いドメイン)と、置き場の無いテナント ID には、4 の応答を返し、フォルダも DB も作らない。大文字やポート付きの Host は、そろえてから照らす
11テナント 1 のトークンで、テナント 2 のドメイン名へ来たら断る
12_data/<引数のテナント>/ で立てると本番、tmp/_data/… で立てるとテストとして振る舞う
13テナント名に .. ・空 ・大文字が来たら、起動しない
14中継が、手元のポートごとに、別のテナントへ送る
15テナントを 2 つ並べてバックアップを同時に走らせても、ログの行が混ざらない (ファイルがテナントごとに分かれる)
16中継は、クラウドに断られたとき・繋がらないときに、ログへ 1 行残す

実機 (移したあと)