{
  "$type": "site.standard.document",
  "canonicalUrl": "https://rednafi.com/misc/docker-mount/",
  "description": "Master Docker mount types: volumes, bind mounts, tmpfs, and build cache. Clear syntax comparison between -v and --mount options with docker-compose.",
  "path": "/misc/docker-mount/",
  "publishedAt": "2024-10-22T00:00:00.000Z",
  "site": "at://did:plc:fgtm2c26vfcj74rfmeggbyqj/site.standard.publication/3mnl6f7ob462z",
  "tags": [
    "TIL",
    "Docker",
    "DevOps"
  ],
  "textContent": "I always get tripped up by Docker's different mount types and their syntax, whether I'm\nstringing together some CLI commands or writing a docker-compose file. Docker's docs cover\nthese, but for me, the confusion often comes from how \"bind\" is used in various contexts and\nhow \"volume\" and \"bind\" sometimes get mixed up in the documentation.\n\nHere's my attempt to disentangle some of my most-used mount commands.\n\nVolume mounts\n\n[Volume mounts] let you store data outside the container in a location managed by Docker.\nThe data persists even after the container stops. On non-Linux systems, volume mounts are\nfaster than bind mounts because data doesn't need to cross the virtualization boundary.\n\nThe -v option\n\nThe -v flag is the older and more common way to define volume mounts in the Docker CLI.\nFor example:\n\nHere's what each part means:\n\n- myvolume: The name of the Docker-managed volume on the host.\n- /usr/share/nginx/html: The mount point inside the container.\n- :ro: Mounts the volume as read-only inside the container. The host can still write to\n  the volume, but the container cannot.\n\nThe general syntax is:\n\nIt can be tricky to remember which part is the host and which is the container, especially\nsince with volumes, the SOURCE is a volume name, not a host path.\n\nThe --mount option\n\nTo make things clearer, Docker introduced the --mount option, which uses key-value pairs.\nThe same volume mount using --mount looks like this:\n\nOr using shorthands:\n\nI find this syntax more explicit and less error-prone, even if it's a bit more verbose.\n\nIn docker-compose.yml\n\nIn docker-compose, volumes can be defined using both the old and new syntax. Here's how\nthey compare:\n\nOld style\n\nNew style\n\nI prefer the new style because it reduces ambiguity and makes the configuration clearer.\n\nBind mounts\n\n[Bind mounts] let you directly mount a file or directory from the host into the container.\nThis is especially useful in development when you want the container to have access to your\ncode or data.\n\nThe key difference between volume mounts and bind mounts is that volumes are fully managed\nby Docker and stored in a special location, while bind mounts rely on specific host paths.\nVolumes are more portable and isolated from the host, whereas bind mounts give you direct\naccess to host files but can introduce permission issues and depend on the exact file\nstructure of the host.\n\nThe -v option\n\nUsing the -v syntax for bind mounts:\n\nHere:\n\n- /path/on/host: The path on the host machine. This must be an absolute path.\n- /usr/share/nginx/html: The mount point inside the container.\n- :ro: Mounts the directory as read-only inside the container.\n\nThe --mount option\n\nUsing --mount for a bind mount:\n\nThis syntax makes it clear that you're using a bind mount and specifies exactly which paths\nare involved.\n\nIn docker-compose.yml\n\nIn docker-compose, bind mounts can be specified like this:\n\nOld style\n\nNew style\n\n> Note: In docker-compose, if you specify a source that doesn't start with / (an\n> absolute path) or ./ (a relative path), Docker might think you're referring to a volume.\n> To ensure it's interpreted as a bind mount, start the path with ./ or /.\n\nTmpfs mounts\n\n[Tmpfs mounts] store data in the host's memory, not on disk. This makes them ideal for\ntemporary storage that doesn't need to persist after the container stops. They're great for\nthings like caches or scratch space.\n\nThe --tmpfs option\n\nDocker provides a --tmpfs option to create a tmpfs mount more concisely:\n\n- /app/tmp: The target directory inside the container.\n- rw: This option allows read and write access to the tmpfs mount.\n- size=64m: Sets the size of the tmpfs mount to 64 MB.\n\nThe --mount option\n\nAlternatively, using the more flexible --mount option:\n\nHere's what each part means:\n\n- type=tmpfs: Specifies that this is a tmpfs mount, using the host's memory.\n- target=/app/tmp: The directory inside the container where the tmpfs mount is mounted.\n- tmpfs-size=64m: Limits the size of the tmpfs mount to 64 MB.\n- tmpfs-mode=1777: Sets permissions for the tmpfs mount (1777 grants read, write, and\n  execute permissions to everyone).\n\nIn docker-compose.yml\n\nIn docker-compose, tmpfs mounts can be defined using both the old and new syntax.\n\nOld style\n\nNew style\n\nBuild cache mounts\n\n[Build cache mounts] help speed up Docker image builds by caching intermediate files like\npackage downloads or compiled artifacts. They're used during the build process and aren't\npart of the final container image.\n\nIn a Dockerfile, you might use a build cache like this:\n\nHere's what each option does:\n\n- --mount=type=cache: Defines a cache mount that stores the files from the apt-get\n  commands to speed up future builds by reusing the downloaded packages.\n- target=/var/cache/apt: Specifies the location inside the container where the cache will\n  be stored during the build process.\n\nIn my Python projects, I cache my dependencies and install them with uv like this:\n\nAbove, the cache mount at /root/.cache/uv saves dependencies so they don't need to be\nre-downloaded in future builds if nothing changes. The bind mounts provide access to\nuv.lock and pyproject.toml from the host, allowing the container to read these config\nfiles during the build. Any changes to the files are picked up, while cached dependencies\nare reused unless the configurations have been updated.\n\n\n\n\n[volume mounts]:\n    https://docs.docker.com/storage/volumes/\n\n[bind mounts]:\n    https://docs.docker.com/storage/bind-mounts/\n\n[tmpfs mounts]:\n    https://docs.docker.com/storage/tmpfs/\n\n[build cache mounts]:\n    https://docs.docker.com/build/cache/optimize/#use-cache-mounts",
  "title": "Docker mount revisited"
}