Skip to content

Bind Mounts

A bind mount maps a specific path on your host machine directly into a container. Unlike a named volume, you choose exactly where the data lives on the host — Docker does not manage the path.

Host filesystem: /home/user/myapp/src
↕ bind mount
Container filesystem: /app/src

Any change made on the host side is immediately visible inside the container, and vice versa. This makes bind mounts ideal for development: your editor modifies files on the host, and the running process inside the container sees the updates instantly — no rebuild required.

Short -v syntax:

Terminal window
docker run -v /host/path:/container/path myimage

Long --mount syntax (recommended for scripts — no ambiguity):

Terminal window
docker run \
--mount type=bind,source=/host/path,target=/container/path \
myimage

In development you almost always want to mount the current working directory:

Terminal window
docker run --rm -v $(pwd):/app -w /app node:22-alpine node server.js

$(pwd) expands to the absolute host path at runtime. This is the standard pattern for running code without building a new image on every change.

Terminal window
# Mount your source into the container at /app
# The -w flag sets the working directory inside the container
docker run -d --name dev-server \
-v $(pwd)/src:/app/src \
-p 3000:3000 \
node:22-alpine \
node /app/src/server.js

Now edit src/server.js on your host. If the process inside the container watches the filesystem (e.g., with nodemon), it restarts automatically. No image rebuild is needed for every code change.

Add :ro to make the mount read-only from the container’s perspective. The container can read the files but cannot write to them:

Terminal window
docker run --rm \
-v $(pwd)/config:/etc/myapp/config:ro \
myimage

With --mount syntax:

Terminal window
docker run --rm \
--mount type=bind,source=$(pwd)/config,target=/etc/myapp/config,readonly \
myimage

This is useful for injecting configuration files without the container accidentally overwriting them.

The snippet below creates a file on the host (simulated here with echo in a setup step), mounts the directory into a container, and reads the file from inside the container — demonstrating live file sharing.

# 1. Create a directory with a file to share
mkdir -p /tmp/bindtest && echo 'shared from host' > /tmp/bindtest/hello.txt

# 2. Mount it into a container and read the file
docker run --rm -v /tmp/bindtest:/data alpine cat /data/hello.txt

# 3. Write from inside the container back to the host
docker run --rm -v /tmp/bindtest:/data alpine sh -c "echo 'written by container' > /data/from-container.txt"

# 4. Check the file now exists on the host path
ls -la /tmp/bindtest/
cat /tmp/bindtest/from-container.txt

# 5. Clean up
rm -rf /tmp/bindtest
What is the key difference between a bind mount and a named volume?
Which shell expression expands to the current working directory in a `docker run` command?
What does adding `:ro` to a bind mount do?
Why are bind mounts preferred for local development but not recommended for production?