Hi I am running docker from within WSL2, docker dekstop version 4.55.0.
I have a simple Spring boot API that is exposing prometheus endpoint. I can’t seem to curl it from within my docker container using host.docker.internal.
❯ docker run --rm -it --add-host=host.docker.internal:host-gateway curlimages/curl sh
~ $ curl http://host.docker.internal:8081/actuator/prometheus
curl: (7) Failed to connect to host.docker.internal port 8081 after 3 ms: Could not connect to server
❯ docker run --rm -it --add-host=host.docker.internal:host-gateway curlimages/curl sh
~ $ curl -v http://172.31.230.230:8081/actuator/prometheus
* Trying 172.31.230.230:8081...
* Established connection to 172.31.230.230 (172.31.230.230 port 8081) from 172.17.0.2 port 34284
* using HTTP/1.x
> GET /actuator/prometheus HTTP/1.1
> Host: 172.31.230.230:8081
> User-Agent: curl/8.18.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200
< Content-Type: text/plain;version=0.0.4;charset=utf-8
< Content-Length: 24137
< Date: Thu, 08 Jan 2026 14:21:30 GMT
<
# HELP application_ready_time_seconds Time taken for the application to be ready to service requests
# TYPE application_ready_time_seconds gauge
application_ready_time_seconds{main_application_class="com.ecommerce.product.ProductApplication"} 14.495
Is there any reason as to why host.docker.internal wasn’t working?
The reason I ask is that I am running prometheus inside docker and was trying to scrape from host.docker.internal:8081 and it wasn’t working. After changing it to that IP address it worked. Why is that the case? Why didn’t host.docker.internal work.
Docker was developed as a Linux tool. Docker Desktop on Windows is usually running all containers inside a Linux VM. As far as I know host.docker.internal is provided by Docker Desktop automatically (doc):
host.docker.internal Resolves to the internal IP address of your host
Using --add-host=host.docker.internal:host-gateway is usually a workaround for Docker-CE on Linux, when not using Docker Desktop.
Running the container without --add-host=host.docker.internal:host-gateway on WSL I can still curl the API using curl -v http://172.31.230.230:8081/actuator/prometheus, but when I use host.docker.internal I get
~ $ curl -v http://host.docker.internal:8081/actuator/prometheus
* Host host.docker.internal:8081 was resolved.
* IPv6: (none)
* IPv4: 192.168.65.254
* Trying 192.168.65.254:8081...
* connect to 192.168.65.254 port 8081 from 172.17.0.2 port 58662 failed: Connection refused
* Failed to connect to host.docker.internal port 8081 after 4 ms: Could not connect to server
* closing connection #0
curl: (7) Failed to connect to host.docker.internal port 8081 after 4 ms: Could not connect to server
host.docker.internal in Docker Desktop points to the localhost of the actual host. The IP you shared looks like the IP of WSL. If the service on port 8081 isn’t listening on localhost, only on the WSL IP, host.docker.internal will not help.
I rarely use WSL for this, so I am not sure about when and how ports are forwarded from Windows to WSL, but I think the service on port 8081 has to be available on the localhost of Windows.
Cany ou try
curl http://localhost:8081/actuator/prometheus
on Windows in Powershell? Or just try http://localhost:8081/actuator/prometheus in a web browser on Windows.
Please share the output of netstat -p tcp -q | Select-String -Pattern ":8081", so we can see that the process actually binds 0.0.0.0:8081, and not just 127.0.0.1:8081.
After discussing with @rimelek seems I was mistaken about how host.docker.internal works, and that it should work, even if the process only binds on 127.0.0.1:8081 on the host.
I cannot reproduce this issue. I can make host.docker.internal not work, but than the URL doesn’T work from the web browser either.
It could still help if you could tell us more about how you start that Sprint boot API with the prometheus endpoint. Is it running in a container to which you forward ports? Is it running directly on Windows or inside a WSL distribution? Do you know what IP addresses that is supposed to listen on? Can you find any configuration related to that if you didn’t set it?
Yes, but on what IP? I gues if you don’t know, it is on default setting. I don’t know what the default is, just assume it should be on all avalable IP addresses.
I am trying to figure out how it is possible that the endpoint works for you from a webbrowser on “localhost” but not when you are using host.docker.internal without --add-host.
I know you are using Docker Desktop, but have you also installed Docker inside the WSL distribution? Docker Desktop should override it, but I have no other ideas what could break host.docker.internal
I think it’s on default setting. I think I might have installed docker inside the WSL distribution. Running the command docker context ls gives the following output:
NAME DESCRIPTION DOCKER ENDPOINT ERROR
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
desktop-linux Docker Desktop npipe:////./pipe/dockerDesktopLinuxEngine
That is just the client. The question is whether you installed the daemon or not. And if that is running. Running the following command should show if a Docker CE daemon is running in WSL: