<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Volumes and Live Reload

Volumes and Live Reload

A container's filesystem is ephemeral : it's a thin writable layer on top of the image, and it's destroyed with the container. Anything the container writes there (database rows, uploads, logs) is gone when the container is removed. Mounts solve this by connecting a path inside the container to storage on the host machine, so the files actually live on the host's disk and outlive any container that uses them.

There are two kinds, and they differ in who controls the host-side location:

  • Bind mount : maps a specific host folder you choose into the container. You know the exact path on disk, and you can edit those files directly. Ideal for development, where you want the container to see your source code as you change it.
  • Named volume : storage Docker creates and manages, identified by a name rather than a path (docker volume create pgdata). Docker decides where it lives on disk; you just refer to it by name. Ideal for data a container must persist but you never edit by hand, like a database's files.
Bind Mount Host folder (you choose) /Users/bob/dev/app Container path /app Both see the same files instantly Named Volume Docker-managed (you pick a name) pgdata (volume) Container path /var/lib/postgresql/data Data survives container restarts
Bind mounts share files between host and container. Named volumes persist data across container restarts without exposing the host path.

The same mechanism covers two different needs: a named volume is about persistence (keep data across container restarts and rebuilds), while a bind mount is usually about sharing (the host and container working on the same files at the same time).

Bind mounts for live-reload

The most common development use is bind-mounting your source code. The host folder and the container path point at the same files, so a change on either side is visible to the other instantly, with no copy step in between.

# Mount dev/app of the home folder into /app in the container
docker run -p 3000:3000 -v /Users/bobsmith/dev/app:/app my-api

# To do the same thing regardless of the name of your home folder
docker run -p 3000:3000 -v "$(pwd)"/dev/app:/app my-api

The -v host:container flag maps a host folder to a path inside the container. The container reads your source directly instead of the copy baked into the image at build time. Add a file watcher inside the container (nodemon for Node, for example) and a save on the host triggers a reload — no rebuild, no restart.

Heads-up: a bind mount replaces what the image had at that path. During the build, npm install created /app/node_modules inside the image, but when you mount your project folder over /app, the container sees your folder instead, which probably has no node_modules (or one built for the wrong OS). The app crashes with "module not found." The fix is an extra flag, -v /app/node_modules, which tells Docker to keep that one subfolder as container-managed storage. Your source comes from the host; the installed dependencies stay from the image's build.

-v .:/app only Host project folder src/ package.json (no node_modules) mounts over /app (in container) built node_modules is hidden by the host folder ✗ Error: module not found add -v /app/node_modules Host project folder src/ package.json mounted at /app /app (your source) /app/node_modules kept from the image build ✓ source live, deps intact
A second mount, -v /app/node_modules, shields the built dependencies from the bind mount so live-reload works without a "module not found" crash.

Named volumes for persistence

For data you want to keep but never edit by hand — a database's files, for instance — use a named volume instead. You refer to it by name and let Docker manage where it lives on disk.

# Create a named volume once
docker volume create pgdata

# Mount it by name; Docker decides where it lives on disk
docker run -v pgdata:/var/lib/postgresql/data postgres

The same -v flag does the work, but the left side is a volume name rather than a host path. The volume outlives the container, so removing and recreating the postgres container keeps the data intact.

Check your understanding

Question 1 of 7

How live-reload works without rebuilding

How does bind-mounting your source folder enable live-reload without rebuilding the image?