NginxProxyManager / nginx-proxy-manager

Docker container for managing Nginx proxy hosts with a simple, powerful interface
https://nginxproxymanager.com
MIT License
22.63k stars 2.63k forks source link

strange behaviour configuring proxy #3283

Open dogeMcdogeface opened 12 months ago

dogeMcdogeface commented 12 months ago

Checklist

Describe the bug On a fresh install, i added host.docker.internal pointing to the host, since i need to reverse proxy an app which i do not have permission to dockerize running on port3000 of the host. I verified inside the container that the app is reachable using curl and indeed it is. I used the webgui to configure a proxy to host.docker.internal:3000 on a certain subomain. This results in a 502 bad gateway when visiting the domain. I manually edited the 1.conf file and added proxy_pass http://host.docker.internal:3000 while commenting the other proxy. Visiting the domain now shows the application correctly.

Trying to figure out if i'd made a configuration error, i created an identical entry from the webgui with a different subdomain (without manually editing the config) and this time it worked with no issue. Deleting the first proxy however, the second one stops working as well.

Nginx Proxy Manager Version v2.10.4

To Reproduce Steps to reproduce the behavior:

  1. Configure dummy server on host machine on port :x
  2. Use webgui to add a proxy configuration to dummy server
  3. Check if it works?

Expected behavior

Expected npm to serve host.docker.internal:x without manual configuration

Screenshots

(this did not work) image (This worked) immagine

Operating System Docker on Ubuntu 22.04.1 LTS

Additional context added to docker-compose.yml

    extra_hosts:
      - "host.docker.internal:host-gateway"
bremme commented 8 months ago

Just came here to say I experience the same issue. I've added:

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

To my docker-compose.yaml file, curl http://host.docker.internal:<my-port> does work, just not the proxy. As a workaround I changed host.docker.internal to 172.17.0.1 and this works as well. But I rather just use host.docker.internal to be 100% this points to the docker host.

Let me know if you need more information to help solve this issue.

MrLoading commented 4 months ago

same problem! (with Rocky OS 9.4 + docker 26.1.2 + nginx-proxy-manager:latest) Below are the steps I've taken and the behaviors observed:

1. Direct Access Within the Container

Executing curl http://host.docker.internal:3000 from inside the container successfully returns a 200 status, indicating that the site is reachable and functions correctly.

2. Proxy Configuration Issue

When configuring a proxy at site.xxx.xxx using the Nginx Proxy Manager GUI, attempting to curl site.xxx.xxx from the host results in a "502 ERROR". The log from within the container shows the following error:

2024/06/02 07:55:58 [error] 287#287: *836 host.docker.internal could not be resolved (3: Host not found), client: xxx.xxx.xxx.xxx, server: site.xxx.xxx, request: "GET / HTTP/2.0", host: "site.xxx.xxx"

3. Custom Nginx Configuration Solution

After configuring the "Custom Nginx Configuration" in the Nginx Proxy Manager GUI with the following setup, the issue resolves:

location / {
proxy_pass http://host.docker.internal:3000/;
}

Configuration Comparisons (inside the container)

server { set $forward_scheme http; set $server "host.docker.internal"; set $port 3000;

listen 80; listen [::]:80;

listen 443 ssl http2; listen [::]:443 ssl http2;

server_name site.xxx.xxx;

SSL and Logs

... Omit

location / { add_header X-Served-By $host; proxy_set_header Host $host; proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_pass $forward_scheme://$server:$port$request_uri; }

Custom

include /data/nginx/custom/server_proxy[.]conf; }


### **With Custom Nginx Configuration**:

map $scheme $hsts_header { https "max-age=63072000; preload"; }

server { set $forward_scheme http; set $server "host.docker.internal"; set $port 3000;

listen 80; listen [::]:80;

listen 443 ssl http2; listen [::]:443 ssl http2;

server_name site.xxx.xxx;

SSL and Logs

... Omit

location / { proxy_pass http://host.docker.internal:3000; }

Custom

include /data/nginx/custom/server_proxy[.]conf; }


I'm seeking insights on why the default configuration results in a 502 error and how the custom configuration resolves this issue. Any guidance or suggestions would be greatly appreciated.
MrLoading commented 4 months ago

After investigating, I believe the issue I encountered can be described as follows:

  1. In Linux, when using --add-host=host.docker.internal:host-gateway or specifying extra_hosts: "host.docker.internal:host-gateway" in the compose.yaml, Docker writes the special hostname "host.docker.internal" into the container's /etc/hosts.

  2. The DNS resolver within the NPM Docker container is set to 127.0.0.11, which can resolve container names normally, but does not resolve the special hostname "host.docker.internal".

  3. The DNS resolver configuration in the NPM's nginx config file is as follows:

    resolver 127.0.0.11 valid=10s;
  4. Nginx attempts to resolve all static addresses needed at startup or when refreshing its configuration (such as proxy_pass http://host.docker.internal:3000). Unfortunately, Nginx queries the resolver at runtime for addresses that use variables (such as proxy_pass $forward_scheme://$server:$port) and does not consider the contents of /etc/hosts.

Therefore, either Docker should provide a more robust implementation for "host.docker.internal," or the Docker version of NPM should specially treat this hostname to automatically convert it to a static address (like "172.17.0.1", which varies and requires checking with ip addr show).

For me, replacing "host.docker.internal" with "172.17.0.1" in the GUI configuration for the reverse proxy worked very well. I am not a professional, so if any errors in my explanation or if anyone knows a better solution, please let me know.