旧版: TrueNAS・Dockge・Cloudflare 実運用試験構成仕様
状態: 計画(実運用試験前の承認用)
基準日: 2026年8月31日
対象: TrueNAS SCALE上のDocker、Dockge、Cloudflare Tunnel / Access
重要: この文書の受け入れ条件を満たすまでは、実在する園児・保護者・職員の情報を投入しない。
旧構成案
この文書は8月31日時点の設計履歴です。現在の構成と受入条件は改訂版、導入・更新操作はTrueNAS導入ガイドを参照してください。
1. 目的
open-hoikuictをTrueNAS上で限定公開し、日常業務の流れ、認証、権限、データ永続化、バックアップ、障害時の代替運用を小規模に検証する。
この試験は「完成済み本番システムの導入」ではない。現在のREADMEおよびリリース前チェックリストに残る条件を解消し、施設が本番移行を判断するための段階的なパイロットである。
2. 試験段階
| 段階 | データ | 利用者 | 公開制御 | 次段階へ進む条件 |
|---|---|---|---|---|
| A: 技術試験 | 架空データのみ | 管理者と試験職員2〜5名 | Cloudflare Accessの個別許可 + アプリ認証 | 起動、認証、権限、更新、停止、復元試験に合格 |
| B: 業務試験 | 架空データのみ | 1クラス相当の職員 | 同上 | 2週間以上の業務シナリオと紙運用への切替に合格 |
| C: 限定実データ試験 | 必要最小限 | 承認済み職員・保護者 | Accessまたは承認済みの公開方針 + アプリ認証 | 本文の全ゲート、個人情報取扱承認、復旧試験に合格 |
| D: 本番 | 実データ | 全対象者 | 別途承認 | 本仕様の対象外 |
段階A・Bで実在情報を入力してはならない。段階Cは、ベータ開始時の本番データ移行仕様が実装・リハーサル済みであることを前提とする。
3. ブランチ・リリース方針
ブランチは分ける。ただし、環境ごとに機能コードを複製しない。
main: 共通コードの正本。検証済み変更だけを取り込む。codex/pilot-truenas-dockge: 導入文書、Compose、監視・バックアップ補助など試験固有の短期作業ブランチ。- TrueNASへは作業ツリーを直接コピーせず、承認したコミットを指すタグまたはコミットSHAを展開する。
- デプロイ記録に、Git SHA、イメージIDまたはdigest、Composeのハッシュ、実施者、実施日時を残す。
- DBや
.env、Tunnel token、秘密鍵をブランチ間で管理しない。これらはGit外のTrueNAS datasetへ置く。
現在の作業ツリーには未コミットの機能変更があるため、それらを整理してコミットするまではブランチ切替を行わない。
4. 論理構成
利用端末
-> Cloudflare (TLS / Access policy / edge protection)
-> Cloudflare Tunnel (outbound-only connector)
-> cloudflared container
-> http://app:8000 (専用Docker network内のみ)
-> open-hoikuict container
-> /data/hoikuict.db + /app/storage (TrueNAS runtime dataset)
4.1 境界
- ルーターで80、443、8000番をTrueNASへポート転送しない。
appサービスにComposeのportsを設定しない。expose: 8000だけを使用する。cloudflaredとappだけを専用Docker networkへ参加させる。- Dockge管理画面とTrueNAS管理画面をCloudflare Tunnelの同じ公開hostnameへ載せない。
- Cloudflare Accessは追加の入口制御であり、open-hoikuict自身の職員・保護者認証を置き換えない。
- CloudflareからTunnelまではHTTPS、Tunnelから
appまでは外部から到達できない専用Docker network上のHTTPとする。
Cloudflare Tunnelはorigin側からCloudflareへ外向き接続を確立するため、originに公開IPや受信ポートを設けない構成にできる。Accessを使用する場合は、公開hostnameのTunnel routeを作る前にAccess applicationと許可policyを作成し、意図せず無認証公開される時間を作らない。
5. TrueNASストレージ仕様
<pool>は実環境のpool名に置き換える。
| dataset / path例 | 内容 | SMB共有 | snapshot |
|---|---|---|---|
/mnt/<pool>/apps/dockge/stacks/open-hoikuict-pilot |
compose.yaml、Git checkout |
原則しない | 更新前 |
/mnt/<pool>/apps/open-hoikuict-pilot/runtime |
SQLite DB、施設文例DB、添付、preview | 禁止 | 15分 + 日次 + 更新前 |
/mnt/<pool>/apps/open-hoikuict-pilot/secrets |
.env、Tunnel token、blocklist |
禁止 | 暗号化・限定保管。通常snapshotの扱いを別途承認 |
/mnt/<pool>/backup/open-hoikuict-pilot |
検証済みDB backup | 禁止 | 別poolまたは別装置へ複製 |
- アプリデータはDocker内部の匿名領域だけに置かず、専用runtime datasetへbind mountする。
- runtime dataset内の
dataを/data、storageを/app/storageへmountする。後者にはお知らせ・職員ルーム添付が入る。 - DB本体、
-wal、-shmは常に同じdatasetへ置く。 - datasetはアプリ実行UID/GIDだけが書き込めるようにし、全利用者への書込権限を与えない。
- snapshotはバックアップの一部であり、同一poolだけのsnapshotを唯一のバックアップにしない。RPO/RTO、保持、検査、復元はバックアップ・復元仕様に従う。
- 少なくとも日次で別poolまたは別装置へ複製し、月1回以上、隔離した復元先で復元試験を行う。
- 稼働中SQLiteの単純な
.dbファイルコピーは禁止する。SQLite backup APIを使うか、コンテナを停止してDB関連ファイルを一貫した時点で保全する。
段階Aの開始前は、短時間停止してdataset snapshotを取得する方式でよい。段階Cの前に、停止不要のSQLite backup APIを使う補助コマンドと世代管理を実装する。
6. コンテナ仕様
6.1 アプリ
| 項目 | 値 |
|---|---|
| build | 承認済みGit SHAのDockerfile |
| 実行ユーザー | image内の非root appuser |
| restart | unless-stopped |
| listen | container内 0.0.0.0:8000 |
| host port | なし |
| healthcheck | GET http://127.0.0.1:8000/healthz |
| 永続化 | runtime datasetのdataを/data、storageを/app/storageへbind mount |
| DB | sqlite:////data/hoikuict.db |
/healthzはプロセスの軽量な稼働確認であり、DB読書きや認証を検査しない。別途、ログインとDBを使う外形監視・日次確認を設ける。
6.2 cloudflared
| 項目 | 値 |
|---|---|
| image | Cloudflare公式image。段階C前にdigest固定 |
| 管理方式 | remotely-managed tunnel |
| token | Git外の読取専用file。Compose本文やDockge画面へ直書きしない |
| origin service | http://app:8000 |
| host port | なし |
| network | appと同じ専用network |
6.3 Docker network
専用CIDRを1つ決め、既存Docker network、LAN、VPNと重複しないことを事前確認する。例は172.30.50.0/24とするが、実値は環境調査後に決める。
FORWARDED_ALLOW_IPSにはこの専用CIDRだけを設定し、*は設定しない。appのhost portを閉じることと組み合わせ、専用network内のcloudflaredだけを信頼する。
7. production必須設定
値は.env等のGit管理外ファイルに保存する。秘密値を文書、Issue、チャット、スクリーンショットへ記録しない。
| 設定 | 試験値・条件 |
|---|---|
HOIKUICT_ENV |
production |
HOIKUICT_ENABLE_MOCK_AUTH |
0 |
HOIKUICT_STAFF_AUTH_MODE |
local_password |
HOIKUICT_PARENT_AUTH_MODE |
local_password |
HOIKUICT_SECRET_KEY |
32文字以上の固定ランダム値 |
HOIKUICT_LOGIN_THROTTLE_HMAC_KEY |
32バイト以上の別の固定ランダム値 |
HOIKUICT_COOKIE_SECURE |
1 |
HOIKUICT_CSRF_ENFORCE |
1 |
HOIKUICT_ALLOWED_ORIGINS |
https://<pilot-hostname>のみ |
FORWARDED_ALLOW_IPS |
専用Docker network CIDR。*禁止 |
HOIKUICT_KIOSK_ACCESS_MODE |
初期値disabled。利用時だけtoken |
HOIKUICT_KIOSK_TOKEN |
kiosk=token時に別の固定ランダム値 |
HOIKUICT_PUSH_TRANSPORT |
disabled |
HOIKUICT_PARENT_MAIL_TRANSPORT |
smtp |
HOIKUICT_PARENT_REGISTRATION_BASE_URL |
https://<pilot-hostname> |
HOIKUICT_SMTP_HOST / PORT / STARTTLS |
承認済みSMTP。STARTTLS=1 |
HOIKUICT_SMTP_USERNAME / PASSWORD |
SMTP側が要求する場合に設定 |
HOIKUICT_PARENT_MAIL_FROM |
承認済み送信元 |
HOIKUICT_PASSWORD_BLOCKLIST_PATH |
container内の読取専用blocklist file |
秘密鍵類は用途ごとに別値とし、アプリ再起動のたびに生成し直さない。変更すると既存sessionやtokenへ影響するため、ローテーション手順と実施記録を残す。
8. Cloudflare仕様
8.1 hostname
- 試験専用subdomainを使う。例:
pilot-hoiku.example.jp。 - 本番hostnameと共有しない。
- Full DNS setupの場合、Tunnel route作成時のDNS recordをCloudflareで管理する。
8.2 Access
- 段階A・BはAccess self-hosted public applicationを作成する。
- policyはdeny-by-defaultとし、許可対象を試験参加者の個別メールアドレスまたは承認済みIdP groupへ限定する。
- MFAと短いsession durationを有効にする。
- Tunnel側の
Protect with Accessを有効にし、Access tokenをTunnelで検証する。 - Access通過後も、アプリの個別アカウントで再認証する。
段階Cで保護者が参加する場合、全対象者がAccessを利用できるかを先に確認する。Accessを外す判断は、WAF/rate limit、アプリ認証、監視、インシデント対応を含む別の公開承認とする。
8.3 edge設定
- TLSはCloudflareの現行推奨設定を使用する。
- 管理・認証URLへのrate limitingやbot対策は、正常な保護者・職員操作を妨げない条件で検証する。
- Cache RulesでHTML、認証後画面、個人情報を含むresponseをcacheしない。
- Cloudflare logへquery stringや個人情報を過剰に残さない。
9. 監視とログ
| 対象 | 確認 | 初期頻度 |
|---|---|---|
| app container | health、restart count、例外 | 毎日 + alert |
| cloudflared | connector接続、再接続、認証失敗 | 毎日 + alert |
| 公開URL | Access、アプリlogin、主要画面 | 毎日 |
| storage | dataset使用率、pool状態 | 毎日 + 閾値alert |
| backup | 最終成功日時、世代数、別系統複製 | 毎日 |
| security | login失敗、権限変更、アカウント停止 | 毎日 |
通常ログへ氏名、住所、健康情報、password、session、Tunnel tokenを出さない。ログ閲覧者と保存期間を決める。
10. 更新・ロールバック
- 承認したGit SHAからimageをbuildし、image IDを記録する。
- 検証環境で自動テストとスモークテストを行う。
- app停止またはSQLite backup APIで整合したbackupを作り、TrueNAS snapshotを取得する。
- Dockgeで更新し、health、login、主要画面、DB件数を確認する。
- 失敗時はappを停止し、コードだけでなく、そのコードと対になるDB snapshotへ戻す。
スキーマ変更後に古いimageだけへ戻してはならない。現時点ではAlembicによる正式なmulti-DB migrationがないため、更新前backupと復元リハーサルを必須とする。
11. 受け入れ条件
段階A開始
- 作業ブランチの変更がレビューされ、デプロイ対象Git SHAが固定されている
- 架空データだけを使用することを参加者へ説明した
- appのhost portが公開されていない
- Access policyが個別許可・deny-by-defaultになっている
- production security validationを通過している
- Dockge、TrueNAS管理画面がインターネット公開されていない
- 専用dataset、snapshot、別系統backup先が用意されている
- 紙・電話等の代替運用と連絡責任者が決まっている
段階C開始
- リリース前チェックリストの実運用該当項目がすべて合格している
- 本番データ移行を新規DBでリハーサルし、整合性検査に合格している
- 保護者が他家庭・未紐付け園児を閲覧できないことを直接URLを含め確認した
- 管理者、編集者、閲覧専用、保護者の権限差を確認した
- SMTP、招待、password resetを実機確認した
- backupから隔離datasetへの復元を成功させ、所要時間を記録した
- 更新失敗時にGit SHAとDBを対で戻す試験に成功した
- 個人情報の利用目的、保存期間、削除、漏えい時連絡を承認した
- サポート時間、停止判断者、Cloudflare/TrueNAS障害時の責任分界を決めた
12. 現時点の導入阻害事項
既存のdeploy/dockge/compose.yamlは開発の土台であり、次の理由からそのまま段階Aへ使わない。
portsで8000番をhostへ公開している。cloudflaredが同一stackに定義されていない。- production必須のstaff/parent auth、SMTP、password blocklist設定が不足している。
- named volumeの実体とTrueNAS snapshot/replication対象の対応が運用上明示されず、添付保存先
/app/storageも永続化されていない。 - imageのcommit/digest固定、backup補助、restore検証、監視が未整備である。
- 本番データ移行仕様が計画状態であり、実データ投入の受け入れ条件をまだ満たしていない。
これらは実運用試験手順書に従って段階的に解消する。