はじめに
Docker コンテナを docker rm すると、コンテナ内だけに置いたファイルは消えます。
Web サーバーの HTML やログなど、残したいデータは ホスト側 に置く必要があります。
この記事では --volume(bind mount) を使い、ホストのファイルやディレクトリをコンテナに載せ、コンテナを削除してもデータが残ることを WSL2 上で確認します。
この記事でやることは次のとおりです。
-
--volume/-vの書き方(ホスト:コンテナ)を理解する - nginx にホストの
index.htmlをマウントして表示を差し替える - busybox でコンテナ内からファイルを作り、ホストに残ることを確認する
※ この記事では、Ubuntu 環境のターミナルで Docker CLI を実行します。Dockerfile の COPY でイメージにファイルを焼き込む方法は、シリーズ ③ Dockerfile と主要命令を使ったイメージのビルド を参照してください。本記事では 実行中のマウント に絞ります。
環境設定につきましては以下の記事を参考にしてください。
Volume(bind mount)とは
docker run の -v(--volume)で、ホスト上のパス と コンテナ内のパス を対応づけます。
-v ホストパス:コンテナパス
コンテナから見えるマウント先は、ホスト上の実ファイル・実ディレクトリを指します。コンテナを削除しても、ホスト側のデータは残ります。
ホスト(WSL)の index.html ←──マウント── コンテナ内 /usr/share/nginx/html/index.html
全体の流れ
- nginx + ホスト
index.htmlの bind mount(Web 表示の差し替え) - busybox + カレントディレクトリの bind mount(ファイル作成の永続化)
- クリーンアップ
実際に試してみる — nginx にホストの HTML を載せる
ファイルを準備する
mkdir -p ~/hands-on/volume_demo/web
cd ~/hands-on/volume_demo/web
echo "Hello from host volume" > index.html
cat index.html
出力例:
Hello from host volume
--volume で nginx を起動する
docker run -d \
--volume "$(pwd)":/usr/share/nginx/html:ro \
-p 8090:80 \
--name demo-web \
nginx
コマンドの意味
| 部分 | 意味 |
|---|---|
--volume "$(pwd)":/usr/share/nginx/html:ro |
今いるホストディレクトリを nginx の HTML 配信先に 読み取り専用 でマウント |
-p 8090:80 |
ブラウザは http://localhost:8090
|
--name demo-web |
コンテナ名 |
表示を確認する
curl localhost:8090
出力例:
Hello from host volume
ホスト側を書き換えて再確認する
コンテナを作り直さず、ホストのファイルだけ 更新します。
echo "Updated on host only" > index.html
curl localhost:8090
出力例:
Updated on host only
マウント先は同じ実ファイルを指しているため、コンテナ内を exec しなくても表示が変わります。
片付け
docker stop demo-web
docker rm demo-web
busybox でコンテナ内作成 → ホストに残ることを確認する
Web 以外でも、コンテナ内で作ったファイルがホストに残る ことを確認します。
作業ディレクトリを用意する
mkdir -p ~/hands-on/volume_demo/data
cd ~/hands-on/volume_demo/data
ls
bind mount 付き busybox を起動する
docker run -d -v "$(pwd)":/data --name demo-busy --rm busybox sleep 500
コンテナ内でファイルを作成する
docker exec -it demo-busy sh
# プロンプト(コンテナ内)で:
cd /data
echo "created inside container" > from_container.txt
cat from_container.txt
exit
ホスト側にファイルがあることを確認する
ls
cat from_container.txt
出力例:
from_container.txt
created inside container
コンテナ削除後も残ることを確認する
docker rm -f demo-busy
ls
cat from_container.txt
demo-busy は削除されても、ホストの from_container.txt は残ります。
出力例:
from_container.txt
created inside container
WSL でのパス選び
| パス | 用途 |
|---|---|
~/hands-on/...(WSL 内) |
推奨。bind mount が安定しやすい |
/mnt/c/Users/... |
Windows 側ファイルを直接載せたいとき。I/O が遅い・権限でハマることがある |
演習では、まず WSL 内パス で進めるのが無難です。
bind mount と named volume(補足)
本記事の -v ホストパス:コンテナパス は bind mount です。ホスト上の決まったパスをそのまま載せます。
Compose や本番では、Docker が管理する named volume(docker volume create)を使うこともあります。永続化の考え方は同じで、「コンテナの外にデータの置き場を用意する」点は共通です。
まとめ
この記事では、--volume を使ってホスト側のデータをコンテナに載せ、コンテナ削除後も残ることを確認しました。
- コンテナ内だけの変更は、コンテナ削除とともに消えやすい
-
--volume ホスト:コンテナでホストのファイル・ディレクトリをコンテナに載せられる - ホスト側を更新すると、マウント経由でコンテナの振る舞いも変わる
- WSL では
~/...の Linux パスでの演習が扱いやすい
参考
本記事を作成するうえで、以下の資料を参考にさせていただきました。
株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。
ご興味がある方は是非下記のリンクをご覧ください: