A container's writable layer disappears when the container is removed — anything that needs to survive (a database's data, uploaded files, generated reports) needs to live outside that writable layer.
| Managed by | Typical use | |
|---|---|---|
| Volume | Docker, stored in Docker's own managed area on the host | Persistent data (databases) — portable, backed up/inspected via Docker itself |
| Bind mount | You — an arbitrary host path mounted into the container | Local development: live-editing source code on the host, reflected instantly inside the container |
| tmpfs mount | The host's RAM, never written to disk | Sensitive temporary data, or a performance-sensitive scratch space that shouldn't persist at all |
docker run -v pgdata:/var/lib/postgresql/data postgres # named volume
docker run -v $(pwd)/src:/app/src myapp # bind mount for live dev editing
docker run --tmpfs /app/cache myapp # in-memory, gone on container stop
pgdata here persists on the host even if the Postgres container is deleted and recreated — exactly what you want for a database. A bind mount, by contrast, is how most local development setups get instant reload: the host's actual source directory is mounted straight into the container, so an edit in your editor is immediately visible inside the running container without rebuilding the image at all. That convenience is specific to development — a production image should generally COPY its code in at build time rather than depend on a bind mount that assumes a particular host filesystem layout.