sehaj/learn
Docker/04 Data

04.04 · with code · 7 min

tmpfs mounts

Memory-backed scratch space that never touches disk, and how it lets you run containers with a read-only root filesystem.

The core idea

A tmpfs mount is a directory that lives in memory. It's fast, it's never written to disk, and it disappears when the container stops. You won't use it often, but it solves two problems neatly: scratch space for files that must never be persisted, and making a read-only container work.

Read-only containers

--read-only makes the container's whole filesystem read-only. An attacker who gets in can't drop files, modify binaries or plant a backdoor that survives. But many programs need to write somewhere, usually /tmp:

❯terminal
$ docker run --rm --read-only alpine touch /tmp/x
touch: /tmp/x: Read-only file system
$ docker run --rm --read-only --tmpfs /tmp:size=16m alpine sh -c 'touch /tmp/x && df -h /tmp'
Filesystem Size Used Available Use% Mounted on
tmpfs 16.0M 0 16.0M 0% /tmp

Everything is read-only except a 16 MB in-memory /tmp. Add a tmpfs for each path the app really needs to write, and a volume for anything it needs to keep. You'll apply this to the notes API in 07.01 Run as non-root.

Syntax and limits

tmpfs
# Short form, options after the colon
docker run --tmpfs /tmp:size=64m,mode=1777 ...

# Long form
docker run --mount type=tmpfs,dst=/cache,tmpfs-size=8m ...

The size is a hard cap:

❯terminal
$ docker run --rm --mount type=tmpfs,dst=/cache,tmpfs-size=8m alpine \
sh -c 'dd if=/dev/zero of=/cache/f bs=1M count=20'
dd: error writing '/cache/f': No space left on device

Always set one. Without it, a tmpfs can grow to half of the host's (or Docker Desktop VM's) memory:

❯terminal
$ docker run --rm --memory 64m --tmpfs /scratch alpine df -h /scratch
tmpfs 3.8G 0 3.8G 0% /scratch

Even inside a container limited to 64 MB, the tmpfs reports 3.8 GB. Files written there count against the container's memory limit, so filling it can get the container OOM-killed (03.06 CPU and memory limits).

VolumeBind mounttmpfs
Stored ondisk, managed by Dockerdisk, your pathmemory
Survives the containeryesyesno
Shared between containersyesyesno
Typical usedatabases, uploadsdev code, configscratch, secrets, read-only roots
Predict first

An app writes decrypted credentials to a temporary file while it starts. You want to be sure they never reach any disk. Where should that path be?

Commit to an answer before you read on.
CheckpointRun read-only

Run the notes API with --read-only. Does it start? (It only writes to Postgres and stdout.) Then run nginx:alpine with --read-only and read the errors: add --tmpfs mounts for the paths it complains about until it serves pages.

STUCK? ▸

An app that fails under --read-only usually prints the path it tried to write. For nginx:alpine, it's mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system); with --tmpfs /var/cache/nginx --tmpfs /run --tmpfs /tmp it serves pages. (Its startup script also notes it can't edit default.conf, which is harmless.)

Recap

Interview questions

MidfreqGood to knowScenario

How would you run a container with a read-only filesystem when the app needs to write temporary files?

Report a mistakeEdit this page
☰ Data04.04 · 25/44next →