Skip to main content
RunBook Academy

← All break/fix scenarios in Docker & Containers

intermediateSecurity~15 min

Break/Fix 14: Writable root filesystem defeats read-only hardening

Reported symptoms

  • Container exits with `Read-only file system` errors in logs.
  • Application cannot write to its working directory, /tmp, or another path.
  • Compose file claims `read_only: true` but the container fails.

Evidence

  • · `docker logs CONTAINER` shows `Read-only file system` and the path that failed.
  • · The path is not declared as `tmpfs:` or a mounted volume.
Diagnosis and resolutionclick to reveal

Root cause

`read_only: true` makes the entire root filesystem read-only. The application needs to write somewhere — `/tmp`, its working directory, the cache. Without an explicit `tmpfs:` or volume mount, every write fails.

Remediation

Mount the writable paths as tmpfs or volumes: ```yaml read_only: true tmpfs: - /tmp - /var/cache/myapp volumes: - app-data:/var/lib/myapp ```

Verification

Container starts and runs. `docker exec CONTAINER touch /tmp/x` succeeds. `docker exec CONTAINER touch /var/cache/myapp/x` succeeds. `docker exec CONTAINER touch /etc/x` fails (root FS remains read-only).

Prevention

When adopting `read_only: true`, audit the application for filesystem writes. Most apps write to `/tmp`, the working dir, or a cache. Add tmpfs mounts for each before flipping read_only.

Diagnosis

docker logs my-container
# [error] Failed to write to /tmp/cache.json: Read-only file system

The application expects to write to /tmp. read_only: true prevents that.

Fix

services:
  api:
    image: myorg/api:1.0.0
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache/myapp
    volumes:
      - app-data:/var/lib/myapp
    security_opt:
      - no-new-privileges:true
    cap_drop: [ALL]
    cap_add: [NET_BIND_SERVICE]

Each writable path is now explicit. The root filesystem stays read-only; the writable paths are isolated to tmpfs or volumes.