アプリの置き場所の設計 — /opt に直置きするかパッケージにして配るか

アプリの置き場所を決める設計判断は、設定ミスや権限エラーよりもはるかに長く尾を引く。直置き・パッケージ化・コンテナ同梱のどれを選ぶかは、引き継ぎやすさ・自動化の難易度・OS標準ツールとの互換性を左右する構築上の選択だ。本記事では、現場でよく発生するレイアウトの錯綜を切り口に、「何を基準に判断し、どこで線を引くか」という設計の骨格を整理する。

置き場所が担当者ごとに違い引き継げなくなる構造

暗黙の慣習がドキュメント化されないまま積み重なる

複数人が関わるサーバー構築プロジェクトでは、最初に手を動かした担当者の癖がそのままファイルシステムに刻まれる。ある担当者は/usr/local以下に展開し、別の担当者は/optを選び、さらに別の担当者はホームディレクトリ配下に暫定置きしたまま本番稼働させる。10台規模のサーバー群で同じアプリを管理するとき、こうした不統一はアップデートの工数を3倍以上に膨らませることも珍しくない。設計思想が言語化されないまま運用が始まると、誰も全体像を把握していない状態が常態化し、後工程の担当者が実態解明から始めることになる。

引き継ぎ時に浮上するレイアウトの錯綜

担当者が交代するタイミングで、レイアウトの暗黙ルールが可視化される。引き継ぎを受けた担当者がアプリのバイナリを探すとき、ドキュメントに書かれたパスと実際のパスが異なっていたり、起動スクリプトの中に絶対パスがハードコードされていたりする状況は珍しくない。現場では「引き継ぎのたびに1〜2週間を棚卸しに費やした」という話を繰り返し耳にする。構築時の設計判断が文書化されていない場合、実物を追いかけることで初めて全体像が見えてくる構造になっており、これが引き継ぎコストの本質的な原因だ。

「とりあえず動く」配置が技術的負債に変わる仕組み

設計を先送りにして「とりあえず動く」状態を優先した配置は、自動化が入った段階で負債化する。Ansibleでプロビジョニングを自動化しようとしたとき、ホスト間でパスがばらついていると変数一つで収まらず、条件分岐が複雑に積み重なる。こうした状況は、当初の実装者が単独で管理している段階では問題として表面化しにくい。引き継ぎや自動化の拡張という外部トリガーが入って初めて全貌が顕わになる。負債化のタイミングが遅れるほど修正コストは上がるため、構築初期にレイアウトの判断基準を定めておくことが長期の安定につながる。

OSの流儀に合わせる部分と独自に決めてよい部分の判断

FHSが定める用途の境界

Filesystem Hierarchy Standard(FHS)は、ディレクトリの用途を役割ごとに定義している。/usrはOS管理下のバイナリ、/var/logはログ、/etcは設定と、それぞれ責務が決まっている。設計判断として押さえるべきは「OS管理のパッケージが使うゾーン」と「サードパーティや独自アプリが使うゾーン」の境界だ。/usr/local以下はパッケージマネージャの管轄外という慣例があり、ここに手動インストールするとOS標準ツールが追跡できなくなる。一方で/optはパッケージ外のアプリを一塊で配置するために設けられた領域として扱いやすい。この境界を意識しないまま進めると、OS側の更新とアプリ側の変更が干渉し合う箇所が生まれる。

標準に従うと自動的に得られるもの

systemdのユニット管理、logrotate、auditdのファイル監視といったOSの標準ツールは、それぞれがFHSの慣例を前提に動作している。/var/log以外にログを出すとlogrotateのデフォルト設定が機能せず、ディスクが肥大化するリスクを手動で管理しなければならない。標準に従うことで「設定しなくていい管理タスク」が増え、独自に決めると「設定しなければいけない管理タスク」が増えるという構造を理解した上で、どこまで従うかを選ぶ。この選択は一度決まれば変えにくいため、構築前の段階で明示的に判断しておきたい。

独自に決めてよい部分を見極める基準

アプリケーション固有のサブディレクトリ構成(plugins/、modules/、data/ など)はFHSの外であり、独自設計の余地がある。判断の軸は「OS更新やディストロのメジャーアップグレードを経ても安定しているか」だ。/opt/myapp以下に完結したレイアウトを持つ構成は、OSの変更からアプリの構成を切り離しやすく、移行・バックアップの単位もシンプルになる。ただし、完全に独自化するとOS標準ツールの恩恵を受けられなくなるため、その境界を意識的に選ぶことが求められる。20環境以上に展開するシステムでは、この判断がデプロイ自動化の難易度に直接影響する。

比較: 直配置・OSパッケージ化・コンテナ同梱の選択軸

比較軸 直置き(/opt・/srv) OSパッケージ(deb/rpm) コンテナ同梱(Docker Image等)
管理・追跡 パッケージマネージャ外・手動追跡 パッケージDBで管理・バージョン記録可 イメージタグで追跡・ホストOS依存なし
更新・ロールバック 手動・デプロイスクリプト依存 パッケージコマンドで統一 イメージ差し替えでロールバック
設定の扱い 配置ルールを自前設計 /etcへのconffile管理が標準化 環境変数・Secrets・マウントで分離
セキュリティスキャン連携 スキャナー対応は別途設定が必要 OS標準の脆弱性DBと連携しやすい イメージスキャナーで自動化しやすい
マルチホスト展開 Ansibleなど外部ツールで管理 リポジトリ経由で配布・バージョン統一 レジストリ経由で配布・環境差なし
OS依存度 ディストロに依存 ディストロ・バージョンに強く依存 ホストOSとほぼ独立
向いている場面 少数台・開発環境・試験的展開 ディストロが固定・OSエコシステム活用 スケールアウト・複数環境への均一展開

この三択は「どれが正しいか」ではなく「自分たちの運用体制と展開規模にどれが合うか」で選ぶ。5台以下の固定環境では直置きがもっともシンプルで導入コストも低い。しかし50台を超える展開や頻繁な更新が求められる環境では、パッケージ化かコンテナ化を選ばないと管理コストが急増する。選択の判断を先送りにすると、展開が拡大したタイミングで方式変更という大きな手戻りが発生する。

設定・データ・ログをどこへ分けて置くか

バイナリと可変データを同一ツリーに混在させる危険

バイナリと設定ファイルを同じディレクトリに置くと、アプリのアップデート時に設定ファイルを上書きするリスクが生まれる。/opt/myapp/conf以下を直接書き換える運用をしていると、デプロイスクリプトが誤って設定を消すインシデントが発生しやすくなる。構築を任されたある担当者がこのパターンを踏んだとき、設定ファイルのバックアップ手順が整備されておらず、直前のデプロイで上書きされた設定の復元に3時間を費やしたという事例がある。30台を超える環境でこの設計を持ち込んだ場合、同様のインシデントが複数ホストで連鎖しやすい。バイナリと可変ファイルは最初から別のツリーに分離しておくことが、デプロイ設計の前提条件となる。

/etcと/var以下への分離原則

設定ファイルは/etc/myapp以下、可変データは/var/lib/myapp以下、ログは/var/log/myapp以下に置く分離は、単なる慣例ではなく運用の安全網として機能する。バックアップ対象を/var/lib以下に限定することで、スナップショットの範囲を最小化できる。ログを/var/log以下に集約することで、既存のログローテーション設定とsyslogの仕組みをそのまま流用できる。この分離を守るだけで、バックアップ・監視・ログ管理という三つの運用タスクに既存ツールが自動的に機能し始め、追加の設定作業を大幅に削減できる。

複数インスタンスを同一ホストで動かすときの分岐

同一ホストで同アプリを複数インスタンス起動するケースでは、設定やデータのパス設計が一層重要になる。/etc/myapp-instance1、/etc/myapp-instance2のように識別子を含む構成と、環境変数で切り替える構成では、自動化やsystemdのTemplateユニットとの相性が異なる。設計時点でシングルインスタンスを前提にしてしまうと、後からマルチ構成への変更がアーキテクチャレベルの改修になることがある。マルチインスタンスの可能性が少しでもある場合は、識別子をパスに含めるか環境変数で切り替えるかを構築初期に決めておくと、後工程の改修範囲を最小化できる。

実行ユーザーと所有者・権限をどう決めるか

rootで動かし続けることのリスクと判断

rootで起動することが許容されるのは、起動時にのみ特権が必要な場合に限定するべきだ。常時rootで動くプロセスが脆弱性を突かれた場合、ホスト全体に影響が及ぶ。専用サービスユーザーを作成し、必要な権限だけを付与する設計は、攻撃面の局所化だけでなく、ファイルの所有関係を明確にして引き継ぎやすくする効果もある。構築プロジェクトでは「とりあえずrootで動かして後で直す」という判断を積み重ねた結果、本番環境の全プロセスがrootで動いている状態を引き継いだという事例が繰り返し報告されている。後から専用ユーザーに切り替える作業は、起動スクリプト・ファイル所有者・ログパーミッションを一括で見直す必要があり、想定以上の影響範囲になりがちだ。

所有者・グループ・パーミッションの設計方針

アプリのバイナリはrootが所有し、サービスユーザーが読み取れる構成が基本だ。設定ファイルにパスワードや鍵を含む場合は、グループを絞り込んで640(所有者読み書き・グループ読み取り専用)に設定する判断が求められる。データディレクトリはサービスユーザーが書き込める必要があるため、755や750で所有を分ける。この三層(バイナリ・設定・データ)のパーミッション設計を構築前に決めておくと、後工程での権限エラーを大幅に減らせる。設計段階で表にまとめておくと、複数担当者が並行して構築するときの基準としても機能する。

デプロイ自動化との整合

CIからデプロイするパイプラインでは、デプロイユーザーとサービスユーザーが別になることが多い。デプロイユーザーがバイナリを上書きし、サービスユーザーが実行するという分業を成立させるには、所有者とグループの設計が整合していなければならない。設計せずに進めた場合、デプロイのたびに権限修正を追記する羽目になり、スクリプトが段々と見通せなくなる。CI/CDを導入する予定があるなら、実行ユーザーとデプロイユーザーの役割分担を先に定義してからパーミッション設計を進める順序が、後工程の手戻りを防ぐ上で重要だ。

独自レイアウトを積んで標準ツールが使えなくなる境界

パッケージ管理が追跡できないゾーンの問題

OSのパッケージマネージャが追跡できないファイルは、脆弱性スキャンツールや構成管理ツールの死角になる。/opt以下に直置きしたアプリは、apt/yumの管理外なので自動更新の対象にならない。セキュリティパッチ適用漏れを防ぐには別途の管理仕組みが必要で、そのコストを事前に見積もった上で配置方式を選ぶべきだ。脆弱性スキャンを導入した環境で、/opt以下のアプリが報告対象から漏れており、パッチ未適用のまま長期間稼働していたという事例は少なくない。直置きを選ぶ場合は、この死角をどう補うかをセットで設計することが求められる。

標準ツールが効かなくなるサインを見極める

ログが/var/log以外にある、systemd以外の起動スクリプトを使っている、設定が/etc以外に散在するという三つの状態が重なると、OS標準のツール群(journalctl、logrotate、auditd、パッケージスキャナー)が連鎖的に機能しなくなる。これらの兆候が3つ以上重なったとき、独自レイアウトの維持コストが標準ツールの恩恵を上回っている可能性が高い。この判断軸は、既存サーバーの棚卸しでレイアウトの健全性を評価するときにも活用できる指標だ。

標準に戻すか、独自を徹底するかの判断軸

中途半端な独自化が最もメンテナンスコストを高くする。独自レイアウトを選ぶならコンテナ同梱という形で徹底し、ホストのOS標準ツールへの依存を切り離す方が設計として一貫している。逆にOSのエコシステムを活用したい場合は、パッケージ化してOS側の管理に乗せる方向が合理的だ。どちらかに振り切ることで、運用チームがどのツールで管理すればよいかが明確になり、知識の引き継ぎもしやすくなる。中間にとどまる選択をする場合は、その理由を構築ドキュメントに明記しておくことで、次の担当者が同じ判断を繰り返す手間を省ける。

配置設計チェックリスト

以下は、配置設計の判断を構築前に整理するための確認軸だ。すべてに「はい」と答えられる状態が設計完了の目安となる。判断の根拠も合わせてメモしておくと、引き継ぎドキュメントとして機能する。

  1. バイナリ・設定・データ・ログを、それぞれ別のディレクトリツリーに分離する設計になっているか
  2. /opt・/srv・/usr/local・/etcのどの領域を使うか、役割ごとに根拠を定義しているか
  3. 専用サービスユーザーを作成し、rootではなくそのユーザーでプロセスを実行する設計になっているか
  4. デプロイユーザーとサービスユーザーの役割を分離し、パーミッションが整合しているか
  5. 設定ファイルに機密情報が含まれる場合、グループとパーミッションを適切に制限する設計になっているか
  6. ログの出力先がOS標準のlogrotateやjournaldと連携できる場所になっているか
  7. パッケージマネージャの管轄外に置く場合、脆弱性管理の別手段を持っているか
  8. マルチインスタンス起動の可能性を考慮し、設定・データのパスに識別子を持たせているか
  9. 複数ホストへの展開方式(直置き・パッケージ・コンテナ)を、運用体制と展開規模を踏まえて選んでいるか
  10. 採用した配置設計の根拠・例外・変更履歴を引き継ぎドキュメントに記録する仕組みがあるか

▶ 手を動かして本番まで到達する

脱属人化の第一歩は「読める・書けるスクリプト」から始まります

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

自動化の設計を、手を動かして身につける2日間です。手順書に閉じ込めた構築を、他人が読めて再現できる形へ変えていきます。

アプリ配置設計をスクリプトで標準化するシェルスクリプト実践コースへ →

シェルスクリプトマスターセミナー|自動化の設計を手で身につける2日間