nginx-proxy-manager icon indicating copy to clipboard operation
nginx-proxy-manager copied to clipboard

host.docker.internal not working with nginx (while curl does)

Open Galileon-venta opened this issue 4 years ago • 19 comments

  • Have you pulled and found the error with jc21/nginx-proxy-manager:latest docker image?
    • Yes
  • Are you sure you're not using someone else's docker image?
    • Yes
  • Have you searched for similar issues (both open and closed)?
    • Yes

Describe the bug I've created a container with the standard setup including 1 tweak: I've added

extra_hosts:
  - "host.docker.internal:host:gateway"

I can curl the gitlab from inside my container without any problem but access via domain from outside leads to 502 Bad Gateway error.

Nginx Proxy Manager Version 2.9.4

Expected behavior I can reverse proxy to a gitlab instance running on the docker host on non standard port

Operating System debian vm on proxmox with Intel x86 Architecture

Galileon-venta avatar Jul 08 '21 06:07 Galileon-venta

Any update?

ij5 avatar Jan 18 '22 07:01 ij5

Any update on this?

devadattas avatar Mar 21 '22 10:03 devadattas

Looks like NGINX doesn't check /ect/hosts when resolving. Workaround seems to be to point to 172.17.0.1 for now instead.

phocks avatar Oct 23 '22 21:10 phocks

In this case this could be a spelling mistakes:

host:gateway should be host-gateway

eddyJK avatar May 09 '23 17:05 eddyJK

A possible fix was suggested here: https://github.com/NginxProxyManager/nginx-proxy-manager/issues/259#issuecomment-1125197753

fritzmg avatar Jul 12 '23 10:07 fritzmg

I worked around this issue by using docker.io/qoomon/docker-host:3.1.2 to forward all of the ports from the relevant containers to the host.

AnastasiyaSoyka avatar Jul 17 '23 19:07 AnastasiyaSoyka

I am also having an issue with this. I can successfully curl a home assistant container on the host.docker.internal localhost domain when I exec into the NPM container but I get a "host could not be found" error when trying to use the reverse proxy.

2023/09/25 00:30:04 [error] 301#301: *3025 host.docker.internal could not be resolved (3: Host not found), client: (redacted ip of requester), server: (redacted hostname), request: "GET / HTTP/2.0", host: "(redacted hostname)"

Switching it back to a direct ip route via the LAN has it working fine though.

Nitrousoxide avatar Sep 25 '23 15:09 Nitrousoxide

I'm having this issue too. Surprised this hasn't been fixed by now!

rothn avatar Oct 24 '23 22:10 rothn

same issue here

slayernominee avatar Dec 24 '23 19:12 slayernominee

The issue is with Docker's default DNS 127.0.0.11 because it does not include extra_hosts and --add-host entries which are stored to /etc/hosts file. When resolver is set, nginx will not read /etc/hosts. 2 workarounds are:

  1. Change host.docker.internal to 172.17.0.1 which it's not sure whether Docker will always use the same IP.
  2. Install dnsmasq and run dnsmasq inside the container. Set nginx resolver to 127.0.0.1.

MobCode100 avatar Feb 28 '24 04:02 MobCode100

Same issue. Curl is fine, but when I add proxy host to host.docker.internal the "bad gateway" error appears

brinza888 avatar Jun 22 '24 00:06 brinza888

I highly discourage using 172.17.0.1. This is not always the default gateway! But you can force docker to use a fixed gateway for the host like this:

Docker Compose

networks:
  default:
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          ip_range: 172.28.5.0/24
          gateway: 172.28.5.254

Create the network externally and link your container to it

docker network create \
  --driver=bridge \
  --subnet=172.28.0.0/16 \
  --ip-range=172.28.5.0/24 \
  --gateway=172.28.5.254 \
  host-gateway

Other workarounds would be to create a container that is merged with the npm network via network_mode: "service:npm" and inside that container run dnsmasq or systemd-resolved which both include /etc/hosts and then set the resolver to 127.0.0.1 / 127.0.0.53 in the nginx config.

Another option is to add a socat container, which internally forwards a port to your host or use a dummy container with a script to get the gateway ip from host.docker.internal and forward all traffic via iptables. https://github.com/qoomon/docker-host This project uses the iptables approach.

I also vote that dnsmasq or systemd-resolved gets integrated in the npm container with the resolver set in the config!

5andr0 avatar Jul 10 '24 19:07 5andr0

Issue is now considered stale. If you want to keep it open, please comment :+1:

github-actions[bot] avatar Feb 09 '25 02:02 github-actions[bot]

I'm still looking for a solution to this issue. I run homeassistant in host network mode in docker, NPM in a docker network with some other containers. I've never been able to proxy the homeassistant web interface via NPM.

kmarius avatar Feb 09 '25 08:02 kmarius

I have the same issue. The funny thing is that it works on macos, but if i run the same container on almalinux, it doesn't work!

vmatt avatar Feb 27 '25 18:02 vmatt

Also interested in this, to proxy services running in other containers on the same host in TrueNAS. Currently it works if I set all my proxy destinations to the host's externally accessible IP address (192.168.0.x), but if I change that address, it can get annoying to update each destination individually.

auxym avatar Mar 12 '25 00:03 auxym

this seems lie a joke to me.. so long to fix this

filisko avatar Mar 20 '25 14:03 filisko

I'm still looking for a solution to this issue. I run homeassistant in host network mode in docker, NPM in a docker network with some other containers. I've never been able to proxy the homeassistant web interface via NPM.

Aside from the know issue with nginx resolving host.docker.local in /etc/hosts, I was able to proxy to homeassistant via the host machine IP and/or docker container gateway IP without installing dnsmaq inside NPM container .

On a standard docker install, a network bridge is setup and the IP range is usually 172.17.0.0/16 and the gateway 172.17.0.1

docker network inspect bridge

Enter the gateway IP in NPM proxy host. It should be fine even if your NPM container is on a different subnet like 172.21.0.0/16 since the host routing table would route appropriately to 172.17.0.1. Image

Following this https://www.home-assistant.io/integrations/http#reverse-proxies

My addition to homeassistant configuration.yaml

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.16.0.0/12

I used 172.16.0.0/12 to cover the private ranges that docker might assign my NPM container.

Eskimo-Sitcom avatar Jul 06 '25 00:07 Eskimo-Sitcom

What extra_hosts does?

extra_hosts:
  - "host.docker.internal:host-gateway"

It means you have HOST_IP in /etc/hosts in your container. This is what docker engine does but it's not DNS service.

you can check via exec 'cat /etc/hosts' it will have like the ip is depends on your docker daemon.

/ # cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::  ip6-localnet
ff00::  ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
0.250.250.254   host.docker.internal
...

So you can access to host successfully via curl command.

What nginx does

Nginx doesn't read hosts's /etc/hosts generally. It always see DNS server which OS relies on. So your container may not having meaning to have extra host.

There is some complex problem about it and infra engineer gets same problem everyday. This is kind of strategy and concept of nginx to resolve DNS problem to ensure the environment setup although it is linux concept to read /etc/hosts as default

I believe this product also has same problem because nginx is base engine.

Why it can be work on your Windows or MAC? Linux docker and other environment are has different engine actually. Desktop version docker engine intercept DNS query and response properly for easy environment setup. So, it depends on which docker engine you are using and linux docker doesn't offer it.

Solution

As @5andr0 said you'd better to use DNS server for it.

I'm not this product user but you may set somewhere DNS server in nginx.

Since dnsmasq is reading /etc/hosts as default, When dnsmasq is targeted as DNS server and it responses IP of host.docker.internal. e.g.)

#/etc/nginx.conf

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    resolver dnsmasq valid=1s;  #dnsmasq is DNS server hostname
}
services:
  dnsmasq:
    image: dockurr/dnsmasq
    expose:
      - 53
    extra_hosts:
      - "host.docker.internal:host-gateway"
  proxy:
    image: nginx:alpine

I generally recommend side car container instead of installing two process in same container because it needs additional image building and application container is generally for single process as concept.

It is really depends on load balancer's implementation i believe the maintainer of this product doesn't have much power to do it. Because it might be way out of concept of this product but nginx itself.

Since we are using container, it comes with additional issues. So other cloud native solutions like traefik are used.

GregYeo avatar Nov 21 '25 20:11 GregYeo