スキップしてメイン コンテンツに移動

【Day 30】Git管理すべきファイルとVolumeに逃がすべきデータの境界線 〜コード(Git)・構成(Git/.env)・データ(Volume)の3層分離、巨大mdfバイナリ混入事故の防止、.gitignore徹底、チーム開発共有ルール〜

Day 30 アイキャッチ
▲ Day 30: Git管理すべきファイルとVolumeに逃がすべきデータの境界線
🐳

「Dockerプロジェクト内のファイル、何でもGitにコミットしていませんか?」

前回のDay 29では、ホストPCとコンテナを直結してC#のホットリロードを実現する「バインドマウント(Bind Mount)」を学びました。
コンテナ環境でのデータ永続化(Named Volume)と高速開発(Bind Mount)の両輪を手に入れた開発チームが、次に必ず直面するのが 「プロジェクト内のどのファイルをGitで管理し、何をVolumeやローカルに逃がすべきか?」という境界線の問題 です。
昔のオンプレミス現場では、ファイルサーバーの共有フォルダにソースコード、SQL Serverの .mdf ファイル、設定ファイル、果てはログまで何でも放り込み、誰かが上書きしてDBが破損するなどの地獄絵図が日常茶飯事でした。
もしこの悪習をそのまま現代のGit×Docker環境に持ち込み、巨大なデータベースファイルをGitにコミットしてしまうと、リポジトリが数十GBに膨れ上がり、チーム全員のPCでクローン不能になる壊滅的事故 を引き起こします。
本講義は第6部「データの永続化とボリューム」の総決算として、「コード(Git)」「構成(Git/.env)」「データ(Volume)」の3層分離原則 と、事故を未然に防ぐ現場ルールを完全解説します!

INDEX 本日の講義カリキュラム

  • 第1章: 共有フォルダ破綻の歴史に学ぶ 〜なぜ「何でも詰め込み」は失敗するのか?〜
  • 第2章: 現代コンテナ開発における「3層分離(コード・構成・データ)」の原則
  • 第3章: 現場向け「ファイル行き先判定マトリクス」と3ステップ判定フロー
  • 第4章: 巨大バイナリ混入の悲劇 〜.mdfをGitにpushするとリポジトリが崩壊する理由と.gitignoreの徹底〜
  • 第5章: C# / .NET 現場での実践:appsettings.json(設定)とSQL Server実データ(Volume)の共存設計
  • 第6章: チーム開発でのGit&Docker運用ルール策定ガイドライン
  • 第7章: 第6部総決算のまとめと理解度チェッククイズ(次回予告:第7部 Dockerネットワーク入門)

第1章: 共有フォルダ破綻の歴史に学ぶ 〜なぜ「何でも詰め込み」は失敗するのか?〜

かつてのオンプレミスや仮想マシン(Hyper-V / VMware)全盛の時代、社内ネットワークには必ず \\fileserver\dev_share のような「開発用共有フォルダ」が存在していました。
そこには以下のようなあらゆる種類のファイルが無法地帯のように混在していました:

  • Visual StudioのソリューションファイルやC#ソースコード
  • SQL Serverにアタッチされている生の app_data.mdf や app_log.ldf
  • 各エンジニアが手元で実行した出力ログやエラーダンプ
  • 本番サーバー接続文字列がハードコードされた設定ファイル

このような「何でも詰め込み」運用がもたらした結末は、多くのベテランエンジニアが身をもって体験してきた通り 「完全な破綻」 でした。

共有フォルダの破綻 vs 現代の境界線
▲ 【図解①】旧来の共有フォルダ破綻(何でも混在) vs 現代の3層分離(コード・構成・データ)

上図(左側)をご覧ください。共有フォルダでファイルを共有すると、次のような致命的トラブルが連日発生しました:

⚠️ 共有フォルダ運用が引き起こした3大悲劇

  1. ファイルロックとデータベース破損: 誰かがSQL Server Management Studio(SSMS)で接続したままにして排他ロックがかかり、他のメンバーが作業できなくなる。最悪の場合、同時書き込みでmdfヘッダーが破損し、全員のデータが全滅する。
  2. データの先祖返りとブラックボックス化: 「最新のDBデータはどれ?」「backup_20261020_final2.bak って誰が作ったの?」と誰も全体像を把握できなくなる。
  3. 秘密情報の漏洩リスク: パスワードや機密データが誰でもアクセス可能な平文ファイルとして放置され、情報セキュリティ上の重大な脆弱性となる。

現代のコンテナ開発では、この苦い歴史の反省から 「ファイルをその性質(ライフサイクルと変更頻度)に応じて厳密に分類し、それぞれ最適な仕組みで管理する」 というパラダイムシフトが確立されています。

第2章: 現代コンテナ開発における「3層分離(コード・構成・データ)」の原則

DockerとGitを組み合わせたモダンな開発環境では、すべての構成要素を以下の 「3層」 に厳格に分離して設計します。

① コード層(Git管理)
対象: ソースコード・構成定義

C#の .cs ファイル、.csproj、Dockerfile、docker-compose.yml。
テキストベースで記述され、変更履歴(コミットログ)が厳密に記録されるべきチーム共通の資産。

② 構成・機密層(.env / 除外)
対象: 環境変数・パスワード・接続文字列

.env や docker-compose.override.yml。
環境ごとに異なる機密情報。Gitにはテンプレート(.env.example)のみをコミットし、実ファイルは .gitignore で完全除外。

③ データ・状態層(Volume管理)
対象: DB実データ・ログ・ユーザー生成物

SQL Serverの .mdf/.ldf、ユーザー投稿画像、アクセスログ。
サイズが巨大で頻繁に更新されるバイナリ。Gitには一切入れず、Dockerの Named Volume に逃がして永続化。

この3層分離を徹底することで、「コードは安全に共有され」「パスワードは漏洩せず」「データベースはコンテナ破棄時も確実に保護される」という強固なアーキテクチャが完成します。

第3章: 現場向け「ファイル行き先判定マトリクス」と3ステップ判定フロー

プロジェクトに新しいファイルやフォルダが追加された際、チームメンバーが迷わず正しく配置できるよう、以下の 「判定3ステップフロー」 を確立しましょう。

ファイルの行き先判定3ステップ
▲ 【図解②】現場で迷わない!ファイルの行き先判定3ステップマトリクス

このフローに基づいた現場向け判定マトリクスがこちらです:

ファイル種類 具体例 管理場所 理由・注意点
C# ソースコード *.cs, *.csproj, *.sln Git管理 アプリの本体。チームで共同開発。
インフラ定義ファイル Dockerfile, docker-compose.yml Git管理 環境の再現手順(IaC)。全員が同じ定義で起動。
アプリケーション共通設定 appsettings.json Git管理 ログ設定や基本オプション。機密パスワードは含めない。
環境固有の機密情報 .env, *.secrets.json Git除外(.gitignore) DBパスワードやAPI鍵。漏洩防止のためGit厳禁。
設定ファイルのひな形 .env.example Git管理 新人参加者がコピーして自分の .env を作るための見本。
データベース実データ *.mdf, *.ldf, *.bak Docker Named Volume 巨大バイナリ。Gitに絶対入れずDocker管理領域へ。
ビルド成果物・一時ファイル bin/, obj/, .vs/ Git除外(.gitignore) ソースからいつでも再生成可能。リポジトリ汚染の主因。
初期マスタデータSQL init.sql, migrations/*.cs Git管理 テーブル定義や初期投入用。テキスト形式なのでGitで共有。

第4章: 巨大バイナリ混入の悲劇 〜.mdfをGitにpushするとリポジトリが崩壊する理由と.gitignoreの徹底〜

なぜデータベースの実データファイル(.mdf や .ldf)をGitにコミットしてはいけないのでしょうか?
その理由は、「Gitの内部データ構造(スナップショット方式)」 にあります。

巨大バイナリ混入の悲劇と防止
▲ 【図解③】巨大バイナリ(mdf/ldf)混入の悲劇と .gitignore 徹底による完全防御

Gitはテキストファイル(C#コードなど)であれば行単位のコンパクトな差分(delta)を保存しますが、バイナリファイルに対しては 「1バイト変わるだけでもファイル全体を丸ごと新しいスナップショットとしてコミット履歴(.git/objects)に保存」 します。

💥 巨大バイナリ事故のシミュレーション

例えば 2GB の testdata.mdf をGitにコミットしたとします。
その後、SQL Serverでレコードを1件INSERTして再度コミットすると、さらに 2GB の新しいバイナリが .git に追加されます。
これを10回繰り返すだけで、リポジトリの容量は 20GB を超えます!
新しくチームに参加したエンジニアが git clone を実行すると、ダウンロードに数時間かかり、通信タイムアウトで失敗し続けるという悪夢が現実になります。

さらに恐ろしいことに、後から git rm testdata.mdf を実行してファイルを消去しても、過去のコミット履歴の中には20GBのバイナリが残り続けます。
履歴から完全に消去するには git-filter-repo などの危険な履歴書き換えコマンドが必要になり、チーム全員のローカル環境のリセットを強いられます。
この悲劇を100%未然に防ぐ唯一の方法が、プロジェクト開始初日における .gitignore の徹底 です!

# Docker × C# / .NET プロジェクト必須の .gitignore テンプレート

### 1. データベース実データ・バックアップ(絶対にコミット禁止!) ###
*.mdf
*.ldf
*.ndf
*.bak
*.trn
*.db
*.sqlite

### 2. 環境変数・秘匿設定ファイル ###
.env
.env.local
.env.*.local
*.secrets.json

### 3. C# / .NET ビルド成果物・キャッシュ ###
[Bb]in/
[Oo]bj/
[Dd]ebug/
[Rr]elease/
*.user
*.suo
.vs/
.idea/

### 4. ログファイル・一時出力 ###
*.log
logs/
temp/
docker_volumes/

第5章: C# / .NET 現場での実践:appsettings.json(設定)とSQL Server実データ(Volume)の共存設計

C# / ASP.NET Core のエンタープライズ現場では、この境界線をどのようにコードとインフラで表現するのでしょうか?
具体的な appsettings.json と docker-compose.yml の連携設計を見てみましょう。

C#現場の設定と実データの分離
▲ 【図解④】C#エンタープライズ現場における設定(Git)と実データ(Volume)の分離共存設計

上図をご覧ください。設計の勘所は以下の2点です:

  1. 設定の抽象化(Git共有): appsettings.json には「DBのホスト名(サービス名: db)」や「ポート(1433)」といった構造のみを記述し、パスワード部分は環境変数で上書き可能なプレースホルダーにしておきます。
  2. データの完全委任(Volume管理): SQL Serverコンテナが生成・管理する /var/opt/mssql/data は、DockerのNamed Volume(sqlserver_data)にマウントします。

① C#側の設定ファイル(Gitで管理・共有)

// appsettings.json (パスワードは空文字または環境変数上書き前提)
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    // ホスト名はコンテナサービス名「db」を指定!パスワードはComposeの環境変数で注入される
    "DefaultConnection": "Server=db,1433;Database=OrderDb;User Id=sa;Password=${DB_PASSWORD};TrustServerCertificate=True;"
  }
}

② docker-compose.yml(Gitで管理・Volumeとパスワードを結合)

services:
  webapi:
    build: .
    ports:
      - "5000:5000"
    environment:
      # .env からパスワードを読み込み、C#の接続文字列を環境変数で完全注入
      - ConnectionStrings__DefaultConnection=Server=db,1433;Database=OrderDb;User Id=sa;Password=${SA_PASSWORD};TrustServerCertificate=True;
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      - ACCEPT_EULA=Y
      - MSSQL_SA_PASSWORD=${SA_PASSWORD}
    volumes:
      # ★実データ(.mdf / .ldf)はNamed Volumeに完全に退避!
      - sqlserver_data:/var/opt/mssql/data

# 名前付きボリュームの宣言(Dockerホスト領域で独立永続化)
volumes:
  sqlserver_data:

この構成にすることで、チームの誰もが生のDBファイルをGitにコミットすることなく、docker compose up -d を実行するだけで即座に安全で完全なローカル開発環境を立ち上げることができます。

第6章: チーム開発でのGit&Docker運用ルール策定ガイドライン

「Git管理とVolumeの境界線」をチーム全員で遵守するために、プロジェクトの README.md や開発ガイドラインに以下の 4大ゴールデンルール を明記しておくことを強く推奨します。

📋 チーム開発のための4大ゴールデンルール

ルール1:初期データは「mdf」ではなく「Migration」または「init.sql」で共有せよ

開発用の初期データやテーブル構造を渡したい時は、バイナリのmdfファイルを渡すのではなく、EF Coreの dotnet ef migrations や、テキスト形式の seed_data.sql をGitで共有します。

ルール2:リポジトリ直下の .env はコミット厳禁! .env.example をメンテナンスせよ

環境変数キーを追加した時は、必ず .env.example にダミー値(例: SA_PASSWORD=YourPasswordHere123!)を追記してコミットします。新メンバーはこれをコピーして手元で動かせます。

ルール3:データベースをリセットしたい時は Volume を再作成せよ

手元のテストデータを完全にクリーンアップして初期状態に戻したい時は、docker compose down -v を実行するだけで、Named Volumeが初期化されマイグレーションが再実行されます。

ルール4:プルリクエスト時の差分チェックで「.mdf / bin」の混入を即時却下せよ

GitHub ActionsなどのCIパイプラインで、万が一バイナリファイルや不要フォルダが含まれていた場合は自動でビルドを失敗させる静的解析ガードを設置するとさらに完璧です。

第7章: 第6部総決算のまとめと理解度チェッククイズ

これで第6部「データの永続化とボリューム(Volume & Bind Mount)」のカリキュラムはすべて完了です!
コンテナのステートレスな原則(Day 27)、Named Volumeによる安全なデータ保持(Day 28)、Bind Mountによる爆速ホットリロード(Day 29)、そして今回のGitとVolumeの境界線(Day 30)を学んだことで、データ永続化と開発効率を完璧に両立させるプロフェッショナルな基盤 が完成しました!

🎯 理解度チェッククイズ!

問: 新しい開発メンバーが「自分の手元のSQL Serverデータをチーム全員に配りたいので、mdfファイルをGitにコミットしてpushしました!」と言ってきました。シニアエンジニアとしてどうアドバイスし、どのように解決すべきでしょうか?

正解と解説を確認する

【アドバイスと対応手順】

  1. 即時差し戻しと履歴の除去: mdfファイルは巨大バイナリであり、リポジトリ肥大化・clone遅延の主因となるため、直ちにpushを差し戻すか git reset でコミットを取り消す。
  2. .gitignore の適用: *.mdf, *.ldf を .gitignore に追加して再コミットを防止する。
  3. シードデータ(SQL/Migration)での共有: データをチームに配る場合は、mdfファイルではなく EF Core の HasData() によるシーディングスクリプト、または init.sql のようなテキストスクリプトを作成してGit管理する。
  4. Volumeの利用: 各メンバーは docker compose up 時にそのスクリプトを各自の Named Volume に流し込む運用に切り替える。

🚀 次回予告:第7部「Dockerネットワークの基礎とサービス間通信」突入!

次回Day 31からは、いよいよ 第7部「Dockerネットワーク」 がスタートします!
「なぜ docker-compose.yml の中では localhost ではなくサービス名(db)で通信できるのか?」
Docker内部に自動生成される仮想ブリッジネットワーク(Bridge Network)やDNSサーバーの驚くべき仕組みを徹底的に解き明かします。お楽しみに!

コメント

このブログの人気の投稿

【Perfume】Perfume 3rd Tour 「JPN」さいたまスーパーアリーナに行って参りました~

Perfume 3rd Tour 「JPN」1月28日、29日の2daysで参戦して参りました。 ファンクラブ会員の選考抽選会に28日、29日の両日で申し込んでいたんですが、両方とも当選していたという嬉しい誤算。 仕事だぁ、なんだかんだと紆余曲折ありまして28日の参戦は危ぶまれていたのですが、なんとかかんとか28日は40分遅刻しながらも参戦、29日はフル参戦する事が出来ました(∩´∀`)∩

Perfume、2025年末で“コールドスリープ(活動休止)”へ──東京ドーム2daysの記録と、公式・各界・ファンの声

  1) 公式発表・基本情報 活動休止(コールドスリープ)を正式発表 2025年9月21日、公式サイト「 Perfumeより 」で、2026年から一度コールドスリープに入ると発表。再始動の意思(“新しいPerfume”として戻る)も明記。 Perfume Official Site 今後の運用告知(配信・上映など) 同21日付の「 今後のPerfumeに関して 」で、9/23(火・祝)東京ドーム公演の LIVESHIP全世界生配信 および 全国ディレイビューイング 決定を案内。特設サイトも併記。 Perfume Official Site +1 公式グッズ **「Perfume Calendar 2026」**発売決定(B2壁掛け/表紙+2カ月1枚×6枚+ポスター)。テーマは“フルーツ”。 Perfume Official Site 2) 東京ドーム2days(9/22・23)要点 公演タイトル: ZO/Z5 Anniversary “ネビュラロマンス” Episode TOKYO DOME 。日程・開場/開演・会場・物販等の実務情報は特設で公開。 Perfume Official Site 9/23公演を世界配信(LIVESHIP) /ディレイビューイング実施。 Perfume Official Site 海外向け報道(英語)も「 indefinite hiatus 」として広く配信。 The Times of India 国内英字メディアも速報。 朝日新聞 3) 現地レポ( メリ爺 )から見える空気 あなたの現地記録(9/24公開)を、ファクトと現場情景の両面で反映: 両日参戦 。22日は アリーナ 、23日は 1階席から俯瞰 。前日の発表を受け、開演前のザワつき→MC後に“いつもの一体感”へ。開演は22日 18:45 頃。オープニングは**P³ツアー東京ドーム(2020/2)**と同趣向で“回収”の演出。 メリ爺のゲーム万歳 MC所感 :解散ではなく前向きな休止で不安を和らげる内容。 かしゆか の涙、 のっち の気丈さ、 あ〜ちゃん の思い出語り──3人の結束と「 また戻る 」約束が強く刻まれた。 メリ爺のゲーム万歳 体感時間 : “3時間弱”級のボリューム ながら“過去一...

ニンテンドースイッチでオンラインゲームを遊ぶには?

モンスターハンターライズが発売になって、家族でモンハン楽しみたい人が増えたみたいですね。 某ブログの検索キーワードを調べると、モンハンを家族でやるにはどうしたらいいのか?を調べている人が沢山いるのがわかります。 ※これでも一部  家族で協力するにはSwitch2台、ソフトも2つ購入する必要があります。 1台のスイッチでは遊べませんし、ソフト1つでも遊べません。 でも、1台のスイッチで別々アカウントがあれば交代で遊ぶこともできますよ。セーブデータもしっかり分かれます。 Switchのオンラインゲームを家族で遊ぶ方法については以下の記事にまとめてますのでよろしければ参考にしてみてくださいね。 家族でモンスターハンターライズDL版のオンラインプレーを楽しむ方法