コンテナにデータを持たせる方法はDockerに3種類あります。named volume、bind mount、そしてtmpfsです。それぞれ用途が明確に異なるのに、とりあえずbind mountで済ませているケースを現場でもよく見かけます。
この記事では、bind mountとtmpfsの仕組みと使い方を実行例とともに解説し、named volumeを含めた3種類のマウント種別をどのような基準で選ぶかを整理します。RHEL 9.4 / Ubuntu 24.04 LTS、Docker 27.x で動作確認済みです。
この記事のポイント
・bind mountはホストのパスをコンテナに直接共有する(ホストに残るが可搬性は低い)
・tmpfsはメモリ上の一時領域でコンテナ停止と同時にデータは消える(機密データ向き)
・バックアップが必要なデータはnamed volume、ホスト連携はbind mount、機密一時データはtmpfs
・選定基準は「永続性・ホスト依存・バックアップ・セキュリティ」の4軸で決める
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Dockerのマウント種別と3つの選択肢
Dockerがコンテナにデータを持たせる方法は3種類に分かれます。・named volume:Dockerが管理する永続領域。ホストの実パスを意識しなくてよい
・bind mount:ホストの任意のパスをコンテナにそのままマウントする
・tmpfs:ホストのメモリ上に一時領域を作り、コンテナだけが使う
大ざっぱに言うと「消えてもいいデータはtmpfs、ホストと共有したいファイルはbind mount、Dockerに管理させる永続データはnamed volume」です。以降ではbind mountとtmpfsに絞って、それぞれの仕組みと適性を具体的に解説します。
bind mountの仕組みと使い方
bind mountは、ホストOS上の特定のパスをコンテナの指定パスに重ね合わせる機能です。Linuxカーネルの bind マウントと同じ仕組みで動いており、コンテナからファイルを書き換えるとホスト側にもリアルタイムで反映されます(mount コマンドの使い方も参照してください)。1. bind mountの基本構文
bind mountを指定するには--mount オプションを使います。古い -v フラグより記述が明示的で、読み取り専用指定も簡単です。# 書き込み可能なbind mount $ docker run --rm \ --mount type=bind,source=/srv/app/logs,target=/app/logs \ myapp:latest # 読み取り専用のbind mount(設定ファイルの配布に使う) $ docker run --rm \ --mount type=bind,source=/srv/app/config,target=/app/config,readonly \ myapp:latest ls /app/config app.yaml db.yaml
source にはホストの絶対パスを指定します。相対パスは使えません。readonly を付けるとコンテナ内からの書き込みを禁止でき、設定ファイルの誤更新を防げます。現在のコンテナにどのマウントが適用されているかは
docker inspect で確認できます。$ docker inspect myapp-container --format '{{json .Mounts}}' | python3 -m json.tool [ { "Type": "bind", "Source": "/srv/app/config", "Destination": "/app/config", "Mode": "", "RW": false, "Propagation": "rprivate" } ]
"RW": false なら読み取り専用、true なら書き込み可能です。2. bind mountが向くユースケース
bind mountが最もよく使われる場面は以下の3つです。・開発中のソースコード共有:ホスト側でエディタを使いながら、コンテナ内でリアルタイムにビルドや実行ができる
・設定ファイルの注入:nginx.confやapp.yamlをホストで管理し、readonlyでコンテナに渡す
・ログの外部保存:コンテナが出力するログをホストの特定ディレクトリに直接書き出す
開発環境でのソースコード共有の例です。
# ホストのsrcディレクトリをコンテナにマウントして開発サーバーを起動 $ docker run -d \ --name dev-server \ --mount type=bind,source=$(pwd)/src,target=/app/src \ -p 8080:8080 \ node:20-alpine npm run dev # ホスト側でファイルを編集すると、コンテナ内にも即座に反映される $ echo "console.log('updated');" >> src/index.js
3. bind mountの権限と注意点
bind mountにはホストとコンテナのUID/GIDが一致しないと権限エラーになる問題があります。# ホストのディレクトリがroot所有の場合、コンテナ内の一般ユーザーはアクセスできない $ ls -la /srv/app/data drwxr-x--- 2 root root 4096 Sep 7 10:00 /srv/app/data $ docker run --rm \ --mount type=bind,source=/srv/app/data,target=/data \ --user 1000:1000 \ alpine ls /data ls: /data: Permission denied
・ホスト側のディレクトリの所有者・パーミッションをコンテナ実行ユーザーに合わせる
・Dockerfileで
USER 命令を使ってコンテナ内のユーザーをホストに合わせるまた、bind mountをDocker Composeから扱う場合は
volumes セクションで以下のように書きます。# docker-compose.yml(bind mount) services: app: image: myapp:latest volumes: - type: bind source: ./config target: /app/config read_only: true
tmpfsの仕組みと使い方
tmpfsはホストのメモリ(RAM)上に一時的なファイルシステムを作り、コンテナのみが使える領域を提供します。コンテナが停止・削除されると同時にデータは完全に消えます。ディスクに書き出されないため、パスワードやAPIキーなどの機密情報を一時的に保持する用途に適しています。1. tmpfsマウントの基本構文
# サイズ上限64MB、パーミッション0700でtmpfsをマウント $ docker run --rm \ --mount type=tmpfs,target=/run/secrets,tmpfs-size=67108864,tmpfs-mode=0700 \ myapp:latest df -h /run/secrets Filesystem Size Used Avail Use% Mounted on tmpfs 64M 0 64M 0% /run/secrets
・tmpfs-size:バイト単位でサイズ上限を指定する。省略するとホストのメモリ量の半分が上限になる
・tmpfs-mode:マウントポイントのパーミッションを8進数で指定する(省略時は
1777)Docker Composeでは以下のように記述します。
# docker-compose.yml(tmpfs) services: app: image: myapp:latest volumes: - type: tmpfs target: /run/secrets tmpfs: size: 67108864 mode: 0700
2. tmpfsが向くユースケース
tmpfsが実務で役立つ場面は次の3つです。・機密データの一時保持:起動時に渡したシークレット(APIキー・証明書)をディスクに書かずにメモリだけで処理する
・高速な一時ファイル処理:/tmpをtmpfsにすることで、ディスクI/Oを伴う一時ファイル処理を高速化する
・セッションキャッシュ:短命なWebアプリのセッションデータなど、再起動後に捨ててよい情報を保持する
bind mountやtmpfsの使い分けを含め、Dockerの設計ノウハウを体系的に習得したい方は、以下のDocker講座をご覧ください。
→ Dockerマスター講座の詳細はこちら >>
3. サイズ上限と機密データへの活用
tmpfsはサイズ上限を明示的に設定することを強く推奨します。上限なしでは、コンテナが大量のデータを書き込んだ場合にホストのメモリを圧迫します。# tmpfsが実際にメモリ上にあることをコンテナ内から確認する $ docker run --rm \ --mount type=tmpfs,target=/run/secrets,tmpfs-size=33554432,tmpfs-mode=0700 \ alpine sh -c " echo 'my-secret-token' > /run/secrets/api_key cat /run/secrets/api_key mount | grep secrets " my-secret-token tmpfs on /run/secrets type tmpfs (rw,nosuid,nodev,noexec,relatime,size=32768k,mode=700)
なお、Dockerの
--secret オプション(Swarm/Compose対応)を使うと、秘密情報のマウントをより宣言的に扱えます。tmpfsを直接指定する方法と --secret は相補的に使えます。named volumeと3つのマウント種別の違い
3種類のマウント種別を比較した一覧表です。| 項目 | named volume | bind mount | tmpfs |
|---|---|---|---|
| データの永続性 | コンテナ削除後も残る | コンテナ削除後も残る | コンテナ停止で消える |
| ホストのパス依存 | なし(Dockerが管理) | あり(ホストパス指定必須) | なし |
| ホスト側からの直接編集 | 難しい(内部パス経由) | しやすい | できない |
| バックアップ適性 | 高(docker volume export) | 中(ホストのバックアップに依存) | 不可(一時データのため) |
| パフォーマンス | 高(OverlayFSを使わない) | 高(OverlayFSを使わない) | 最高(メモリI/O) |
| セキュリティ | 標準 | ホストのパーミッションに依存 | 高(ディスクに書かない) |
| 複数ホスト間の共有 | プラグイン経由で可能 | 困難 | 不可 |
| 主な用途 | DBデータ・アプリ永続データ | 設定ファイル・ログ・ソースコード | 機密一時データ・高速一時処理 |
/var/lib/docker/volumes/ 以下を自動管理するため、ホストのパス構成に依存しません。本番DBのデータ領域など、確実に永続化したいデータに向いています。マウント種別の選定フロー
「どのマウント種別を選べばいいか」は以下の4つの質問に答えることで決まります。質問1:コンテナ停止後もデータを残す必要があるか?
→ NO → tmpfs を使う
→ YES → 質問2へ
質問2:ホスト側でファイルを直接編集・参照したいか?
→ YES → bind mount を使う
→ NO → 質問3へ
質問3:バックアップや複数ホスト間での共有が必要か?
→ YES → named volume を使う
→ NO → named volumeまたはbind mount(どちらでも可)
質問4(セキュリティ補足):機密情報(APIキー・証明書)を一時的に扱うか?
→ YES → tmpfsを検討する(ディスクに書かない設計が安全)
開発環境と本番環境では使い分けが変わることも覚えておいてください。
・開発環境:ソースコードをbind mount → 変更がリアルタイムに反映されて便利
・本番環境:アプリのコードはイメージに焼き込み、設定ファイルだけbind mount(readonlyで)
本番でソースコードをbind mountしているのは、コンテナの再現性を失う設計なので注意が必要です。
トラブルシュート:よくあるエラーと対処法
1. 「invalid mount config for type bind: bind source path does not exist」
bind mountで指定したホスト側のパスが存在しない場合に出るエラーです。# エラー例 $ docker run --rm \ --mount type=bind,source=/srv/app/nonexistent,target=/data \ alpine ls /data docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /srv/app/nonexistent. # 対処:ホスト側でディレクトリを先に作る $ mkdir -p /srv/app/nonexistent $ docker run --rm \ --mount type=bind,source=/srv/app/nonexistent,target=/data \ alpine ls /data
-v フラグはホストパスが存在しない場合にディレクトリを自動作成しますが、--mount は作成しません。--mount を使う場合は事前に mkdir -p でパスを用意しておきます。2. 「Permission denied」(権限エラー)
コンテナのプロセスユーザーとホストのディレクトリ所有者が一致しない場合に起きます。# エラー確認 $ docker run --rm \ --mount type=bind,source=/srv/app/data,target=/data \ --user 1001:1001 \ alpine touch /data/test.txt touch: /data/test.txt: Permission denied # 対処:ホスト側のオーナーをコンテナのUIDに合わせる $ sudo chown 1001:1001 /srv/app/data $ docker run --rm \ --mount type=bind,source=/srv/app/data,target=/data \ --user 1001:1001 \ alpine touch /data/test.txt # エラーなし
3. tmpfsのサイズ超過
tmpfsのサイズ上限を超えてデータを書き込もうとすると、コンテナ内で「No space left on device」が発生します。# tmpfsのサイズを10MB(10485760バイト)に制限してテスト $ docker run --rm \ --mount type=tmpfs,target=/tmp/cache,tmpfs-size=10485760 \ alpine sh -c "dd if=/dev/zero of=/tmp/cache/fill.dat bs=1M count=20" dd: /tmp/cache/fill.dat: No space left on device # 対処:tmpfs-sizeを増やすか、書き込むデータ量を減らす $ docker run --rm \ --mount type=tmpfs,target=/tmp/cache,tmpfs-size=104857600 \ alpine sh -c "dd if=/dev/zero of=/tmp/cache/fill.dat bs=1M count=20 && echo 'OK'" 20+0 records in 20+0 records out OK
本記事のまとめ
マウント種別の選定基準の早見表です。| やりたいこと | 推奨マウント種別 |
|---|---|
| DBデータやアプリデータを永続化する | docker run --mount type=volume,source=mydata,target=/data |
| 設定ファイルをホストから読み取り専用で渡す | docker run --mount type=bind,source=/etc/myapp,target=/app/config,readonly |
| 開発中のソースコードをリアルタイムに共有する | docker run --mount type=bind,source=$(pwd)/src,target=/app/src |
| 機密データをメモリだけで処理する(ディスクに書かない) | docker run --mount type=tmpfs,target=/run/secrets,tmpfs-mode=0700 |
| 高速な一時ファイル処理(/tmpを高速化する) | docker run --mount type=tmpfs,target=/tmp,tmpfs-size=134217728 |
・bind mountは「ホストと直接やり取りしたい」場面に使う。開発中のソースコード共有・設定ファイル注入・ログ外部保存が主な用途
・tmpfsは「コンテナ停止で消えていい一時データ」に使う。機密情報のメモリ処理と一時ファイルの高速化が主な用途
・named volumeは「Dockerに永続管理を任せる」場面に使う。DBデータや本番アプリのデータ領域が主な用途
・権限設計でつまずく場合はUID/GIDの不一致が原因であることが多い。コンテナのユーザーとホストのパーミッションを先に確認する
次に読む記事
・Dockerのログ運用設計|loggingドライバとjson-fileローテーションで肥大化を防ぐ方法
・Dockerコンテナのリソース制限と監視|--memory・--cpusとdocker statsでホストを守る設計
・docker system pruneでディスク容量を管理する方法|overlay2肥大の原因調査と安全な削除手順
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、bind mountとtmpfsの使い分けを含めたDockerのデータ設計まで体系的に学べるDocker講座を用意しています。
→ Dockerマスター講座の詳細はこちら >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:PostgreSQLコンテナをDocker Composeで運用する設計|データ永続化と初期化スクリプト、ダンプ取得の実務
- この記事の属するカテゴリ:Dockerへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます