Claude
Skills
Sign in
Back

docker-git-bash-guide

Included with Lifetime
$97 forever

Docker on Windows with Git Bash / MINGW path conversion. PROACTIVELY activate for: (1) Docker commands failing on Windows Git Bash with path errors, (2) volume mount path conversion (-v $(pwd):/app), (3) MSYS_NO_PATHCONV and MSYS2_ARG_CONV_EXCL workarounds, (4) double-slash escapes (//c/foo) for MINGW, (5) docker-compose volume mounts on Windows, (6) WSL2 vs Hyper-V backend path interop, (7) line-ending issues in mounted scripts (CRLF vs LF), (8) UNC path limitations. Provides: MSYS path-conversion explainer, copy-pasteable env-var workarounds, double-slash recipes, line-ending fixes, and compose-mount patterns for Windows.

Ads & Marketing

What this skill does


# Docker on Windows Git Bash / MINGW - Path Conversion Guide

This skill provides comprehensive guidance on handling Docker commands in Git Bash (MINGW) on Windows, with specific focus on volume mount path conversion issues and solutions.

## The Path Conversion Problem

When running Docker commands in Git Bash (MINGW) or MSYS2 on Windows, automatic path conversion can cause serious issues with volume mounts and other Docker commands.

### What Triggers Automatic Conversion

MSYS/MINGW shells automatically convert arguments that look like Unix paths when calling Windows executables (like `docker.exe`):

**Examples of problematic conversions:**
```bash
# What you type:
docker run -v /c/Users/project:/app myimage

# What Docker receives (BROKEN):
docker run -v C:\Program Files\Git\c\Users\project:/app myimage
```

**Triggers for path conversion:**
- Leading forward slash (`/`) in arguments
- Colon-separated path lists (`/foo:/bar`)
- Arguments with path components after `-` or `,`

**What's exempt from conversion:**
- Arguments containing `=` (variable assignments)
- Drive letters (`C:`)
- Arguments with `;` (already Windows format)
- Arguments starting with `//` (network paths/Windows switches)

## Shell Detection for Docker Commands

### Detecting Git Bash / MINGW Environment

Use these environment variables to detect when path conversion issues may occur:

```bash
# Most reliable: Check for MSYSTEM
if [ -n "$MSYSTEM" ]; then
  echo "Running in Git Bash/MINGW - path conversion needed"
fi

# Alternative: Check uname
if [[ "$(uname -s)" == MINGW* ]]; then
  echo "Running in MINGW environment"
fi

# Environment variable to check:
# MSYSTEM values: MINGW64, MINGW32, MSYS
```

## Solution 1: MSYS_NO_PATHCONV (Recommended for Git Bash)

The most reliable solution for Git Bash on Windows.

### Per-Command Usage

Prefix each Docker command with `MSYS_NO_PATHCONV=1`:

```bash
# Volume mount with $(pwd)
MSYS_NO_PATHCONV=1 docker run -v $(pwd):/app myimage

# Volume mount with absolute path
MSYS_NO_PATHCONV=1 docker run -v /c/Users/project:/app myimage

# Multiple volume mounts
MSYS_NO_PATHCONV=1 docker run \
  -v $(pwd)/data:/data \
  -v $(pwd)/config:/etc/config \
  myimage
```

### Shell-Level Configuration

Disable path conversion for all Docker commands in your session:

```bash
# Add to ~/.bashrc or run in current shell
export MSYS_NO_PATHCONV=1

# Now all Docker commands work normally
docker run -v $(pwd):/app myimage
```

### Function Wrapper (Automatic per Docker Command)

Create a function wrapper that automatically disables path conversion:

```bash
# Add to ~/.bashrc
docker() {
  (export MSYS_NO_PATHCONV=1; command docker.exe "$@")
}

# Or using MSYS2_ARG_CONV_EXCL for MSYS2
docker() {
  (export MSYS2_ARG_CONV_EXCL='*'; command docker.exe "$@")
}

# Make function available in subshells
export -f docker
```

## Solution 2: MSYS2_ARG_CONV_EXCL (MSYS2 Specific)

For MSYS2 environments (not standard Git Bash):

```bash
# Disable all argument conversion
export MSYS2_ARG_CONV_EXCL='*'

# Selective exclusion (specific patterns)
export MSYS2_ARG_CONV_EXCL='--dir=;/test'

# Environment variable conversion exclusion
export MSYS2_ENV_CONV_EXCL='*'
```

## Solution 3: Double Leading Slash

Prefix paths with an extra `/` to prevent conversion:

```bash
# Single slash (converted - BROKEN)
docker run -v /c/Users/project:/app myimage

# Double slash (not converted - WORKS)
docker run -v //c/Users/project:/app myimage

# Works in Git Bash on Windows
# Treated as single slash on Linux (portable)
```

**Advantages:**
- No environment variables needed
- Works without wrapper functions
- Portable (extra slash ignored on Linux)

**Disadvantages:**
- Less readable
- Easy to forget
- Doesn't look like standard Docker syntax

## Solution 4: Use $(pwd) with Proper Escaping

Always use lowercase `$(pwd)` (not `$PWD`) with proper syntax:

```bash
# CORRECT: Round brackets, lowercase pwd, no quotes
MSYS_NO_PATHCONV=1 docker run -v $(pwd):/app myimage

# CORRECT: With subdirectories
MSYS_NO_PATHCONV=1 docker run -v $(pwd)/src:/app/src myimage

# WRONG: Uppercase PWD variable (may not convert correctly)
docker run -v $PWD:/app myimage

# WRONG: Without MSYS_NO_PATHCONV (path gets mangled)
docker run -v $(pwd):/app myimage
```

## Docker Volume Mount Best Practices (Git Bash on Windows)

### For docker run Commands

```bash
# Named volumes (no path conversion issue)
docker run -v my-named-volume:/data myimage

# Bind mount with MSYS_NO_PATHCONV (RECOMMENDED)
MSYS_NO_PATHCONV=1 docker run -v $(pwd):/app myimage

# Bind mount with double slash (ALTERNATIVE)
docker run -v //c/Users/project:/app myimage

# Read-only bind mount
MSYS_NO_PATHCONV=1 docker run -v $(pwd)/config:/etc/config:ro myimage

# Multiple volumes
MSYS_NO_PATHCONV=1 docker run \
  -v $(pwd)/src:/app/src \
  -v $(pwd)/data:/app/data \
  -v my-named-volume:/var/lib/data \
  myimage
```

### For docker-compose.yml Files

Docker Compose files use forward slashes and relative paths - **these work correctly** in Git Bash:

```yaml
# WORKS WITHOUT MODIFICATION in Git Bash
services:
  app:
    image: myimage
    volumes:
      # Relative paths (RECOMMENDED)
      - ./src:/app/src
      - ./data:/app/data

      # Named volumes (RECOMMENDED)
      - my-data:/var/lib/data

      # Windows absolute paths with forward slashes (WORKS)
      - C:/Users/project:/app

      # Unix-style paths (WORKS if referring to WSL/MINGW paths)
      - /c/Users/project:/app

volumes:
  my-data:
```

**Important:** When running `docker compose` commands:

```bash
# No special handling needed for compose files
docker compose up -d

# But if you use command-line volume overrides:
MSYS_NO_PATHCONV=1 docker compose run -v $(pwd)/extra:/extra app
```

## Complete Examples

### Example 1: Simple Application Development

```bash
# Set up environment once per session
export MSYS_NO_PATHCONV=1

# Run with live code reload
docker run -d \
  --name dev-app \
  -v $(pwd)/src:/app/src \
  -v $(pwd)/public:/app/public \
  -p 3000:3000 \
  node:20-alpine \
  npm run dev

# View logs
docker logs -f dev-app
```

### Example 2: Database with Data Persistence

```bash
# Use named volume for database data (no path issues)
docker run -d \
  --name postgres-db \
  -e POSTGRES_PASSWORD=mypassword \
  -v pgdata:/var/lib/postgresql/data \
  -p 5432:5432 \
  postgres:16-alpine

# Mount init scripts with MSYS_NO_PATHCONV
MSYS_NO_PATHCONV=1 docker run -d \
  --name postgres-db \
  -e POSTGRES_PASSWORD=mypassword \
  -v pgdata:/var/lib/postgresql/data \
  -v $(pwd)/init.sql:/docker-entrypoint-initdb.d/init.sql:ro \
  -p 5432:5432 \
  postgres:16-alpine
```

### Example 3: Full Stack with Docker Compose

```bash
# Project structure:
# /c/Users/project/
#   ├── docker-compose.yml
#   ├── backend/
#   ├── frontend/
#   └── data/

# docker-compose.yml (no special path handling needed)
cat > docker-compose.yml <<'EOF'
services:
  backend:
    build: ./backend
    volumes:
      - ./backend/src:/app/src
      - ./data:/app/data
    ports:
      - "4000:4000"

  frontend:
    build: ./frontend
    volumes:
      - ./frontend/src:/app/src
      - ./frontend/public:/app/public
    ports:
      - "3000:3000"
    depends_on:
      - backend

  database:
    image: postgres:16-alpine
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: changeme

volumes:
  db-data:
EOF

# Start everything (works normally)
docker compose up -d

# Override with additional volume (needs MSYS_NO_PATHCONV)
MSYS_NO_PATHCONV=1 docker compose run -v $(pwd)/scripts:/scripts backend bash
```

## Troubleshooting Path Issues

### Problem: "No such file or directory" errors

**Symptoms:**
```bash
Error response from daemon: invalid mount config for type "bind":
bind source path does not exist: C:\Program Files\Git\c\Users\project
```

**Diagnosis:**
- Path has been incorrectly converted by MINGW
- Notice `C:\Program Files\Git\` prefix added

**Solution:**
```bash
# Add M

Related in Ads & Marketing