サービス依存関係は、どのサービスが存在しなければならず、どのサービスが利用可能でなければならず、どのサービスが並行して起動できるかを定義することでホームサーバーの起動順序を形作ります。その結果は単純な番号付きリストではなく依存関係グラフです。
メディアアプリはリクエストを処理する前にマウントされたファイルシステム、ネットワークアクセス、DNS、データベース、キャッシュを必要とするかもしれません。プロセスを早く起動してもそれらの前提条件が準備完了になるわけではなく、すべてのサービスを待ちすぎると起動が遅くなり、オプションのコンポーネントが致命的な障害点になることもあります。
依存関係グラフは単純な起動リストにどう取って代わるのか?
実際のホームサーバースタックは共有の前提条件と分岐関係を含みます。依存関係マップは共有の前提条件を明らかにし、データベースが複数のアプリにサービスを提供し、1つのリバースプロキシが複数のバックエンドに依存していることを示します。
「ストレージが最初、データベースが2番目、アプリが3番目」というリストはそうした枝を隠します。あるサービスはストレージを必要としますがデータベースは不要であり、別のサービスはネットワークを必要としますがリモート接続が完全に利用可能になる前に起動できます。
グラフはどのユニットが起動トランザクションに引き込まれ、どの障害が依存先をブロックし、どの無関係な枝が同時に進行できるかを決定します。
なぜ依存関係と順序付けは異なるルールなのか?
依存関係は別のユニットを含めるべきか必須として扱うかを答え、順序付けはどちらが先に起動するかを答えます。依存関係と順序付けはWants、Requires、After、Before、BindsToなどの関係を通じて別の関係です。
ネットワークの後にサービスを順序付けても、ネットワークユニットが起動するとは限りません。データベースを要求しても、そのプロセスが最初に現れた時点でデータベースがクエリを受け付けられるとは自動的に証明されません。
誤った意味論を組み合わせると脆弱な起動が生まれます。オプションのサービスが必須になったり、障害が過度に伝播したり、明示的な順序なしに要件が宣言されてユニットが同時に起動したりします。
なぜ開始されたプロセスが必ずしも準備完了のサービスとは限らないのか?
コンテナランタイムはプロセスが実行中であると報告しても、アプリケーションがまだデータベースの移行、インデックスの読み込み、キーの作成、ソケットのオープンを行っている場合があります。実行中のコンテナが準備完了とは限りません。
ポートオープンのチェックも浅すぎることがあります。データベースは必要なスキーマが存在する前にTCP接続を受け入れることがあり、ウェブアプリはストレージマウントや下流APIが利用できない間もヘルスエンドポイントに応答することがあります。
準備完了は依存するサービスが実際に必要とする最小限の機能をテストすべきです。生存性はプロセスを再起動すべきかどうかを問いますが、起動と準備完了は下流の作業を開始すべきか、トラフィックを受け入れるべきかを問います。
マウント、ネットワーク、データベースはどのように起動チェーンを形成しますか?
典型的なチェーンはストレージデバイス → ファイルシステムのマウント → データベース → アプリケーション → リバースプロキシです。マウントの準備完了は依存するアプリの起動に先行しなければなりません。なぜなら、期待されるマウントがない場合、アプリケーションは空のローカルディレクトリを作成してしまう可能性があるからです。
ネットワーク依存関係にも同様の層があります。インターフェースはアドレス、ルート、DNSリゾルバー、VPN、またはリモートNASが使用可能になる前に設定されることがあります。一般的なネットワークターゲットはサービスが必要とする正確な機能を表していないかもしれません。
最も安全な依存関係は実際の前提条件に近いものです。マウントパスを要求し、データベース操作をテストし、起動後に推定秒数だけ待つのではなくリモート接続を再試行してください。
並列起動とサイクルは起動動作にどのような影響を与えますか?
依存関係を認識したサービスマネージャーは、独立したブランチを同時に起動できます。依存関係制御によりより多くの並列起動が可能となり、すべてのユニットを1つのグローバルなシーケンスで強制するよりも起動時間が短縮されます。
並列処理はまた、欠落した前提条件を露呈します。ある起動時に好ましい順序で起動した2つのサービスが、ソフトウェアの更新、より高速なディスク、または異なるネットワークタイミングの後に競合することがあります。
グラフが不可能な順序を要求するとサイクルが発生します。例えば、Aの後にB、Bの後にC、そしてCの後にAという順序です。マネージャーはトランザクションの一部を拒否または破棄しなければならず、起動競合を修正するために追加された依存関係が別のサービスの起動を妨げることがあります。
起動後に依存関係が堅牢である理由は何ですか?
起動順序は最初の遷移を処理しますが、マウントの解除、データベースの再起動、ネットワークルートの変更などで依存関係は後で消えることがあります。制限された再試行は一時的な依存関係の障害から回復し、ホームサーバー全体の再起動を必要としません。
アプリケーションはバックオフを伴う再接続を行い、準備状態の変化を公開し、安全でない作業の受け入れを停止し、依存関係が戻ったときに回復すべきです。再起動ポリシーには制限が必要で、1つの利用不可なデータベースが急速なクラッシュループを引き起こさないようにします。
厳格な起動依存関係は狭く扱い、ランタイム依存関係は中断に対応するよう設計してください。堅牢なホームサーバーは単に一度正しく起動するだけでなく、通常のメンテナンスや部分的な障害後に再び使用可能な状態に収束します。
| 関係 | 答える質問 | 誤用時の障害 |
|---|---|---|
| 要件 | この依存関係は含めるべきか、必須として扱うべきか? | オプションサービスがスタック全体をブロックする |
| 順序付け | どのユニットが先に開始しますか? | 競合状態や不必要な直列起動 |
| 準備完了 | 依存先は必要な操作を実行できますか? | プロセス開始後の接続失敗 |
| ランタイム回復 | 依存関係が後で消えたらどうなりますか? | クラッシュループや再接続しないサービス |
よくある質問
Docker Composeのdepends_onはデータベースが準備完了を意味しますか?
それだけではありません。起動順序は最初にデータベースコンテナを開始できますが、準備完了には適切なヘルスチェックやアプリケーションレベルの再試行が必要です。
すべてのサービスはnetwork-onlineを待つべきですか?
いいえ。ローカルサービスは外部接続を必要としない場合があり、広範なネットワークターゲットを待つと起動が遅れることがあります。サービスが必要とする特定のルート、マウント、アドレス、またはリモート機能に依存してください。
なぜアプリは手動再起動後に動作するのですか?
依存先は最初の試行が失敗した後に準備完了になった可能性があります。再起動はマウント、データベース、ネットワーク、またはDNSサービスの初期化完了後に行われます。
依存関係が多すぎると起動が不安定になりますか?
はい。過度に広範な厳格な要件は障害の伝播を増やし、順序の循環を生む可能性があります。正確性を保つ最も弱い関係を使用してください。
最終的な結論
サービス依存関係は、複数のデーモンやコンテナを要件、順序、準備状態のグラフに変換することでホームサーバーの起動を形作ります。正しい起動は、関連のない作業を直列化せずに実際の機能を待ちます。安定した運用には、依存関係の失敗後の再試行、準備状態の変化、そして制限された回復も必要です。
テック&AIハブ
もっと読む

Home Assistantにおけるランタイム状態と永続状態:再起動後も維持すべきものは?
Home Assistantはすべてのライブ値を永続化するわけではありません。設定、レジストリ、選択された復元状態、履歴、デプロイデータは、再起動時にそれぞれ異なる役割を果たします。

Home Assistantはローカルセッションとリモートセッションをどのように認証しますか?
ローカルおよびリモートのHome Assistantセッションでは、同じサーバー側のIDモデルを使用します。リモートアクセスによって変わるのは経路とTLSの境界であり、トークンフローの中核ではありません。

Recorderデータが増えると、なぜHome Assistantの履歴クエリは遅くなるのですか?
レコーダーの成長に伴い、要求された範囲に含まれる行数が増えたり、キャッシュミスが増加したり、ストレージやインデックス処理が遅くなったりすると、履歴クエリのコストが上昇する可能性があります。

