午前2時の本番環境アラートデプロイは成功し、ヘルスチェックもパスしました。ようやくノートPCを閉じます。しかし10分後、監視アラートが鳴り始めます。ログを確認すると、コンテナがクラッシュループに陥っています。手動でコンテナを調査しようとすると、壁にぶつかります:
touch: cannot touch 'data.log': Read-only file system
このエラーは典型的なものです。rootユーザーであっても、自分のファイルシステムから締め出されてしまいます。通常、Dockerや基盤となるホストOSが、設定ミスやハードウェアの警告を理由に、ディスクへの書き込みはリスクが高すぎると判断したときに発生します。
クイック修正- マウントフラグを監査する: docker-compose.ymlを再確認してください。ボリューム文字列の末尾に誤って:roが付いていると、ディレクトリがロックされます。- ホストディスクの健全性をスキャンする: Linuxカーネルは、I/Oエラーを検出するとファイルシステムを読み取り専用として再マウントすることがよくあります。dmesg | grep -i "remount-ro"を実行して、ホストが故障しそうなドライブから自身を保護していないか確認してください。- Docker Engineを再起動する: MacやWindowsでは、Dockerを実行している仮想マシンが時折ハングすることがあります。Docker Desktopを素早く再起動することで、古いファイルロックが解消されることがよくあります。## 一般的な原因と解決策### 1. 明示的な読み取り専用マウント設定ミスは最も頻繁に起こる原因です。Dockerでは、コンテナ化されたプロセスからホストの機密データを保護するために、ボリュームを読み取り専用モードでマウントできます。ボリュームマッピングに:roサフィックスがないか探してください。
Docker Composeの例:
services:
app:
image: my-app:v2.1.0
volumes:
- ./configs:/app/config:ro # この 'ro' によりすべての書き込み操作が禁止される
修正方法: フラグを:rwに切り替えるか、完全に削除します。フラグが指定されていない場合、Dockerはデフォルトで読み書きアクセスになります。
- ./configs:/app/config:rw
2. ホストファイルシステムの破損Linuxカーネルがext4やxfsパーティションで重大なI/Oエラーに遭遇すると、緊急再マウントをトリガーします。この安全策はデータの破損を防ぎますが、ボリュームを読み取り専用ゾーンに変えてしまいます。これは、クラウドプロバイダーのブロックストレージに一時的な不具合が生じた際によく発生します。
すぐにホストのログを確認してください:
journalctl -k | grep -E "error|read-only"
'EXT4-fs error'が表示される場合は、ドライブをアンマウントしてfsckを実行する必要があるかもしれません。本番サーバーの場合は、クラウドコンソールでハードウェアの廃止通知やディスクの接続の問題がないか確認してください。
3. Docker Desktopのリソース制限 (Mac/Windows)Docker Desktopは隠れた仮想マシン内で動作しています。このVMは固定サイズ(通常はデフォルトで64GB)の仮想ディスクイメージ(通常はDocker.raw)を使用します。この仮想ディスクの容量が100%に達すると、データベースの破損を防ぐために内部ファイルシステムが読み取り専用モードに切り替わることがあります。
修正方法:
- Docker Desktop設定の「Disk usage」メーターを確認します。-
docker system prune -a --volumesを実行して未使用のデータを整理し、スペースを回収します。- ディスクイメージが破損している場合は、「Reset to factory defaults」オプションを使用します。これにより、ローカルのイメージとボリュームが消去されることに注意してください。### 4. SELinuxによる強制RHEL、Fedora、CentOSなどのセキュリティが強化されたシステムでは、SELinuxが特定のフォルダに書き込み可能なプロセスを管理しています。Linuxのパーミッションが777に設定されていても、SELinuxがコンテナをブロックすることがあります。これはストレージドライバーによっては、読み取り専用エラーとして現れることがあります。 マウントに:zまたは:Zフラグを追加してみてください。小文字の:zはボリュームが複数のコンテナ間で共有されることをDockerに伝え、大文字の:Zはプライベートで非共有のボリュームであることを示します。
docker run -v /data/storage:/app/data:Z my-image:latest
Read-Only(読み取り専用) vs. Permission Denied(アクセス拒否)これら2つのエラーを区別することは非常に重要です。それぞれ全く異なる修正が必要です。
- Read-only file system: 「パイプ」全体が閉じられています。rootを含むいかなるユーザーもデータを書き込めません。これはマウントレベルまたはハードウェアレベルの問題です。- Permission denied: 「パイプ」は開いていますが、特定のユーザーID (UID) が鍵を持っていません。これは
chmodやchownの問題です。読み取り専用エラーを修正しても書き込みができない場合は、コンテナユーザーに適切な権限がない可能性があります。私はよくUnix Permissions Calculatorを使用して、数値モード(755など)がアプリケーションのニーズと一致しているか確認します。これにより、セキュリティ上の大きなリスクとなる「とりあえず何でもchmod 777にする」習慣を防ぐことができます。
検証手順修正を適用した後は、アプリケーションの言葉を鵜呑みにせず、マウントの状態を直接確認してください。
- マウントフラグを検査する:
docker exec <container_id> mount | grep /your/path ````(rw,...)`を探します。依然として`(ro,...)`が表示される場合は、コンテナに設定変更が反映されていません。- **手動書き込みテストを実行する:**docker exec <container_id> dd if=/dev/zero of=/your/path/testfile bs=1M count=1

