はじめに:機能差分で「Gitブランチ」を分けると地獄が待っている
ソフトウェアを開発していると、必ず「エディション違い」を提供したくなる場面があります。
- 「軽量Base版」: CPUのみ・メモリ2GBで動く、AI機能なしの高速資産スキャンツール
- 「LLM拡張版」: ローカルAIモデル(Ollama)やRAGエンジンを同梱したフル機能版
これを実現しようとして、初心者がやってしまいがちな最大の失敗が 「Gitブランチを分けること(branch: base と branch: llm-pro)」 です。
ブランチを分けると、コア機能(バグ修正や画面改善)を修正するたびに双方向へのマージ作業(コンフリクト解消)が発生し、わずか数ヶ月で保守が破綻します。
絶対にブランチを分けてはいけません。
「コードベースは完全に単一(main ブランチのみ)」 を維持し、Docker Composeの「物理分割」と「オーバーライド(-f オプション)」 を使ってデプロイ時に構成を切り替えるのがプロのインフラ設計です。
本記事では、2GB RAMで自立稼働する「Base版」と、AIアドオンを重ねる「LLM版」をスマートに両立させるDocker Compose設計を公開します。
1. 基盤層:docker-compose.base.yaml(AI完全除外・軽量自立)
基盤ファイルには、システムが動作するために最低限必要なサービスのみを定義します。
AI関連のコンテナは一切含めず、環境変数 LLM_ENABLED=false をデフォルトとします。
💻 コア実装・設定スニペット(抜粋)
# docker-compose.base.yaml (軽量Base版)
version: '3.8'
services:
db:
image: mariadb:10.6
container_name: asset-db
environment:
- MYSQL_DATABASE=snipeit
- MYSQL_USER=snipeit
- MYSQL_PASSWORD=secret
volumes:
- db_data:/var/lib/mysql
snipeit:
image: snipe/snipe-it:latest
container_name: asset-snipeit
depends_on:
- db
ports:
- "8080:80"
web:
build:
context: .
dockerfile: web/Dockerfile.base
container_name: asset-web
ports:
- "8000:8000"
environment:
- LLM_ENABLED=false # AI機能を無効化(決定論的ルールで稼働)
- DATABASE_URL=sqlite:////app/data/scan_queue.db
scanner:
build:
context: .
dockerfile: scanner_scripts/Dockerfile.base
container_name: asset-scanner
environment:
- LLM_ENABLED=false
volumes:
db_data:
この構成だけであれば、わずか 2GB RAMの古いサーバーやファンレスPC でも極めて軽快に立ち上がります。
2. 拡張層:docker-compose.llm.yaml(AIアドオン)
AI機能を有効化したい環境でのみ、差分ファイルとしてこのYAMLを重ねます。
Docker Composeの仕様上、同名サービス(web, scanner)の定義は自動的にマージ(上書き) されます。
3. コマンド1発で切り替える運用(Makefile / スクリプト)
利用者は、起動コマンドを使い分けるだけです。
# (要点抜粋)
# (Source: https://github.com/ojisantech/)
# 【Base版として起動する場合(メモリ2GB環境)】
docker compose -f docker-compose.base.yaml up -d
# 【LLM拡張版として起動する場合(メモリ8GB環境)】
docker compose -f docker-compose.base.yaml -f docker-compose.llm.yaml up -d
Makefile でコマンドを抽象化
まとめ:ブランチを分ける前に「Composeの重ね合わせ」を使え
顧客の予算やサーバーのスペック(メモリ容量)に応じて製品構成を変えたいとき、コードやGitブランチをフォークするのは最悪の手法です。
- ソースコードは1つに保ち、環境変数(
LLM_ENABLED)で振る舞いを切り替える - Baseコンテナと拡張コンテナを物理的に分離する
- Docker Composeのマルチファイル(
-f)で透過的にマージする
このレイヤー型IaCアーキテクチャを敷くことで、開発チームは単一のブランチに集中しながら、顧客のインフラに合わせて最小構成からフルスペック構成まで自由自在にデプロイできるようになります!
📚 さらに詳しいアーキテクチャ設計・パラメータ表・トラブルシューティング
最後までお読みいただきありがとうございます!
本記事が少しでも「役に立った」「あとで試したい」と感じていただけましたら、ぜひQiitaの 「いいね(♡)」 と 「ストック」、および アカウントのフォロー をいただけると今後の検証・執筆の大きな励みになります!
また、本記事のさらに踏み込んだ 「深層アーキテクチャ解説」「主要パラメータの技術的根拠」「現場アンチパターン・トラブルシューティング対応表」 は、以下のGitHub技術リファレンスにて公開しています。
👉 【第28弾 詳細技術リファレンス (QIITA_ARTICLE_DETAIL_28.md)】
⭐ 全14層・200パターンの自立型インフラ&オンプレAIリファレンス集(おじさんの武器庫)を順次公開中です。ぜひGitHubリポジトリへの Star (★) と X (@OjisanTechnical) のフォローもお願いいたします!
👉 GitHub リポジトリ: ojisantech/ojisan-arsenal
💡 【検証環境・個人研究(PoC)に関する注記】
本記事は、筆者個人の自宅検証環境(ホームラボ/仮想環境)において、公開情報およびOSS(オープンソースソフトウェア)を用いて独自に構築・検証した個人研究(PoC)の記録です。特定の企業・団体の実環境や業務上の非公開情報とは一切関係ありません。