GetHostDockerInternal determines the correct host.docker.internal configuration for containers. Returns HostDockerInternal containing IP, extra_hosts value, and debug message. The function handles platform-specific cases: - Docker Desktop: Uses built-in host.docker.internal - Linux: Uses host-gatew
()
| 47 | // - Colima: Uses fixed IP 192.168.5.2 |
| 48 | // - IDE location overrides: Respects global xdebug_ide_location settings |
| 49 | func GetHostDockerInternal() *HostDockerInternal { |
| 50 | hostDockerInternalOnce.Do(func() { |
| 51 | var ipAddress string |
| 52 | var extraHost string |
| 53 | var message string |
| 54 | |
| 55 | switch { |
| 56 | case nodeps.IsIPAddress(globalconfig.DdevGlobalConfig.XdebugIDELocation): |
| 57 | ipAddress = globalconfig.DdevGlobalConfig.XdebugIDELocation |
| 58 | message = fmt.Sprintf("xdebug_ide_location=%s, see https://docs.ddev.com/en/stable/users/configuration/config/#xdebug_ide_location", globalconfig.DdevGlobalConfig.XdebugIDELocation) |
| 59 | |
| 60 | case globalconfig.DdevGlobalConfig.XdebugIDELocation == globalconfig.XdebugIDELocationContainer: |
| 61 | // If the IDE is actually listening inside container, then localhost/127.0.0.1 should work. |
| 62 | ipAddress = "127.0.0.1" |
| 63 | message = fmt.Sprintf("xdebug_ide_location=%s, see https://docs.ddev.com/en/stable/users/configuration/config/#xdebug_ide_location", globalconfig.DdevGlobalConfig.XdebugIDELocation) |
| 64 | |
| 65 | case IsColima(): |
| 66 | // Lima specifies this as a named explicit IP address at this time |
| 67 | // see https://lima-vm.io/docs/config/network/user/#host-ip-19216852 |
| 68 | ipAddress = "192.168.5.2" |
| 69 | message = "IsColima" |
| 70 | |
| 71 | case nodeps.IsCodespaces(): |
| 72 | message = "IsCodespaces uses 'host-gateway' in extra_hosts" |
| 73 | |
| 74 | case nodeps.IsDevcontainer(): |
| 75 | message = "IsDevcontainer uses 'host-gateway' in extra_hosts" |
| 76 | |
| 77 | case nodeps.IsWSL2() && nodeps.IsWSL2NoneMode(): |
| 78 | // WSL2 networking=none disables the network bridge entirely; no internet |
| 79 | // access and no path to the Windows host from the distro or containers. |
| 80 | message = "IsWSL2 with networkingMode=none; no internet access and no network path to Windows host" |
| 81 | |
| 82 | case nodeps.IsWSL2() && IsDockerDesktop(): |
| 83 | // If IDE is on Windows, return; we don't have to do anything. |
| 84 | message = "IsWSL2 and IsDockerDesktop" |
| 85 | |
| 86 | case nodeps.IsWSL2() && globalconfig.DdevGlobalConfig.XdebugIDELocation == globalconfig.XdebugIDELocationWSL2: |
| 87 | // If IDE is inside WSL2 then the normal Linux processing should work |
| 88 | message = fmt.Sprintf("xdebug_ide_location=%s uses 'host-gateway' in extra_hosts, see https://docs.ddev.com/en/stable/users/configuration/config/#xdebug_ide_location", globalconfig.DdevGlobalConfig.XdebugIDELocation) |
| 89 | |
| 90 | case nodeps.IsWSL2() && nodeps.IsWSL2VirtioProxyMode() && !IsDockerDesktop(): |
| 91 | // In virtioproxy mode, the default gateway is the actual network router, |
| 92 | // not the Windows host. We need the Windows vEthernet (WSL) Hyper-V interface IP. |
| 93 | virtioProxyIP, err := getWSL2VirtioProxyWindowsIP() |
| 94 | if err == nil { |
| 95 | ipAddress = virtioProxyIP |
| 96 | message = "IsWSL2 virtioproxy and !IsDockerDesktop; received from Windows vEthernet (WSL) interface" |
| 97 | } else { |
| 98 | // No Hyper-V virtual switch found (common on ARM64 Windows). |
| 99 | // Fall back to WSL2's own physical IP so host.docker.internal resolves. |
| 100 | // This enables IDE-in-WSL2 (xdebug_ide_location=wsl2) but not Windows-side IDE. |
| 101 | if wsl2PhysIP, physErr := getWSL2PhysicalIP(); physErr == nil { |
| 102 | ipAddress = wsl2PhysIP |
| 103 | message = fmt.Sprintf("IsWSL2 virtioproxy and !IsDockerDesktop; no vEthernet (WSL) found, using WSL2 physical IP %s (IDE-in-WSL2 only)", wsl2PhysIP) |
| 104 | } else { |
| 105 | message = fmt.Sprintf("IsWSL2 virtioproxy and !IsDockerDesktop; unable to get IP: %v", err) |
| 106 | } |