Docker Bind Mounts for Host Directory Access

Learn how to mount host directories into Docker containers using bind mounts. Understand the syntax, security implications, and common use cases like live code reloading during development.

Volumes & Storage

Detailed Explanation

Bridging Host and Container Filesystems

A bind mount maps a specific directory (or file) on the host machine directly into the container. Unlike named volumes, bind mounts give you full control over the exact host path:

docker run -d -v /home/user/project:/app -p 3000:3000 node:20

This mounts the host directory /home/user/project at /app inside the container. Any changes to files on the host are immediately visible inside the container, and vice versa.

Bind Mount Syntax

# Absolute host path (required for bind mounts)
-v /absolute/host/path:/container/path

# Using $(pwd) for current directory
-v $(pwd):/app

# Read-only bind mount (container cannot modify host files)
-v $(pwd)/config:/app/config:ro

# Using --mount (more explicit, recommended for clarity)
--mount type=bind,source=/host/path,target=/container/path

Development Workflow: Live Code Reloading

The most common use of bind mounts is live development. Mount your source code into the container so that code changes on the host trigger hot-reloading inside the container:

docker run -d \
  --name dev-server \
  -v $(pwd)/src:/app/src \
  -v $(pwd)/public:/app/public \
  -p 3000:3000 \
  my-dev-image

With a file watcher (Nodemon, Vite, webpack dev server) inside the container, saving a file on the host instantly triggers a rebuild.

Bind Mount vs. Named Volume

The critical difference: bind mounts overlay the container directory with host content. If the container image has files at /app, a bind mount replaces them entirely with the host directory contents.

# Named volume: pre-populates with image content
docker run -v mydata:/app/data my-image  # /app/data has image files

# Bind mount: replaces with host content (may be empty!)
docker run -v $(pwd)/data:/app/data my-image  # /app/data has host files only

Handling node_modules with Bind Mounts

A common issue in Node.js development: bind-mounting the entire project directory overwrites the container's node_modules:

docker run -d \
  -v $(pwd):/app \
  -v /app/node_modules \
  node:20 npm start

The anonymous volume at /app/node_modules preserves the container's installed dependencies, preventing the host's (possibly incompatible) node_modules from overwriting them.

Security Considerations

  • Bind mounts expose host filesystem paths to the container. A compromised container could read or modify sensitive host files.
  • Use :ro (read-only) whenever the container does not need write access.
  • Avoid mounting sensitive directories like /etc, /var, or $HOME unless absolutely necessary.
  • In production, prefer named volumes over bind mounts for security and portability.

File Ownership and Permissions

Containers often run as root (UID 0), but the host user may have a different UID. Files created by the container in a bind mount may be owned by root on the host:

# Run container as current user to match host ownership
docker run -v $(pwd):/app --user $(id -u):$(id -g) my-image

Use Case

Setting up a local development environment where source code changes on the host machine are immediately reflected inside the Docker container, enabling hot-reloading without rebuilding the image.

Try It — Docker Run Command Builder

Open full tool