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

【Day 28】ボリューム(Named Volume)によるSQL Serverデータの安全な永続化 〜Docker管理領域によるmdf/ldfファイルの完全保護、docker-compose.ymlでのボリューム定義構文、一時コンテナを用いた安全バックアップ・リストア術、C# EF Core現場でのデータ保持〜

Day 28 アイキャッチ
▲ Day 28: ボリューム(Named Volume)によるSQL Serverデータの安全な永続化
🐳

「物理サーバーのDドライブのように、SQL ServerのDBレコードを安全に守り抜くにはどうすればいいのか?」

前回のDay 27では、Dockerコンテナが「いつでも使い捨てて作り直せるステートレスなプロセス」であり、何も設定せずにデータを書き込むとコンテナ破棄(docker compose down)と同時にデータが消滅する原理を学びました。
では、業務システムの要である SQL Server のデータベース(.mdf / .ldf) は、具体的にどのように保護すべきなのでしょうか?
その答えが、Dockerが推奨する 「名前付きボリューム(Named Volume)」 です!
本講義では、SQL Server公式Linuxコンテナのデータ格納構造(/var/opt/mssql/data)を解剖し、docker-compose.yml での正しいボリューム宣言、一時コンテナを用いた安全バックアップ&リストア手法、そしてC# / Entity Framework Core開発における超快適なデータ保護サイクルを徹底解説します!

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

  • 第1章: 名前付きボリューム(Named Volume)の基本と仕組み 〜ホスト管理領域の完全隔離〜
  • 第2章: SQL Server Linuxコンテナのデータ格納構造(/var/opt/mssql/data の秘密)
  • 第3章: docker-compose.yml での volumes 定義構文 〜2層構造の完全理解〜
  • 第4章: 実践!Docker CLIによるボリューム管理(create, ls, inspect, prune)
  • 第5章: 現場必須!一時コンテナ(alpine)を使った安全なデータバックアップ&リストア手順
  • 第6章: C# / ASP.NET Core & EF Core 現場での実践運用パターン
  • 第7章: 本日のまとめと理解度チェッククイズ(次回予告:Day 29 ホットリロード)

第1章: 名前付きボリューム(Named Volume)の基本と仕組み 〜ホスト管理領域の完全隔離〜

従来のWindows ServerやHyper-V仮想マシンでは、OSドライブ(Cドライブ)とは別に データ専用の独立ドライブ(DドライブやSAN/NASボリューム) を用意し、SQL Serverのデータファイルを配置するのが鉄則でした。OSが故障したり再インストールが必要になったりしても、Dドライブさえデタッチして無事なら、いつでも新しいマシンにアタッチして復旧できたからです。

Dockerにおける 「名前付きボリューム(Named Volume)」 は、まさにこの 「独立した安全なデータドライブ」 に相当する機能です。

💡 なぜバインドマウントではなく「Named Volume」を使うのか?
  • ① ホストOSのファイル権限(UID/GID)の競合ゼロ: SQL ServerコンテナはLinux内部で特殊な mssql ユーザー(UID 10001)で動作します。ホストPCのWindowsフォルダを直接直結(バインドマウント)するとNTFSのパーミッションエラーで起動失敗することが多発しますが、Named VolumeならDocker Engineが内部で安全な権限管理を自動代行します。
  • ② 高速なI/O性能: Windows上でWSL2を使う場合、WindowsのNTFSドライブ(/mnt/c/...)をマウントするとファイルアクセスが著しく低下します。Named VolumeはWSL2のExt4仮想ディスク内に直接確保されるため、ネイティブLinux並みの圧倒的なディスクI/O速度を誇ります。
  • ③ 名前によるポータビリティ: C:\Users\yamada\data のような環境依存の絶対パスを書く必要がなく、sqlserver_data という名前だけで全開発者・CI環境で共通運用できます。

Named Volumeの実体は、Docker Engineが管理するホスト上の専用領域(Linuxでは /var/lib/docker/volumes/<volume_name>/_data)に配置されます。コンテナが何百回起動・停止・破棄されようとも、このホスト管理領域の実体ファイルには指一本触れられません。

Named Volumeの仕組み
▲ 【図解①】Dockerホスト管理領域とSQL Serverコンテナ内部(/var/opt/mssql/data)のマウント結合関係

第2章: SQL Server Linuxコンテナのデータ格納構造(/var/opt/mssql/data の秘密)

Microsoft公式のSQL Server Linuxコンテナ(mcr.microsoft.com/mssql/server)を扱う際、エンジニアが必ず押さえておくべき絶対的なパスがあります。それが /var/opt/mssql/data です。

このディレクトリの中には、SQL Serverのエンジンが稼働するために不可欠なシステムデータベースおよびユーザーデータベースの実体ファイルが全て配置されます:

# コンテナ内の /var/opt/mssql/data の構成一覧
/var/opt/mssql/data/
├── master.mdf # システム構成・ログイン情報
├── mastlog.ldf # masterのトランザクションログ
├── model.mdf # 新規DB作成時のテンプレート
├── modellog.ldf # modelのトランザクションログ
├── msdbdata.mdf # ジョブやバックアップ履歴
├── msdblog.ldf # msdbのトランザクションログ
├── tempdb.mdf # 一時テーブル(起動毎に再生成)
├── templog.ldf # tempdbのトランザクションログ
├── MyCsharpAppDb.mdf # ★自作C#アプリのテーブル・データレコード実体
└── MyCsharpAppDb_log.ldf # ★自作C#アプリのトランザクションログ

つまり、コンテナ内の /var/opt/mssql/data ディレクトリをDockerのNamed Volumeにマウント してしまえば、SQL Serverが管理するすべてのデータファイル(.mdf / .ldf)がホスト側の安全なボリュームへ自動的に逃がされることになります!

第3章: docker-compose.yml での volumes 定義構文 〜2層構造の完全理解〜

ComposeファイルでNamed Volumeを利用する場合、初心者が最も躓きやすいのが 「2箇所に書く必要がある」 という点です。 以下の完成版 docker-compose.yml をご覧ください。

# docker-compose.yml: SQL Server Named Volume実践定義
services:
  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    container_name: sqlserver_container
    environment:
      - ACCEPT_EULA=Y
      - MSSQL_SA_PASSWORD=YourStrong@Passw0rd
    ports:
      - "1433:1433"
    volumes:
      # 【階層①】サービス内マウント: <ボリューム名>:<コンテナ内パス>
      - sqlserver_data:/var/opt/mssql/data

# 【階層②】トップレベル宣言: プロジェクト全体で利用するNamed Volumeを宣言
volumes:
  sqlserver_data:
    name: myproject_sql_volume # 任意のグローバルボリューム名を明示(省略可能)

この2層構造の役割を明確に区別しましょう:

  • ① サービス内 volumes: 個々のコンテナに対して「どのボリュームを」「コンテナ内のどこに差し込む(マウントする)か」を指示する プラグの接続設定 です。
  • ② トップレベル volumes: Docker Engineに対して「この名前の永続化ボリューム実体を1個確保せよ」と命じる 金庫自体の作成宣言 です。ここに書かないと、Composeは「そんなボリューム定義は存在しない」とエラーを出します。
Composeでのボリューム定義
▲ 【図解②】docker-compose.ymlにおけるサービス内マウントとトップレベルvolumes宣言の2層構造

第4章: 実践!Docker CLIによるボリューム管理(create, ls, inspect, prune)

普段は docker compose up で自動生成されるNamed Volumeですが、障害対応やディスクメンテナンス時にはDocker CLIから直接操作できることが現場エンジニアの必須スキルです。

コマンド 機能説明 実務でのユースケース
docker volume ls 存在するボリュームの一覧表示 現在PCに溜まっているDBボリュームの確認
docker volume inspect <名> ボリュームの詳細情報(Mountpoint)表示 ホストOS上の物理保存先パスの特定
docker volume create <名> 名前を指定して手動作成 事前に共通データボリュームを仕込んでおく場合
docker volume rm <名> 特定ボリュームの削除 テスト環境を完全破棄したい時(※コンテナ停止要)
docker volume prune どのコンテナにも繋がっていないボリューム一括削除 SSD空き容量の劇的回復(※未接続ボリューム消滅注意)
⚠️ 現場で最も恐ろしい「down -v」の誤爆事故

普段の docker compose down では、コンテナプロセスのみが破棄され、Named Volumeは無傷で残ります。
しかし、末尾に -v(または --volumes)を付与して docker compose down -v と叩くと、トップレベルで宣言されたNamed Volumeごと物理削除 されます!テストレコードを意図してリセットしたい場合を除き、日常の停止時には絶対に -v を付けないよう指差呼称してください。

第5章: 現場必須!一時コンテナ(alpine)を使った安全なデータバックアップ&リストア手順

「Named Volumeの中身をバックアップして別のPCに持っていきたい」「本番に近いテストデータを開発チーム全員に配布したい」というシチュエーションは現場で日常茶飯事です。
しかし、Named Volumeの実体フォルダ(/var/lib/docker/volumes/...)はroot権限で保護されており、Windowsエクスプローラーから直接ZIP圧縮することは困難です。

そこで、Dockerの世界で標準的に使われるプロの手法が 「超軽量な一時コンテナ(alpine)を用いたtarアーカイブバックアップ」 です!

# 【手順1: バックアップ】Named Volumeを一時コンテナにマウントし、ホスト側へtar.gz出力
docker run --rm \
  -v sqlserver_data:/dbdata \
  -v ${PWD}:/backup \
  alpine tar czvf /backup/sqlserver_backup.tar.gz -C /dbdata .

# 【手順2: リストア(復元)】新規作成したボリュームにtar.gzを展開
docker run --rm \
  -v sqlserver_data:/dbdata \
  -v ${PWD}:/backup \
  alpine tar xzvf /backup/sqlserver_backup.tar.gz -C /dbdata

このワンライナーがなぜエレガントなのか、その仕組みを紐解きましょう:

  1. --rm オプションにより、tar圧縮・展開の処理が終わった瞬間に一時コンテナ(alpine)は自動で消滅します(ゴミが残りません)。
  2. Named Volume(sqlserver_data)を /dbdata に、ホスト側のカレントディレクトリ(${PWD})を /backup に同時にマウントします。
  3. コンテナ内部で tar コマンドが走り、/dbdata の中身(.mdf/.ldfファイル群)を瞬時に圧縮して、ホスト側の /backup/sqlserver_backup.tar.gz に保存してくれます。
ボリュームのバックアップ手順
▲ 【図解③】一時コンテナ(alpine)を活用したNamed Volumeのtarアーカイブ安全バックアップ・リストア 3ステップ

第6章: C# / ASP.NET Core & EF Core 現場での実践運用パターン

Named Volumeを導入することで、C#エンジニアの開発体験(Developer Experience)は劇的に進化します。

① EF Core マイグレーションとボリュームの共存

ASP.NET Coreアプリケーション起動時に DbContext.Database.Migrate() を呼び出す設計を採用している場合、初回起動時にテーブルが自動作成され、テストシードデータが投入されます。
もしボリュームがなければ、C#コードを修正してコンテナを再起動するたびに「初期化スクリプト」が最初から走り直し、手動で画面からポチポチ登録したテストユーザーや受注レコードが吹き飛んでいました。

// Program.cs: アプリ起動時の自動マイグレーション例
using (var scope = app.Services.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
    // Named VolumeにDBファイルが存在すればマイグレーション履歴テーブル(__EFMigrationsHistory)
    // を見て差分のみ適用されるため、既存データは完全に安全!
    dbContext.Database.Migrate();
}

② チーム開発におけるGitとボリュームの運用ルール

チームでDockerを活用する際の鉄則は、「Gitで共有するのはコードとマイグレーション(.csファイル)だけであり、Named VolumeのDB実体ファイル(.mdf/.ldf)は絶対にGitにコミットしない」 ということです。

  • Gitの役割: データベースの「スキーマ定義(設計図)」を全員で同期する。
  • Volumeの役割: 各開発者のPC上で動作する「生データ(テストレコード)」をローカルで安全に保持する。

これにより、Gitのブランチを切り替えて新機能を実装し、コンテナを docker compose up -d --build で差分再ビルドしても、昨日登録したログインセッションや複雑なテストデータがそのまま保持されるため、開発効率が何十倍にも向上します!

C#現場の開発ワークフロー
▲ 【図解④】C#開発現場におけるデータ保護恩恵(コード更新・再ビルド時もテストDBレコードを完全保持)

第7章: 本日のまとめと理解度チェッククイズ

📌 本日の最重要チェックポイント

  1. Named VolumeはDocker管理の安全な独立データドライブ: ホストOSの権限競合を防ぎ、最高速のディスクI/Oを提供。
  2. SQL Serverの格納先は /var/opt/mssql/data: ここをボリュームにマウントすることで、すべてのmdf/ldfファイルがコンテナ外へ保護される。
  3. Compose定義は「サービス内」と「トップレベル」の2層構造: サービス内でマウント先を指定し、最下部で実体宣言を行う。
  4. 日常は down、リセット時のみ down -v: -v オプションを誤爆するとボリュームごとデータ消滅するため厳格注意。
  5. バックアップは一時コンテナ(alpine)のtarが業界標準: コンテナを汚染せず、ホスト側へクリーンにtar.gzアーカイブを出力可能。

🎯 理解度チェッククイズ

Q: docker-compose.ymlでNamed Volumeを利用してSQL Serverを起動している現場で、開発者が叩いたコマンドのうち、データベースのデータが「完全に消滅してしまう」ものはどれでしょうか?

  • A. docker compose stop
  • B. docker compose down
  • C. docker compose up -d --build
  • D. docker compose down -v
正解と解説を見る

正解: D. docker compose down -v
通常の stop や down、再ビルドを伴う up -d --build では、Named Volumeは完全に維持されるためDBデータは消えません。しかし、-v(または --volumes)フラグを付けて実行すると、コンテナだけでなく定義されたボリューム自体が破棄されるため、データが完全に初期化されます。意図的なデータリセット以外では絶対に付与しないようにしましょう。

🚀 次回予告(Day 29)

次回は永続化のもう一つの主役、「バインドマウント(Bind Mount)によるソースコード即時反映(ホットリロード)」 を徹底攻略します!
C#コードを保存した瞬間にコンテナ内で自動再起動・即時反映される dotnet watch とバインドマウントの超高速開発サイクルを構築します。お楽しみに!

コメント

このブログの人気の投稿

【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版のオンラインプレーを楽しむ方法