KhueApps
Home/DevOps/Fix 'The path must be absolute' for volumes and binds in Compose

Fix 'The path must be absolute' for volumes and binds in Compose

Last updated: October 07, 2025

What this error means

Compose is telling you that a bind mount’s host side is not an absolute path. Docker can’t mount a relative path from your machine into a container unless Compose resolves it to an absolute path first.

Typical triggers:

  • Long syntax with type: bind and a relative source (e.g., source: ./data)
  • OS-specific path formatting issues (Windows drive letters, backslashes)
  • Using ~ (home) or unexpanded variables in YAML

Quickstart fix

Use an absolute path or the built-in ${COMPOSE_PROJECT_DIR} variable, which expands to the directory containing your compose file.

  • Cross‑platform (recommended): ${COMPOSE_PROJECT_DIR}/data
  • Linux/macOS: ${PWD}/data (works when PWD is set)
  • Windows: C:/Users/you/project/data (forward slashes)

If you don’t need a host path, prefer a named volume to avoid path issues entirely.

Minimal working example (bind mount)

Create a data directory next to your compose file and start a container that writes to it.

tversion: "3.9"
services:
  app:
    image: busybox:1.36
    command: ["sh", "-c", "echo hello >> /data/out.txt && tail -f /dev/null"]
    volumes:
      - type: bind
        source: ${COMPOSE_PROJECT_DIR}/data
        target: /data
        bind:
          create_host_path: true

Run:

docker compose up -d
ls ./data
cat ./data/out.txt

This works on Linux, macOS, and Windows (Docker Desktop) because COMPOSE_PROJECT_DIR resolves to an absolute path.

Minimal working example (named volume, no host path)

tversion: "3.9"
services:
  app:
    image: busybox:1.36
    command: ["sh", "-c", "echo hello >> /data/out.txt && tail -f /dev/null"]
    volumes:
      - appdata:/data
volumes:
  appdata:

No host path—so no absolute-path problem.

Step-by-step: Fixing your compose file

  1. Identify mounts that need host paths
  • In service.volumes, entries like ./data:/data or long syntax with type: bind use a host path.
  1. Switch to an absolute path
  • Best: source: ${COMPOSE_PROJECT_DIR}/data
  • Or: use a full OS path, e.g., /home/alice/proj/data or C:/Users/Alice/proj/data
  1. Keep Windows paths portable
  • Use forward slashes: C:/Users/Alice/proj/data
  • Ensure the path is under a shared location (e.g., C:/Users) if file sharing is enabled in Docker Desktop.
  1. Prefer named volumes when you don’t need a specific host directory
  • Replace host path with a named volume and declare it under top-level volumes.
  1. Validate expansion before running
  • Print the rendered config: docker compose config
  • Confirm the source paths are absolute in the output.

Common patterns (good vs. bad)

  • Good (long syntax, cross‑platform):
volumes:
  - type: bind
    source: ${COMPOSE_PROJECT_DIR}/logs
    target: /var/log/app
  • Good (short syntax, explicit absolute):
volumes:
  - /home/alice/app/logs:/var/log/app:rw
  • Windows good:
volumes:
  - C:/Users/Alice/app/logs:/var/log/app
  • Bad (relative in long syntax):
volumes:
  - type: bind
    source: ./logs   # Likely: The path must be absolute
    target: /var/log/app
  • Bad (tilde not expanded):
volumes:
  - ~/logs:/var/log/app  # ~ is not expanded by Compose

Cross-platform variable approach

Define an absolute path in .env per machine, or rely on COMPOSE_PROJECT_DIR.

  • Using COMPOSE_PROJECT_DIR (no .env needed):
volumes:
  - type: bind
    source: ${COMPOSE_PROJECT_DIR}/data
    target: /data
  • Using a custom DATA_DIR from .env:
DATA_DIR=/absolute/path/to/project/data
volumes:
  - type: bind
    source: ${DATA_DIR}
    target: /data

On Windows PowerShell, create .env with an absolute path via:

"DATA_DIR=$(Get-Location).Path\data" | Out-File -Encoding ASCII .env

Then edit slashes to forward (C:/...) or rely on Compose handling. Forward slashes are safest.

Troubleshooting checklist

  • docker compose config shows absolute source paths
  • The host directory exists or create_host_path: true is set
  • Windows: path is shared with Docker Desktop and uses forward slashes
  • WSL2: run compose inside the Linux distro and use Linux paths (/home/… or /mnt/c/…)
  • You’re not mixing a named volume name with type: bind (that’s invalid)

Performance notes

  • Bind mounts are convenient but can be slower, especially on macOS/Windows where file I/O crosses the virtualization boundary.
  • Prefer named volumes for heavy, hot I/O (databases, caches). Use bind mounts mainly for source code.
  • Avoid mounting large node_modules or build directories; consider .dockerignore or multi-stage builds.
  • On Windows/macOS, keep projects under the default shared locations (e.g., C:/Users, $HOME) to reduce overhead.

Pitfalls to avoid

  • Relative source in long syntax for binds (use COMPOSE_PROJECT_DIR or a full path)
  • Tilde (~) and %USERPROFILE% not expanded by Compose unless provided via .env or environment
  • Backslashes in Windows paths; prefer forward slashes
  • Mounting a file vs. directory: specify the exact host file path when targeting a file
  • Using docker stack deploy: Swarm nodes require absolute host paths that exist on every node

FAQ

Q: Can I use relative paths for bind mounts? A: Use ${COMPOSE_PROJECT_DIR}/relative-dir to ensure they resolve to an absolute path. Plain ./dir in long syntax often triggers the error.

Q: Why does short syntax sometimes work and long syntax fails? A: Some implementations are stricter with long syntax (type: bind). Using an already-absolute source avoids ambiguity.

Q: How do I mount a single file? A: Use the absolute path to the file on the host: /abs/path/app.conf:/app/app.conf:ro.

Q: How do I make this portable across OSes? A: Use ${COMPOSE_PROJECT_DIR} or a .env variable set to an absolute path per machine.

Q: Should I use a named volume instead? A: Yes, if you don’t need a specific host directory. It avoids path errors and is usually faster for heavy I/O.

Series: Docker

DevOps