Bind mounts

A bind mount puts a folder of the server inside the container. A change on one side is seen at once on the other, which is ideal in development and risky in production.

How it works

-v ./src:/app/src on docker run, or a volumes entry starting with a path in Compose. The mount hides whatever the image had at that path. Files keep the owner and permissions they have on the server, so a non-root container may be unable to write to them.

What breaks

Mounting the whole project over /app also hides the node_modules installed in the image: the app crashes with "Cannot find module". In production, a bind mount makes the container depend on files that are not in the image, so what you tested is not what runs.

In compose.yaml

services:
  api:
    build: ./api
    command: ["npx", "nodemon", "src/server.js"]
    volumes:
      - ./api/src:/app/src

See it break, then fix it

Write the Dockerfile or the compose file, type the docker commands, and watch a simulated server run them through reboots, upgrades and traffic. Free to start.