【注意】Dockerコンテナ終了後にデータが消えた?原因と対策をわかりやすく解説!

Docker

「Dockerコンテナを停止したら、保存していたはずのデータが消えていた…」

そんな経験をした方、意外と多いのではないでしょうか?

Dockerは開発・運用を効率化する素晴らしいツールですが、使い方を間違えると”データが保存されない”という落とし穴にハマります。

この記事では、Dockerコンテナ停止後にデータが消える理由と、データを永続化(ずっと保存しておく)するための確実な方法を丁寧に説明します。


スポンサーリンク

なぜコンテナを終了するとデータが消えるのか?

Dockerコンテナの基本的な仕組み

Dockerのコンテナは、基本的に一時的な実行環境として設計されています。

身近な例で説明すると:

  • 普通のパソコン:電源を切ってもファイルは残る
  • Dockerコンテナ:電源を切ると作業内容がリセットされる

データが消える主な理由

1. コンテナ内のファイルシステムは一時的

  • コンテナの中で作ったファイルは「仮の保存場所」に置かれる
  • コンテナを止めると、この仮の保存場所がなくなる
  • まるで「下書き用紙」のような存在

2. 再起動や削除時にリセットされる

  • コンテナを削除すると、中のファイルも一緒に消える
  • 新しく起動すると、最初の状態に戻る
  • ゲームの「リセット」ボタンを押したような状態

3. –rmオプションで自動削除される

# これは危険な例
docker run --rm -it ubuntu
# コンテナが停止すると同時に完全に削除される

–rmオプションとは:

  • コンテナ停止時に自動的に削除するオプション
  • 一時的な作業には便利だが、データは絶対に残らない

なぜこんな仕組みなの?

Dockerの設計思想:

  • 再現可能性:いつでも同じ環境を作れる
  • 軽量性:余計なファイルを保存しない
  • セキュリティ:終了後に痕跡を残さない

良い点:

  • クリーンな環境を簡単に作れる
  • テストやお試しに最適
  • セキュリティリスクが少ない

注意点:

  • 大切なデータは別の方法で保存する必要がある

データを永続化する方法①「ボリュームの使用」

ボリュームとは?

ボリューム(volume)は、Dockerが管理する永続的なデータ保存場所です。

身近な例で説明すると:

  • コンテナ:借りているアパートの部屋
  • ボリューム:自分が所有している倉庫
  • アパートから引っ越しても、倉庫の荷物は残る

ボリュームの基本的な使い方

ステップ1:ボリュームを作成

# 「mydata」という名前のボリュームを作成
docker volume create mydata

# 作成されたボリュームを確認
docker volume ls

ステップ2:コンテナにボリュームを接続

# MySQLデータベースでボリュームを使用
docker run -v mydata:/var/lib/mysql mysql

# 解説:
# mydata = ボリューム名
# /var/lib/mysql = コンテナ内のデータ保存場所

ステップ3:データが残ることを確認

# コンテナを停止・削除
docker stop コンテナ名
docker rm コンテナ名

# 新しいコンテナで同じボリュームを使用
docker run -v mydata:/var/lib/mysql mysql
# 前のデータがそのまま残っている!

ボリュームの利点

利点説明
安全性コンテナを削除してもデータが残る
共有可能複数のコンテナで同じデータを使える
バックアップしやすいDockerコマンドで簡単にバックアップ
パフォーマンス高速でアクセスできる

実際の使用例

Webアプリケーションのデータベース

# データベース用ボリュームを作成
docker volume create webapp-db

# MySQLコンテナを起動(データはボリュームに保存)
docker run -d \
  --name mysql-server \
  -e MYSQL_ROOT_PASSWORD=password \
  -v webapp-db:/var/lib/mysql \
  mysql:8.0

# アプリケーションコンテナを起動
docker run -d \
  --name web-app \
  --link mysql-server \
  mywebapp

データを永続化する方法②「バインドマウント」

バインドマウントとは?

**バインドマウント(bind mount)**は、ホストOS(あなたのパソコン)上の特定のフォルダをコンテナで使う方法です。

身近な例で説明すると:

  • ホストのフォルダ:自分の部屋の机
  • コンテナ:図書館の勉強スペース
  • バインドマウント:図書館で自分の机の資料を使って勉強

バインドマウントの基本的な使い方

基本構文

docker run -v /ホスト側のパス:/コンテナ側のパス イメージ名

実際の使用例

# ホームディレクトリのprojectsフォルダを使用
docker run -v /home/user/projects:/workspace ubuntu

# Windowsの場合
docker run -v C:\Users\username\projects:/workspace ubuntu

# 現在のディレクトリを使用(便利なショートカット)
docker run -v $(pwd):/workspace ubuntu

バインドマウントの特徴

良い点

  • リアルタイム編集:ホスト側でファイルを編集すると、コンテナ内にすぐ反映
  • 開発に最適:コードを書きながらすぐにテストできる
  • わかりやすい:ホスト側でファイルが見える

注意点

  • パスの間違い:フォルダのパスを間違えるとエラー
  • 権限問題:ファイルの読み書き権限に注意
  • OS依存:WindowsとLinuxでパスの書き方が違う

開発でよく使うパターン

Webアプリ開発

# 現在のディレクトリのコードをコンテナで実行
docker run -d \
  -v $(pwd):/app \
  -p 3000:3000 \
  node:16 \
  npm start

# コードを編集すると、すぐに反映される

設定ファイルの管理

# 設定ファイルをホスト側で管理
docker run -d \
  -v /home/user/config:/etc/myapp \
  -v /home/user/data:/var/lib/myapp \
  myapplication

消えたデータを復旧できるか?

復旧の可能性

残念ながら、コンテナを削除した後では、基本的にデータの復旧はできません

復旧可能な場合

1. コンテナが停止しているだけ(削除していない)

# 停止中のコンテナを確認
docker ps -a

# コンテナを再起動
docker start コンテナID

# データは残っている!

2. イメージとして保存していた場合

# コンテナの現在の状態をイメージとして保存
docker commit コンテナID backup-image

# 保存したイメージから新しいコンテナを起動
docker run -it backup-image

3. ボリュームやバインドマウントを使っていた場合

# ボリュームは削除されていなければデータが残る
docker volume ls

# 同じボリュームを使って新しいコンテナを起動
docker run -v 既存のボリューム名:/data イメージ名

復旧不可能な場合

  • docker rm でコンテナを削除済み
  • docker system prune で一括削除済み
  • --rm オプション付きで起動していた

データ消失を防ぐチェックポイント

起動前にチェック:

  • [ ] 重要なデータをどこに保存するか決めている
  • [ ] ボリュームまたはバインドマウントを設定している
  • [ ] --rm オプションを不用意に使っていない

作業中にチェック:

  • [ ] データの保存場所を意識している
  • [ ] 定期的にバックアップを取っている

終了前にチェック:

  • [ ] 重要なデータがコンテナ外に保存されている
  • [ ] コンテナ削除前にデータを確認している

データ消失を防ぐためのDocker運用ベストプラクティス

基本原則

1. すべての重要データは外部に保存

  • データベースファイル → ボリューム
  • 設定ファイル → バインドマウント
  • ログファイル → ボリュームまたはバインドマウント

2. docker-compose.yml で設定を明記

version: '3.8'
services:
  # データベースサービス
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - db-data:/var/lib/mysql  # データ永続化
      - ./config:/etc/mysql/conf.d  # 設定ファイル

  # Webアプリケーションサービス
  web:
    image: mywebapp
    volumes:
      - ./app:/var/www/html  # アプリコード
      - uploads:/var/www/html/uploads  # アップロードファイル
    ports:
      - "80:80"

# ボリューム定義
volumes:
  db-data:  # データベース用
  uploads:  # ファイルアップロード用

3. 危険なコマンドを避ける

# 危険:一時的な用途以外では使わない
docker run --rm 

# 危険:重要なデータがある場合は注意
docker system prune

# 安全:明示的にボリュームを指定
docker run -v mydata:/data

自動バックアップの設定

シンプルなバックアップスクリプト

#!/bin/bash
# backup.sh

# バックアップディレクトリを作成
mkdir -p /backup/$(date +%Y%m%d)

# ボリュームをtar形式でバックアップ
docker run --rm \
  -v mydata:/data \
  -v /backup:/backup \
  ubuntu tar czf /backup/$(date +%Y%m%d)/mydata.tar.gz -C /data .

echo "バックアップ完了: $(date)"

cron で定期実行

# 毎日午前2時にバックアップ実行
0 2 * * * /path/to/backup.sh

開発環境での推奨設定

設定ファイルテンプレート

# docker-compose.dev.yml(開発用)
version: '3.8'
services:
  app:
    build: .
    volumes:
      - ./src:/app/src  # ソースコードの同期
      - ./config:/app/config  # 設定ファイル
      - node_modules:/app/node_modules  # 依存関係は分離
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development

  db:
    image: postgres:13
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./sql:/docker-entrypoint-initdb.d  # 初期化SQL
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=developer
      - POSTGRES_PASSWORD=password

volumes:
  db_data:
  node_modules:

トラブル時の対処手順

1. データの確認

# ボリューム一覧を確認
docker volume ls

# ボリュームの詳細情報
docker volume inspect ボリューム名

# コンテナの状態確認
docker ps -a

2. データの救出

# 停止中のコンテナからデータをコピー
docker cp コンテナID:/path/to/data ./backup/

# ボリュームからデータをコピー
docker run --rm \
  -v ボリューム名:/data \
  -v $(pwd):/backup \
  ubuntu cp -r /data /backup/

3. 予防策の実装

# 重要なコンテナには必ずボリュームを設定
docker run -v important-data:/data myapp

# 設定をdocker-compose.ymlで管理
docker-compose up -d

よくある質問と答え

Q1. ボリュームとバインドマウント、どちらを使うべき?

A. 用途によって使い分けましょう。

用途おすすめ
データベースファイルボリューム
開発中のソースコードバインドマウント
設定ファイルバインドマウント
ログファイルボリューム
一時的なキャッシュボリューム

Q2. ボリュームはどこに保存される?

A. Dockerが管理する場所に保存されます。

# ボリュームの保存場所を確認
docker volume inspect ボリューム名

# Linuxの場合、通常は以下の場所
/var/lib/docker/volumes/ボリューム名/_data

Q3. 複数のコンテナで同じボリュームを使える?

A. はい、可能です。

# 複数のコンテナで同じボリュームを共有
docker run -v shared-data:/data container1
docker run -v shared-data:/data container2

Q4. ボリュームを削除するには?

A. 以下のコマンドで削除できます。

# 特定のボリュームを削除
docker volume rm ボリューム名

# 使用されていないボリュームを一括削除
docker volume prune

まとめ

Dockerでのデータ消失は、設計段階で回避可能な”あるある事故”です。

重要なポイント

データ保存の基本原則

  • コンテナ内に重要なデータを直接保存しない
  • ボリュームやバインドマウントを正しく使う
  • 運用中も定期バックアップと設定の見直しを

使い分けガイド

  • ボリューム:データベース、ログ、永続化が必要なデータ
  • バインドマウント:開発中のコード、設定ファイル、リアルタイム編集が必要なファイル

予防策

  • docker-compose.yml で設定を明文化
  • 定期的なバックアップ体制の構築
  • 危険なコマンド(–rm、system prune)の慎重な使用

コメント

タイトルとURLをコピーしました