Troubleshooting ‘Docker compose relative path volume mount invalid directory’ on Windows WSL2 Ubuntu

Resolve Docker compose volume mount errors on Windows WSL2 Ubuntu when using relative paths. Learn how to fix 'invalid directory' issues.


Resolve Docker compose volume mount errors on Windows WSL2 Ubuntu when using relative paths. Learn how to fix 'invalid directory' issues.

When working with Docker Compose on Windows, specifically within a WSL2 (Windows Subsystem for Linux 2) Ubuntu environment, you might encounter frustrating errors related to volume mounts when using relative paths. This guide addresses scenarios where docker compose up fails, reporting that a directory specified for a volume mount is "invalid" or "not found," despite the path seemingly being correct from within your WSL2 terminal. This often stems from the interaction and path translation challenges between the Windows filesystem, the WSL2 filesystem, and Docker Desktop.

Symptom & Error Signature

The primary symptom is that your Docker Compose services fail to start, reporting issues with creating or mounting volumes. You will typically see error messages in your terminal after running docker compose up (or docker-compose up for older versions) that resemble the following:

[+] Running 1/1
 ⠿ Container myapp-web  Error                                                                                                                                                                                                                                                            0.0s
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: rootfs_linux.go:50: creating rootfs for container "a1b2c3d4e5f6g7h8": mount /var/lib/docker/volumes/myproject_data/_data:/app/data caused "not a directory": unknown

Or, a slightly different variation:

ERROR: for myapp-web  Cannot start service myapp-web: error while mounting volume '/var/lib/docker/volumes/myproject_data/_data': failed to mount host path /mnt/c/Users/youruser/myproject/data to container path /app/data over overlay: not a directory

Notice the key phrases: "not a directory," "failed to create task," or "failed to mount host path," often referencing a path that does exist on your Windows or WSL2 filesystem.

Root Cause Analysis

The core of this issue lies in the intricate interplay of path resolution and file sharing between Windows, WSL2, and Docker Desktop. When you run docker compose from within your WSL2 Ubuntu environment, Docker Desktop acts as the Docker engine. The problem manifests primarily under these conditions:

  1. Project Located on Windows Filesystem, Accessed via WSL2: Your docker-compose.yml file and project directories (e.g., ./data) are located on your Windows filesystem (e.g., C:Usersyourusermyproject), and you're accessing them from your WSL2 terminal via the /mnt/c/Users/youruser/myproject path.
  2. Docker Desktop's Path Translation Challenges: When docker compose is executed from WSL2, but referring to a Windows path via /mnt/c/, Docker Desktop needs to correctly translate these paths for its underlying Windows host. While Docker Desktop generally handles this well for absolute paths (e.g., /mnt/c/Users/...), relative paths (e.g., ./data) can sometimes be ambiguous. Docker Desktop attempts to resolve these relative paths relative to the original Windows location of the docker-compose.yml file, but this process can fail if the drive isn't properly shared, or if there's a misinterpretation of the path context.
  3. Inadequate Drive Sharing: Docker Desktop requires explicit permission to access drives on your Windows host. If the C: drive (or any other drive hosting your project) is not enabled for sharing in Docker Desktop settings, any volume mount attempting to access that drive will fail.
  4. Case Sensitivity Mismatch (Less Common, but Contributory): While less likely to cause "not a directory," Windows filesystems are generally case-insensitive, while Linux (WSL2 and Docker containers) are case-sensitive. If docker-compose.yml refers to ./Data but the actual directory is ./data, it can lead to problems.

In essence, Docker Desktop, running on Windows, cannot find or correctly interpret the host path for the volume because the relative path given from within WSL2, pointing to a Windows-mounted directory, isn't being correctly resolved or shared.

Step-by-Step Resolution

There are several effective strategies to resolve this issue, ranging from ensuring proper Docker Desktop configuration to fundamental changes in your project structure.

1. Ensure Docker Desktop Drive Sharing is Enabled

This is a fundamental prerequisite. Docker Desktop needs explicit permission to access your Windows drives.

  1. Open Docker Desktop Settings: Right-click the Docker icon in your Windows system tray and select "Settings."

  2. Navigate to Resources > File Sharing: In the Settings window, go to "Resources" then "File Sharing."

  3. Enable Drive Sharing: Ensure that the drive where your Docker Compose project resides (most commonly C:) is checked. If it's not, check it and click "Apply & Restart." Docker Desktop will restart.

    If you encounter issues applying changes or if Apply & Restart fails, try resetting credentials or reinstalling Docker Desktop. Sometimes corporate antivirus or firewalls can interfere with drive sharing.

2. Relocate Your Project to the WSL2 Filesystem

This is the most recommended and robust solution for development on WSL2. Storing your project files directly within the WSL2 filesystem (e.g., /home/youruser/myproject) bypasses all Windows-to-WSL2 path translation complexities and generally offers better performance for I/O operations from within WSL2.

  1. Create a Project Directory in WSL2: Open your WSL2 Ubuntu terminal and create a new directory for your project.

    mkdir -p ~/projects/myproject
    
  2. Move Your Project Files: Copy all your project files, including your docker-compose.yml and any directories intended for volume mounts (e.g., data, logs), from their Windows location to the new WSL2 directory.

    # Example: Copy from Windows C: drive to WSL2 home
    cp -r /mnt/c/Users/youruser/MyProject/* ~/projects/myproject/
    
  3. Navigate to the WSL2 Project Directory:

    cd ~/projects/myproject
    
  4. Run Docker Compose: Now, execute your Docker Compose command. Relative paths in your docker-compose.yml (e.g., ./data:/app/data) will now resolve correctly within the WSL2 filesystem context.

    docker compose up -d
    

    While beneficial for Docker, be aware that editing files within the WSL2 filesystem from Windows applications (like VS Code opened directly via Explorer) can sometimes be slower than editing files on the Windows filesystem. For the best experience, use VS Code's "Remote – WSL" extension to open your WSL2 project directly within VS Code, ensuring all file operations are handled by WSL2.

3. Use Absolute Paths in docker-compose.yml (Windows Path Format)

If relocating your project to the WSL2 filesystem is not feasible or desired, you can explicitly define absolute paths in your docker-compose.yml using the Windows path format. Docker Desktop is designed to translate these paths correctly.

  1. Identify the Absolute Windows Path: Get the full absolute path to your project directory on the Windows filesystem. For example, C:UsersyouruserMyProject.

  2. Update docker-compose.yml: Modify the volumes section in your docker-compose.yml to use the absolute Windows path. Remember to use forward slashes (/) even for Windows paths within Docker configurations.

    # docker-compose.yml
    version: '3.8'
    services:
      web:
        image: nginx:latest
        ports:
          - "80:80"
        volumes:
          # BEFORE (relative path causing issues)
          # - ./nginx.conf:/etc/nginx/nginx.conf
          # - ./html:/usr/share/nginx/html
    
          # AFTER (absolute Windows path with forward slashes)
          - C:/Users/youruser/MyProject/nginx.conf:/etc/nginx/nginx.conf
          - C:/Users/youruser/MyProject/html:/usr/share/nginx/html
          # Or, for the entire project directory:
          # - C:/Users/youruser/MyProject:/app
    

    Ensure that the drive (e.g., C:) is shared in Docker Desktop settings as described in Step 1. Without it, even absolute paths will fail.

4. Use Absolute Paths with wslpath (Less Common, but Specific)

This method is less common for docker-compose.yml but can be useful for shell commands if you need to pass a Windows path directly to a Docker command while operating from WSL2. wslpath is a utility in WSL2 that converts Windows paths to WSL2 paths and vice-versa.

For docker-compose.yml, this is typically not needed, as Docker Desktop handles the Windows path format directly. However, if you were explicitly building a command where you needed a WSL2-formatted path to be passed as a Windows-formatted path to a Docker command, you might use:

# This example is illustrative, not for direct use in docker-compose.yml
# It converts a WSL2 path to a Windows-style path for Docker Desktop
win_path=$(wslpath -w /mnt/c/Users/youruser/MyProject/data)
docker run -v "${win_path}:/app/data" myimage

For docker-compose.yml, stick to either relocating the project (Step 2) or using direct Windows absolute paths (Step 3).

By following these steps, you should be able to effectively resolve "invalid directory" errors when mounting volumes with Docker Compose on Windows WSL2 Ubuntu, allowing for a smoother development workflow.