「コンテナをdownして作り直したら,データベースの中身が全部消えた」── Docker初心者が必ず一度は通る悲劇だ.これはコンテナが本質的に「使い捨て」であることを理解していないために起こる.

コンテナの中に書いたデータは,コンテナを削除すれば消える.だからこそ「消えてはいけないデータ」をコンテナの外に永続化する仕組み── volume── を正しく使う必要がある.

この記事は,VPSでDockerを使う個人開発者,データの永続化を曖昧にしているエンジニアに向けている.volume・bind mount・tmpfsの使い分けから,DBデータの置き方,バックアップ,権限の罠までを徹底解説する.

読み終えたとき,あなたはコンテナを作り直してもデータを失わず,volumeをバックアップ・リストアできるようになっている.データを守ることは,すべての運用の前提だ.

なぜコンテナはデータを失うのか

コンテナはイメージから作られ,削除されると書き込んだ変更ごと消える.これはバグではなく設計だ.コンテナは「いつでも捨てて作り直せる」ことに価値があり,そのために状態を持たない思想で作られている.

ところがDB・アップロード・ログといった「失ってはいけないデータ」も,何もしなければコンテナの中に書かれてしまう.するとコンテナ更新・再作成のたびに消える.

解決策は,これらのデータをコンテナの外(ホストやvolume)に保存すること.コンテナは使い捨て,データは外に永続化── この分離が,Dockerでデータを守る大原則だ.

この原則を理解すれば,「コンテナはいつ作り直しても安全,データは残る」という安心して運用できる状態になる.

3つの永続化方式 ― volume・bind mount・tmpfs

Dockerのデータ永続化には3つの方式がある.それぞれ適した用途が異なる.まず全体像を掴もう.

方式保存先主な用途
named volumeDocker管理領域DBデータなど(推奨・移植性高)
bind mountホストの指定パス設定ファイル・開発時のソース共有
tmpfsメモリ上(揮発)一時データ・秘密情報の一時保持

原則として,永続させたいアプリのデータ(DB等)はnamed volume,ホスト上の特定ファイルを渡したいならbind mountを使う.tmpfsは「永続させたくない一時データ」専用だ.迷ったらnamed volumeが基本になる.

named volume ― DBデータの正しい置き方

named volumeはDockerが管理する永続領域で,コンテナを削除しても残る.DBのデータディレクトリをここに置くのが定石だ.

named volumeでDBを永続化(compose)

services:
  db:
    image: postgres:16
    volumes:
      - dbdata:/var/lib/postgresql/data   # DBデータをvolumeに
    environment:
      POSTGRES_PASSWORD: pass
volumes:
  dbdata:    # named volumeを宣言

これでdocker compose downしてもDBデータはdbdata volumeに残り,再度upすれば前の状態が復元される.volumeを明示的に削除(docker volume rmdown -v)しない限りデータは安全だ.逆に言えば,down -vはデータを消すので慎重に扱う.

down -v の落とし穴

docker compose down -v-vはvolumeも削除するオプションだ.「環境をきれいにしよう」と何気なく付けると,DBデータごと消える.本番やデータを残したい環境では-vを絶対に付けない.これは事故報告の定番だ.

bind mount ― ホストのファイルを渡す

bind mountはホストの特定パスをコンテナにマウントする方式だ.設定ファイルを渡す,開発中にソースコードを共有する,といった用途に向く.

bind mountの例

services:
  web:
    image: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro   # 設定を渡す(読取専用)
      - ./html:/usr/share/nginx/html            # 静的ファイル

:ro(read-only)を付けるとコンテナから書き換えられないため,設定ファイルを渡すときは付けるのが安全だ.bind mountはホストのパスに直接依存するため移植性は下がる.「このサーバーの,このパスのファイル」を渡す用途に限定し,DBデータのような永続データにはnamed volumeを使う,と分けるのが整理のコツだ.

volumeのバックアップとリストア

named volumeのデータも,当然バックアップが必要だ.volumeの中身を取り出してアーカイブし,外部に保管する.DBの場合はpg_dump等の論理バックアップが基本だが,volume自体のバックアップ手段も知っておくと心強い.

volumeの中身をtarでバックアップ

# volumeを一時コンテナでマウントしてtarに固める
docker run --rm -v dbdata:/data -v $(pwd):/backup alpine 
  tar czf /backup/dbdata-$(date +%F).tgz -C /data .

# リストア(空のvolumeに展開)
docker run --rm -v dbdata:/data -v $(pwd):/backup alpine 
  tar xzf /backup/dbdata-2026-07-10.tgz -C /data

この手法は任意のvolumeを,一時的なalpineコンテナでマウントしてtarに固める汎用テクニックだ.ただしDBのvolumeを稼働中に固めると不整合のリスクがあるため,DBは論理バックアップ(pg_dump/mysqldump)を優先し,volume tarは停止中や設定系volumeに使うのが安全だ.

権限の落とし穴 ― コンテナ内UIDとホストの食い違い

bind mountで頻発するのが権限(パーミッション)の問題だ.コンテナ内のプロセスが動くUIDと,ホスト側のファイル所有者が食い違うと,「読めない」「書けない」が起きる.

たとえばコンテナ内のアプリがnodeユーザー(UID 1000)で動くのに,bind mountしたホストのディレクトリがroot所有だと,書き込めずエラーになる.named volumeはDockerが権限を管理するためこの問題が起きにくいのも,volumeが推奨される理由の一つだ.

対策は,bind mount先の所有者をコンテナの実行UIDに合わせるか,可能ならnamed volumeを使うことだ.「コンテナでは動くのにファイルにアクセスできない」ときは,まずこのUID/権限の食い違いを疑う(Linux権限の記事も参照).

実践 ― 何をvolumeに、何を使い捨てにするか

最後に,実際の構成で「何を永続化し,何を使い捨てるか」の判断をまとめる.これが設計の指針になる.

  1. 必ずvolume(永続):DBデータ・ユーザーアップロード(またはオブジェクトストレージへ)・残したいログ
  2. bind mount:設定ファイル(nginx.conf等)・TLS証明書・開発時のソース
  3. 使い捨てでよい(volume不要):アプリのコード(イメージに含める)・再生成できるキャッシュ・ビルド成果物

補論:データを守るには「volume+スナップショット+外部保管」の三段

Dockerのデータ永続化は,volumeでコンテナの揮発から守り,スナップショットでサーバー全体を守り,外部保管でサーバー消失から守る── この三段が揃って初めて盤石になる.volumeだけでは「VPSが飛んだら終わり」だ.

高速NVMe・50種類以上のOSテンプレートに対応した国内VPS─シン・VPS─ はスナップショットでvolumeを含むサーバー全体を丸ごと退避でき,NVMe SSDでvolumeの読み書きも高速だ.「コンテナ更新の前にスナップショット→失敗したら即戻す」運用がしやすく,Dockerのデータ事故からの復旧力が高い.

さらにDBダンプやアップロードをオブジェクトストレージへ外部保管すれば(別記事参照),3-2-1ルールが完成する.独自ドメインは 取り扱い400種類以上のドメイン取得サービス─ムームードメイン─ で取得し,データを守りながらサービスを公開しよう.

よくある質問(FAQ)

Q1.named volumeとbind mountどちらを使う?

アプリの永続データ(DB等)はnamed volume,ホストの特定ファイルを渡すならbind mount.volumeは移植性と権限管理に優れ,bind mountは設定ファイルやソース共有に向く.迷ったらvolumeが基本だ.

Q2.down したらデータが消えた

down -v-vがvolumeを削除している.データを残したいなら-vを付けない.通常のdown(volumeなし)ならデータは残り,再upで復元される.

Q3.volumeのデータはどこにある?

Dockerが管理する領域(通常/var/lib/docker/volumes/配下)にある.直接触るよりdocker volumeコマンドや,一時コンテナでマウントして操作するのが安全だ.

Q4.DBのバックアップはvolume tarでよい?

稼働中のDBはpg_dump/mysqldumpの論理バックアップを優先する.稼働中にvolumeをtarで固めると不整合のリスクがある.volume tarは停止中や設定系volume向きだ.

Q5.bind mountでファイルにアクセスできない

コンテナの実行UIDとホストのファイル所有者の食い違いが原因のことが多い.マウント先の所有者を合わせるか,named volumeに切り替える.Linux権限の理解が役立つ.

Q6.コンテナのコードもvolumeに置くべき?

いいえ.アプリのコードはイメージに含めるのが基本だ(再現性のため).volumeは「コンテナの外に残すべきデータ」に使う.コードと永続データは分けて考える.

まとめ ― コンテナは使い捨て、データは外に永続化

Dockerでデータを失わない原則は,コンテナは使い捨て,消えてはいけないデータはvolumeで外に永続化することだ.named volumeを基本にし,down -vに注意し,バックアップと権限の罠を押さえれば,データ事故は防げる.

今日やるべきことは,自分のcomposeでDBデータがvolumeに置かれているか確認すること.コンテナ内に直接書いているなら,volumeに移す.そして一度,作り直してもデータが残ることを確認する.

データを守ることはすべての前提だ.volume+スナップショット+外部保管の三段を,戻せるVPSの上で組もう.