nginx-proxy-manager
nginx-proxy-manager copied to clipboard
strange behaviour configuring proxy
Checklist
- 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
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:
- Configure dummy server on host machine on port :x
- Use webgui to add a proxy configuration to dummy server
- Check if it works?
Expected behavior
Expected npm to serve host.docker.internal:x
without manual configuration
Screenshots
(this did not work)
(This worked)
Operating System Docker on Ubuntu 22.04.1 LTS
Additional context added to docker-compose.yml
extra_hosts:
- "host.docker.internal:host-gateway"
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.
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)
- Without 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 / {
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.
After investigating, I believe the issue I encountered can be described as follows:
-
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.
-
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".
-
The DNS resolver configuration in the NPM's nginx config file is as follows:
resolver 127.0.0.11 valid=10s;
-
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.