The 2 AM Production AlertYour deployment was successful, the health checks passed, and you finally closed your laptop. Ten minutes later, the monitoring alerts start firing. You check the logs and find your containers crashing in a loop. When you manually inspect the container, you hit a wall:
touch: cannot touch 'data.log': Read-only file system
This error is a classic. Even as the root user, you are locked out of your own filesystem. It usually happens when Docker or the underlying host OS decides that writing to the disk is too risky, often due to a configuration slip-up or a hardware warning.
Quick Fixes- Audit your mount flags: Double-check your docker-compose.yml. A accidental :ro at the end of a volume string will lock the directory.- Scan host disk health: Linux kernels often remount filesystems as read-only if they detect I/O errors. Run dmesg | grep -i "remount-ro" to see if the host is protecting itself from a failing drive.- Reboot the Docker Engine: On Mac or Windows, the virtual machine running Docker can occasionally hang. A quick restart of Docker Desktop often clears stale file locks.## Common Causes and Solutions### 1. Explicit Read-Only MountsMistakes in configuration are the most frequent culprits. Docker allows you to mount volumes in read-only mode to safeguard sensitive host data from containerized processes. Look for the :ro suffix in your volume mappings.
Docker Compose example:
services:
app:
image: my-app:v2.1.0
volumes:
- ./configs:/app/config:ro # This 'ro' prevents all write operations
The Fix: Switch the flag to :rw or remove it entirely. Docker defaults to read-write access if no flag is specified.
- ./configs:/app/config:rw
2. Host Filesystem CorruptionWhen the Linux kernel encounters a critical I/O error on an ext4 or xfs partition, it triggers an emergency remount. This safety move prevents data corruption but turns your volumes into read-only zones. This often happens when a cloud provider's block storage experiences a hiccup.
Check your host logs immediately:
journalctl -k | grep -E "error|read-only"
If you see 'EXT4-fs error', you may need to unmount the drive and run fsck. If this is a production server, check your cloud console for hardware retirement notices or disk attachment issues.
3. Docker Desktop Resource Limits (Mac/Windows)Docker Desktop operates inside a hidden virtual machine. This VM uses a virtual disk image (usually Docker.raw) with a fixed size—often 64GB by default. If this virtual disk hits 100% capacity, the internal filesystem may flip to read-only mode to prevent database corruption.
The Fix:
- Check the 'Disk usage' meter in Docker Desktop settings.- Prune unused data with
docker system prune -a --volumesto reclaim space.- If the disk image is corrupted, use the 'Reset to factory defaults' option. Note that this will wipe your local images and volumes.### 4. SELinux EnforcementsOn security-hardened systems like RHEL, Fedora, or CentOS, SELinux manages which processes can write to specific folders. Even if your Linux permissions are set to777, SELinux might block the container. This sometimes manifests as a read-only error depending on the storage driver. Try appending the:zor:Zflags to your mount. The lowercase:ztells Docker that the volume is shared between multiple containers, while the uppercase:Zindicates a private, unshared volume.
docker run -v /data/storage:/app/data:Z my-image:latest
Read-Only vs. Permission DeniedIt is vital to distinguish between these two errors. They require very different fixes.
- Read-only file system: The entire 'pipe' is closed. No user, not even root, can write data. This is a mount-level or hardware-level issue.- Permission denied: The 'pipe' is open, but your specific user ID (UID) doesn't have the key. This is a
chmodorchownissue.If you fix the read-only error but still cannot write, the container user likely lacks the correct permissions. I often use a Unix Permissions Calculator to verify that my numeric modes (like755) align with the application's needs. It helps prevent the 'just chmod 777 everything' habit, which is a significant security risk.
Verification StepsAfter applying a fix, don't just take the application's word for it. Verify the mount state directly:
- Inspect the mount flags:
docker exec <container_id> mount | grep /your/pathLook for(rw,...). If you still see(ro,...), the container hasn't picked up the configuration change.- Perform a manual write test:``` docker exec <container_id> dd if=/dev/zero of=/your/path/testfile bs=1M count=1

