Dockerコンテナはデフォルトで書き込みレイヤーが使い捨て——docker rmした瞬間にDBも、ユーザーがアップしたファイルも、ログも消えます。この壁を越えるための核心機能がvolume(ボリューム)。MySQL/PostgreSQLのデータ、WordPressの画像、Redisのスナップショット、Prometheusの時系列データ——本番・開発を問わず「永続化すべきもの」は全てvolumeに載せる、というのが2026年の標準です。
入門記事の多くは-v db_data:/var/lib/mysqlの例で止まっていますが、実運用で差がつくのはvolume driverによるクラウドストレージ連携(AWS EBS/Azure Files)、backup/restore戦略、ホスト間移行、権限問題(UID/GID)、read-only/shared propagation、labelsによるライフサイクル管理、prune –filterなどの運用寄りトピック。これらを知らないとDBのフルバックアップや本番移行で必ず困ります。
この記事では、volumeの内部構造(/var/lib/docker/volumes/)から始めて、5種のマウントタイプ比較、driver_opts(NFS/cifs/tmpfs/sshfs)、バックアップ/リストア7パターン、ホスト間移行、権限/labels/prune の運用テクニック、macOS・Windows特有の性能問題まで、volumeを使いこなすための完全ガイドとしてまとめます。bind mountとの使い分け詳細は【Docker】bind mountとvolumeの違いと使い分け、Compose基礎は【Docker】Compose完全ガイドで補完できます。
この記事で学べること
- volumeの内部構造(
/var/lib/docker/volumes/の中身) - 5種のマウント比較:named/anonymous/bind/tmpfs/npipe
- volume driver活用(
local/NFS/cifs/sshfs/AWS EBS/Azure Files) driver_optsでmount typeやsize制限を細かく指定- Composeの
external/labels/name/driver_optsで運用管理 - backup/restore 7パターン(tar/helper container/Compose連携)
- ホスト間移行:
docker run --rm+tar + scpの実戦テクニック - UID/GID問題(Linuxでの所有者ズレ)と解決策
ro/:z/:Z(SELinux)/propagationの適用- labels+
prune --filterで誤削除事故を防ぐ - macOS/Windowsでの性能問題と回避策
- disaster recovery:volume消失時の復旧手順
- 30秒クイックスタート:volume操作の4大コマンド
- volumeの内部構造:/var/lib/docker/volumes/
- マウントタイプ5種の完全比較
- volume CLI操作完全リファレンス
- Composeでのvolume定義完全版
- volume driver:ローカル以外のストレージ連携
- backup/restore:volumeデータを守る7パターン
- ホスト間移行:本番↔ステージング間でvolumeを移動
- 権限問題(UID/GID)とその解決
- read-only/SELinux/propagationオプション
- クリーンアップ戦略:labelsで事故を防ぐ
- よくあるトラブルと対処
- よくある質問
- 関連記事
- まとめ
30秒クイックスタート:volume操作の4大コマンド
# ① 作成(明示的に名前を付ける) docker volume create db_data # ② マウントして使う docker run -d --name mydb \ -e MARIADB_ROOT_PASSWORD=root \ -v db_data:/var/lib/mysql \ mariadb:11 # ③ 一覧・詳細確認 docker volume ls docker volume inspect db_data # ④ 削除(コンテナ停止後) docker volume rm db_data
# -v より明示的で安全な --mount 構文 docker run -d --name mydb \ -e MARIADB_ROOT_PASSWORD=root \ --mount type=volume,source=db_data,target=/var/lib/mysql \ mariadb:11 # bind mountと区別しやすい docker run --mount type=bind,source=./conf,target=/etc/conf ... docker run --mount type=tmpfs,target=/tmp ...
2026年は--mount構文を推奨。-v db_data:/pathは「volumeなのか./db_data:/path(bind mount)なのか」が書いた場所の先頭パスでしか判別できず、事故が起きやすい。--mount type=volume,source=...なら意図が明示され、tmpfsやNFS driverも同じ構文で扱えます。
volumeの内部構造:/var/lib/docker/volumes/
Dockerのnamed volumeはホスト上の決まった場所に作られ、Dockerエンジンが管理します。これを知っていると障害時のデータ救出や移行が楽になります。
# Docker用ディレクトリ(Linuxの既定)
ls -la /var/lib/docker/volumes/
# 特定volumeの中身を見る(要sudo)
sudo ls -la /var/lib/docker/volumes/db_data/_data/
# → ibdata1 ib_logfile0 mysql/ performance_schema/ ...
# ボリュームの物理パスを確認
docker volume inspect db_data
# [
# {
# "CreatedAt": "2026-04-22T10:00:00+09:00",
# "Driver": "local",
# "Labels": null,
# "Mountpoint": "/var/lib/docker/volumes/db_data/_data",
# "Name": "db_data",
# "Options": null,
# "Scope": "local"
# }
# ]
macOS/Windows(Docker Desktop)の場合:volumeはホストOSではなくLinuxVM内(Hyper-V/WSL2/HyperKit)に作られます。そのため/var/lib/docker/volumes/をFinder/Explorerで開けません。中身を見るにはdocker run --rm -v db_data:/data alpine ls /dataのように一時コンテナ経由でアクセスするのが基本。
匿名volume(anonymous volume)
# Dockerfileの VOLUME 宣言やimage定義で自動作成される FROM mariadb:11 VOLUME /var/lib/mysql # 明示指定なしで起動すると勝手に匿名volumeが作られる docker run -d mariadb:11 # → 無名volumeが作られてデータが入る docker stop <cid> docker rm <cid> # → 匿名volumeは残るが「どれがどのコンテナのだったか」不明 # 一覧で名前がハッシュ値のがそれ docker volume ls # DRIVER VOLUME NAME # local 3f8d2a1c9b4e5f6a7b8c... ← 匿名volume
匿名volumeはゴミが溜まりがち。「誰が作ったか分からない」状態で残り続けDisk Fullを招くので、必ず明示的にnamed volumeで運用しましょう。定期的にdocker volume ls -qf dangling=trueで孤児volumeを洗い出し、docker volume pruneで掃除を。
マウントタイプ5種の完全比較
# named volume docker run --mount type=volume,source=db_data,target=/var/lib/mysql ... # bind mount docker run --mount type=bind,source="$(pwd)/conf",target=/etc/conf,readonly ... # tmpfs(メモリ、コンテナ終了で消える) docker run --mount type=tmpfs,target=/tmp,tmpfs-size=100m ... # read-only volume docker run --mount type=volume,source=config,target=/etc/app,readonly ...
どれを選ぶか
- DB/永続データ:named volume(第一選択)
- ソース/nginx.conf等:bind mount
- 一時I/O/秘密展開:tmpfs
- 複数ホスト共有:NFS driver付きvolume
- クラウド運用:EBS/Azure Files driver
volume CLI操作完全リファレンス
# 作成(labels/driver_optsで高度化) docker volume create db_data docker volume create \ --label env=production \ --label app=myapp \ db_data_prod # 一覧+フィルタ docker volume ls docker volume ls --filter "label=env=production" docker volume ls --filter "name=db_" docker volume ls -qf dangling=true # 孤児(未使用)のみ # 詳細(Mountpoint/Options/Labels) docker volume inspect db_data # 削除 docker volume rm db_data docker volume rm $(docker volume ls -qf dangling=true) # 孤児一括削除 # 未使用volume一括削除(prune) docker volume prune # 2026年推奨:labelsでフィルタして誤削除防止 docker volume prune --filter "label!=keep=true"
volumeの中身を覗く(ホストから直接触らない)
# 既存volumeの中身を一覧 docker run --rm -v db_data:/data alpine ls -la /data # 特定ファイルをcat docker run --rm -v db_data:/data alpine cat /data/server.cnf # volumeにファイルを投入 docker run --rm -v db_data:/data -v "$(pwd):/src" \ alpine cp /src/myfile /data/ # volume内をシェルで触りたい docker run --rm -it -v db_data:/data alpine sh
/var/lib/docker/volumes/配下を直接viやrmするのは非推奨。ファイル所有者/SELinuxコンテキスト/Dockerの管理情報と不整合が起きる可能性。必ず一時コンテナ経由(docker run --rm -v ...)か専用コンテナ内から操作しましょう。
Composeでのvolume定義完全版
services:
db:
image: mariadb:11
volumes:
# ① named volume(top-levelで定義)
- db_data:/var/lib/mysql
# ② bind mount(相対パス)
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
# ③ --mount形式(明示的で推奨)
- type: volume
source: db_backup
target: /backup
volume:
nocopy: true # 既存volume内容を優先
# ④ tmpfs(メモリ)
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 104857600 # 100MB
# ⑤ read-only bind mount
- type: bind
source: ./conf
target: /etc/conf
read_only: true
volumes:
# 基本定義
db_data:
# ラベル付与(クリーンアップ時の保護に有用)
db_backup:
labels:
env: "production"
app: "myapp"
keep: "true"
# 外部で事前作成したvolumeを使う
shared_data:
external: true
name: legacy_shared_data # 既存名前指定
# driver_optsでNFS等の高度マウント
nfs_data:
driver: local
driver_opts:
type: nfs
o: "addr=10.0.0.100,rw,nfsvers=4"
device: ":/export/data"
Compose関連のvolumeオプション
external: true:Compose外で作成済みのvolumeを参照(事故で消えない)name: "xxx":自動プレフィックス(プロジェクト名)を付けずに固定名labels::運用メタデータ。prune --filterで誤削除防止driver:/driver_opts::ローカル以外のストレージnocopy: true:既存volume内容を上書きしない(初回マウント制御)
volume driver:ローカル以外のストレージ連携
NFS(ネットワーク共有)
volumes:
shared:
driver: local
driver_opts:
type: nfs
o: "addr=192.168.1.100,rw,nfsvers=4"
device: ":/exports/docker"
# mount(8)コマンドの互換性
# type / o / device が mount の -t / -o / <src> に対応
cifs/samba(Windows共有)
volumes:
winshare:
driver: local
driver_opts:
type: cifs
o: "username=user,password=pass,uid=1000,gid=1000"
device: "//192.168.1.50/share"
AWS EBS/Azure Files(クラウドストレージ)
# REX-Ray (legacy) や Docker公式 CSI pluginを使用 # Kubernetesへ移行するなら各CSIドライバを推奨 # 例: AWS EBSプラグイン docker plugin install rexray/ebs REXRAY_PREEMPT=true \ EBS_ACCESSKEY=... EBS_SECRETKEY=... docker volume create --driver rexray/ebs \ --opt size=10 \ --opt volumetype=gp3 \ ebs_data
クラウド統合は2026年ではKubernetes CSIが主流
単発DockerホストでAWS EBS/Azure Diskを直接マウントする需要は減少し、Kubernetes+CSIドライバでの運用が一般的になりました。Dockerのdriver_optsで間に合う規模(単一ホスト、NFS程度)なら今でも便利ですが、複数ホスト/可用性が必要ならKubernetesへの移行を検討してください。
tmpfs driver(メモリ上の永続化風)
services:
app:
volumes:
- type: tmpfs
target: /app/cache
tmpfs:
size: 256M
mode: 0755
# メモリ上なので超高速、コンテナ再起動で消える
# 秘密鍵の一時展開、セッションデータ等に最適
backup/restore:volumeデータを守る7パターン
volumeは永続化が目的ですが、それ自体が消える(プルーンミス/ホスト障害/人為ミス)可能性があります。日次バックアップの組み込みが実運用の前提。
①tar を使ったシンプルバックアップ(万能パターン)
#!/usr/bin/env bash
# volumeをtar.gzに固める
set -euo pipefail
VOLUME="db_data"
OUT="./backup/${VOLUME}_$(date +%Y%m%d_%H%M).tar.gz"
mkdir -p ./backup
docker run --rm \
-v "$VOLUME":/data:ro \
-v "$(pwd)/backup":/backup \
alpine tar czf "/backup/$(basename $OUT)" -C /data .
echo "Backup: $OUT"
# 7日以上前の削除
find ./backup -name "*.tar.gz" -mtime +7 -delete
②tarによるrestore
#!/usr/bin/env bash set -euo pipefail VOLUME="db_data" ARCHIVE="$1" # 新規volumeを作成 docker volume create "$VOLUME" # アーカイブを展開 docker run --rm \ -v "$VOLUME":/data \ -v "$(pwd)/$(dirname $ARCHIVE)":/backup:ro \ alpine tar xzf "/backup/$(basename $ARCHIVE)" -C /data echo "Restored: $ARCHIVE → $VOLUME"
③MySQL/MariaDB専用のmysqldump方式
# volumeレベルのtarよりDBレベルのdumpが安全 # → 整合性チェック済み/クロスバージョン対応 docker compose exec db mysqldump \ --single-transaction \ --routines --triggers --events \ -u root -proot mydb | gzip > backup_$(date +%Y%m%d).sql.gz # リストア gunzip -c backup_20260422.sql.gz | \ docker compose exec -T db mysql -u root -proot mydb
④PostgreSQL専用のpg_dump方式
# バックアップ(カスタム形式、高速並列リストア可) docker compose exec postgres pg_dump -U app -F c -b -f /tmp/backup.dump mydb docker compose cp postgres:/tmp/backup.dump ./backup_$(date +%Y%m%d).dump # リストア docker compose cp ./backup.dump postgres:/tmp/ docker compose exec postgres pg_restore -U app -d mydb -j 4 /tmp/backup.dump
⑤Docker Compose含みのフルバックアップ
#!/usr/bin/env bash
# 全volumeを個別tarに
set -euo pipefail
BACKUP_DIR="./backup/$(date +%Y%m%d_%H%M)"
mkdir -p "$BACKUP_DIR"
for vol in $(docker compose config --volumes); do
FULL_NAME="$(basename $(pwd))_${vol}"
docker run --rm \
-v "$FULL_NAME":/data:ro \
-v "$(pwd)/$BACKUP_DIR":/backup \
alpine tar czf "/backup/${vol}.tar.gz" -C /data .
echo "✓ $vol → ${vol}.tar.gz"
done
# compose.yml, .env 等もコピーして完全復元できるように
cp compose.yml .env "$BACKUP_DIR/"
echo "Full backup: $BACKUP_DIR"
⑥バックアップ専用volumeへdockerコンテナからtar出力
services:
db:
image: mariadb:11
volumes:
- db_data:/var/lib/mysql
backup:
image: alpine:latest
profiles: ["backup"]
volumes:
- db_data:/data:ro
- ./backup:/backup
command: |
sh -c "tar czf /backup/db_$(date +%Y%m%d).tar.gz -C /data ."
# 実行
# docker compose --profile backup run --rm backup
⑦AWS S3への自動アップロード
#!/usr/bin/env bash
# backup-to-s3.sh
set -euo pipefail
STAMP=$(date +%Y%m%d_%H%M)
LOCAL="./backup/db_${STAMP}.tar.gz"
S3_PATH="s3://mycompany-backup/docker-volumes/db_${STAMP}.tar.gz"
mkdir -p ./backup
docker run --rm \
-v db_data:/data:ro \
-v "$(pwd)/backup":/backup \
alpine tar czf "/backup/db_${STAMP}.tar.gz" -C /data .
aws s3 cp "$LOCAL" "$S3_PATH" --storage-class STANDARD_IA
# 過去30日分は自動で消す(S3ライフサイクルポリシーでも可)
aws s3 ls s3://mycompany-backup/docker-volumes/ | \
awk '$1 < "'$(date -d "30 days ago" "+%Y-%m-%d")'" {print $4}' | \
xargs -I{} aws s3 rm "s3://mycompany-backup/docker-volumes/{}"
推奨の組み合わせ:①開発環境:パターン①(tar)+profilesのhelperコンテナ、②本番DB:アプリレベル(③mysqldump/④pg_dump)+S3アップロード(⑦)、③crontabで日次3時、S3ライフサイクルで30日保持。GitHub Actionsでのスケジュール実行も可:【GitHub】Actions完全ガイドのscheduleセクション参照。
ホスト間移行:本番↔ステージング間でvolumeを移動
# ソース側ホストで docker run --rm \ -v db_data:/data:ro \ alpine tar czf - -C /data . \ | ssh user@destination "cat > /tmp/db_data.tar.gz" # デスティネーション側ホストで docker volume create db_data docker run --rm \ -v db_data:/data \ -v /tmp/db_data.tar.gz:/backup/db_data.tar.gz:ro \ alpine tar xzf /backup/db_data.tar.gz -C /data # 中間ファイル削除 ssh user@destination "rm /tmp/db_data.tar.gz"
# tar→ssh→tarの直結パイプライン docker run --rm -v db_data:/data:ro alpine tar czf - -C /data . | \ ssh user@destination \ "docker run --rm -i -v db_data_new:/data alpine tar xzf - -C /data" # 事前にデスティネーション側で # docker volume create db_data_new を実行しておくこと
DBのvolumeを稼働中コンテナからcopyするとデータ不整合を起こします。移行前に必ずdocker compose stop dbか、アプリレベルダンプ(mysqldump/pg_dump)を使ってください。稼働中のInnoDBをtarで固めると起動時にCorrupt pageエラーが頻発します。
権限問題(UID/GID)とその解決
volumeの中のファイル所有者はコンテナ内プロセスのUIDが記録されます。ホストから見ると「知らないUID」になり、bind mount併用時やvolume中身を直接触る時にPermission deniedが頻発する典型的トラブルです。
# volume内ファイルの所有者確認
docker run --rm -v db_data:/data alpine ls -la /data
# drwxr-xr-x 1 999 999 ... ← UID 999 = mysql / mariadb
# コンテナ内プロセスのUID確認
docker compose exec db id
# uid=999(mysql) gid=999(mysql) groups=999(mysql)
# ホストユーザーと合わせたい場合
docker run --rm \
--user "$(id -u):$(id -g)" \
-v mydata:/data alpine touch /data/test
# Composeでuser指定
services:
app:
user: "1000:1000" # ホストと合わせる
既存volumeの所有者を一括変更
# 間違えた所有者を全ファイル変更 docker run --rm -v db_data:/data alpine chown -R 999:999 /data
PUID/PGIDパターン(LinuxServer.io流)
LinuxServer.io系のイメージはPUID/PGID環境変数でプロセスUIDを実行時に変更できる設計。ホストのUIDを指定するとbind mount時の権限問題がゼロに。自作イメージでもentrypointスクリプトでusermodするパターンを採用すると便利です。
read-only/SELinux/propagationオプション
# 読み取り専用 docker run -v config_vol:/etc/app:ro ... # --mount 構文 docker run --mount type=volume,source=config_vol,target=/etc/app,readonly ... # SELinux共有ラベル(Fedora/RHEL/CentOS) docker run -v db_data:/var/lib/mysql:z ... # 共有 docker run -v db_data:/var/lib/mysql:Z ... # プライベート # z/Zを付けないとSELinux環境で Permission denied # bind mountのpropagation(ホスト/コンテナ間での伝播) docker run --mount type=bind,source=/host,target=/container,bind-propagation=rslave ... # private / rprivate / shared / rshared / slave / rslave # consistent / cached / delegated (macOS/Windows向き高速化) docker run -v "$(pwd)":/app:delegated ... # macOSで大規模fs高速化
macOS/Windowsでbind mountが遅い時は:delegatedまたは:cachedを付けると劇的に速くなります。:delegatedは「コンテナ側の変更が優先」、:cachedは「ホスト側の変更が優先」というconsistency制御です。named volumeの場合はもともと高速なのでこれらのオプションは不要。
クリーンアップ戦略:labelsで事故を防ぐ
docker volume pruneはコンテナから参照されていないvolumeを全削除します。稼働していないバックアップ用volumeや、一時的にstopしているコンテナのvolumeも対象になり得るため誤削除の事故が多発します。labels+filterで安全に運用しましょう。
# ❌ 危険:全孤児を削除 docker volume prune # ⭕ 安全:keepラベル付きは除外 docker volume prune --filter "label!=keep=true" # ⭕ より安全:特定ラベルのみ削除対象 docker volume prune --filter "label=ephemeral=true" # ⭕ 確認プロンプトなしで実行(CI向け) docker volume prune -f --filter "label=ephemeral=true"
# 作成時にラベル付与
docker volume create \
--label env=production \
--label keep=true \
--label app=myapp \
db_data_prod
# Composeでラベル
volumes:
db_data:
labels:
env: "production"
keep: "true"
運用ベストプラクティス:①本番・ステージングの永続volumeにはkeep=true必ず付与、②テスト用・一時用にはephemeral=true付与、③prune時は必ず--filter "label=ephemeral=true"指定、④定期的にdocker volume ls --filter "dangling=true"で孤児確認、⑤本番volume変更前にバックアップ取得。
よくあるトラブルと対処
①volumeをマウントしたのに空
原因はvolumeの初期化タイミング。新規volumeをマウントした最初のコンテナ起動時のみ、コンテナイメージ内の対象パスのファイルがvolumeにコピーされます。既存volumeがあった場合はvolumeの内容が優先されるため「空」のvolumeを使うと中身がない。解決:一度docker volume rmして再作成するか、既存データをtar経由で投入。
②Permission denied
# SELinux(Fedora/RHEL/CentOS) docker run -v ./data:/data:z ... # :z で共有モード # UID不一致 docker run --user "$(id -u):$(id -g)" ... docker run -v my_vol:/data alpine chown -R 1000:1000 /data # bind mount専用の回避策 chmod -R 777 ./bind_dir # 開発中のみ(本番NG)
③DiskがFull
# Docker全体の使用量 docker system df docker system df -v # 詳細(volumeごとのサイズ) # 特定volumeのサイズ docker run --rm -v my_vol:/data alpine du -sh /data # 全未使用データ削除(注意:開発用のみ) docker system prune -a --volumes
④macOS/Windowsでパフォーマンスが遅い
bind mountはmacOS/Windowsで遅いのが既知の問題。named volumeに切替、:delegated/:cached付与、node_modulesやvendorのような重いディレクトリはanonymous volumeで上書き、Docker Desktopのファイル共有設定でVirtioFS(macOS)/WSL2(Windows)を使うと劇的改善。
⑤誤ってdocker volume pruneでデータ喪失
バックアップからしか復旧できません。日次でtar/mysqldump/pg_dumpをS3等に送っていれば数分で戻せます。取ってなかった場合はextundeleteやtestdiskでDocker用ディスクから削除済みファイルサルベージを試みる最終手段のみ。本記事「backup/restore」セクションのパターン①④⑦を必ず運用に組み込みましょう。
よくある質問
docker rmしても残る)。明示的にdocker volume rmするか、docker compose down -vで削除しない限り保持されます。匿名volumeはdocker rm -vで一緒に消えるが、named volumeは別管理と覚えてください。docker run --rm -it -v my_vol:/data alpine shで一時コンテナ経由でアクセスするか、既存コンテナ内でdocker compose exec service bashで入ってください。/var/lib/docker/volumes/xxx/_dataを直接vi/rmするとSELinux/UIDの整合が取れなくなります。./data:/var/lib/mysqlのようにbind mountでDBを持たせると、①OS依存(Windows/macOSでパフォーマンス劣化)、②UID/GID問題、③prune対象外で管理しづらい、④ホスト側エディタで誤編集して壊す、などのリスク。本番DBは必ずnamed volumeにしてください。tar czf - | ssh user@dest "tar xzf - -C ..."のパイプライン1行で完結します。稼働中のDBコンテナはstop+mysqldumpでアプリレベル転送が安全。cifsdriverでusername/password指定が楽。どちらもdriver_opts.oにsec=krb5やusername=...を指定します。クラウドはCSIドライバ+IAMでの認証に移行するのが2026年的。docker rm $(docker ps -aq)でexit状態のコンテナを先に削除してからdocker volume pruneすれば消えます。kompose convertでcompose.ymlをマニフェストに変換できますが、volume部分は手動調整が必要。データ本体はtar→NFS/EBSに移してPVでマウントする形が典型です。docker volume ls -qf "dangling=true"で孤児を洗い出し、docker volume rm $(docker volume ls -qf "dangling=true")で一括削除。イメージのVOLUME宣言(VOLUME /var/lib/mysql等)がある場合、compose.ymlで必ずnamed volumeを指定しておくと新規作成が防げます。関連記事
- 【Docker】bind mountとvolumeの違いと使い分け — マウント方式の選定フレーム
- 【Docker】Compose完全ガイド — volumes top-level定義とservice連携
- 【Docker】WordPress環境構築完全ガイド — WP特化のvolume戦略(wp-content/DB)
- 【Docker】MySQL CLI完全ガイド — mysqldumpによるアプリレベルバックアップ
- 【Docker】Nginxローカル開発環境構築完全ガイド — 設定ファイル用のマウント
- 【Docker】Nginx + PHP-FPM完全ガイド — PHPアプリのvolume構成
- 【保存版】Docker Desktopが「Docker Desktop stopped」で起動できない時の完全解決ガイド — Docker起動トラブル
- 【GitHub】Actions完全ガイド — 定時バックアップスクリプトのCI統合
まとめ
- コンテナのデータ永続化はnamed volumeが第一選択
- 実体は
/var/lib/docker/volumes/<name>/_data(macOS/WinはVM内部) - マウント5種:named/anonymous/bind/tmpfs/npipe、用途で選ぶ
- 2026年推奨は
--mount type=volume,source=...,target=...構文(意図明示) - Composeでは
external: true/labels/driver_optsで運用管理 - NFS/cifs/EBS等は
driver_optsで接続、ただしマルチホストはK8s推奨 - バックアップ7パターン:tar/アプリダンプ/helperコンテナ/S3を使い分け
- ホスト間移行は
tar | ssh | tarの1行パイプで完結(DBはstop or ダンプ必須) - UID/GID問題は
--user/chown/PUID/PGIDで解決 - SELinuxは
:z/:Z、macOS/Win遅延は:delegated - 誤削除防止はlabels+
prune --filterで物理的に守る - ディスク枯渇時は
docker system df -vで診断→個別削除
volumeは「データを失わないための基盤」として、本番/開発を問わず必須のコンポーネント。本記事のバックアップ7パターンとホスト間移行手順をスクリプト化しておけば、人為ミス・ホスト障害・クラウド移行のいずれでも数分でデータを復旧できます。bind mountとの使い分け、Composeでの運用、mysqldumpアプリレベルバックアップと組み合わせて、堅牢なコンテナ運用基盤を作ってください。

