「コンテナをdownして作り直したら,データベースの中身が全部消えた」── Docker初心者が必ず一度は通る悲劇だ.これはコンテナが本質的に「使い捨て」であることを理解していないために起こる.
コンテナの中に書いたデータは,コンテナを削除すれば消える.だからこそ「消えてはいけないデータ」をコンテナの外に永続化する仕組み── volume── を正しく使う必要がある.
この記事は,VPSでDockerを使う個人開発者,データの永続化を曖昧にしているエンジニアに向けている.volume・bind mount・tmpfsの使い分けから,DBデータの置き方,バックアップ,権限の罠までを徹底解説する.
読み終えたとき,あなたはコンテナを作り直してもデータを失わず,volumeをバックアップ・リストアできるようになっている.データを守ることは,すべての運用の前提だ.
なぜコンテナはデータを失うのか
コンテナはイメージから作られ,削除されると書き込んだ変更ごと消える.これはバグではなく設計だ.コンテナは「いつでも捨てて作り直せる」ことに価値があり,そのために状態を持たない思想で作られている.
ところがDB・アップロード・ログといった「失ってはいけないデータ」も,何もしなければコンテナの中に書かれてしまう.するとコンテナ更新・再作成のたびに消える.
解決策は,これらのデータをコンテナの外(ホストやvolume)に保存すること.コンテナは使い捨て,データは外に永続化── この分離が,Dockerでデータを守る大原則だ.
この原則を理解すれば,「コンテナはいつ作り直しても安全,データは残る」という安心して運用できる状態になる.
3つの永続化方式 ― volume・bind mount・tmpfs
Dockerのデータ永続化には3つの方式がある.それぞれ適した用途が異なる.まず全体像を掴もう.
| 方式 | 保存先 | 主な用途 |
|---|---|---|
| named volume | Docker管理領域 | 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 rmやdown -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に、何を使い捨てにするか
最後に,実際の構成で「何を永続化し,何を使い捨てるか」の判断をまとめる.これが設計の指針になる.
- 必ずvolume(永続):DBデータ・ユーザーアップロード(またはオブジェクトストレージへ)・残したいログ
- bind mount:設定ファイル(nginx.conf等)・TLS証明書・開発時のソース
- 使い捨てでよい(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の上で組もう.