如何使用 nginx docker 容器访问本地主机上的服务器?
How do I access a server on localhost with nginx docker container?
我正在尝试使用 nginx 的 dockerized 版本作为我的节点 (ExpressJS) 应用程序的代理服务器。在没有对 nginx 进行任何配置和为容器发布端口 80 的情况下,我能够看到默认的 nginx 登录页面。所以我知道很多都在起作用。
现在我可以挂载我的启用站点的目录,其中包含 proxy_pass localhost:3000
的配置。我的节点应用程序在本地运行(不在任何 Docker 容器中),我可以通过端口 3000(即 localhost:3000
)访问它。但是,我假设 nginx 容器正在运行,映射到端口 80,并代理我的 localhost:3000,我将能够看到我的 very 简单(hello world)应用程序.相反,我收到了 502。
我需要将某些东西传递给 docker 吗?这可能是 nginx 配置错误吗?这是我的 nginx 配置:
server {
listen 0.0.0.0:80;
server_name localhost;
location / {
proxy_pass http://localhost:3000;
}
}
我试过使用 this question,但似乎没有用。那是除非我做的事情完全错误。
是的。 Docker 需要了解您的主机。您可以使用 --add-host
开关为其设置别名。在 *nix 框上为名称 "localbox" 创建别名,这将是:
docker run my_repo/my_image --add-host=localbox:<host_name>`
在 boot2docker 上它将是:
docker run my_repo/my_image --add-host=localbox:192.168.59.3`
你应该用 boot2docker ip
returns.
替换“192.168.59.3”
然后,您应该始终通过别名 localbox 访问您的主机,因此只需将您的 nginx 配置更改为:
location / {
proxy_pass http://localbox:3000;
}
您可以得到您当前的IP地址,如图here:
ifconfig en0 | grep inet | grep -v inet6 | awk '{print }'
然后你可以使用 --add-host
标志和 docker run
:
docker run --add-host localnode:$(ifconfig en0 | grep inet | grep -v inet6 | awk '{print $2}') ...
在您的 proxypass
中使用 localnode
而不是 localhost
。
如果您使用 docker-for-mac 18.03 或更新版本,它会自动创建一个特殊的 DNS 条目 host.docker.internal
,动态绑定到主机 inet ip。然后,您可以使用 dns 名称从容器内部的主机 machine 上代理服务 运行 作为 localhost
.
的替代
即nginx 配置文件:
server {
listen 0.0.0.0:80;
server_name localhost;
location / {
proxy_pass http://host.docker.internal:3000;
}
}
最后,如果您使用 Nginx 作为多个服务的反向代理,您可以使用 docker-compose 旋转所有这些。确保仅在 Nginx 服务上公开端口“80:80”。其他服务您可以只公开服务端口而不映射到底层网络,如下所示:
web:
.....
expose:
- 8080
nginx:
.....
port:
- “80:80”
然后使用Nginx配置proxy_passhttp://service-name:port
您根本不需要上游应用程序部分
在 linux,这对我有用:
在docker-compose.yml中,将入口点脚本挂载到nginx容器中:
nginx:
image: nginx:1.19.2
# ...
volumes:
- ./nginx-entrypoint.sh:/docker-entrypoint.d/nginx-entrypoint.sh:ro
入口点的内容将本地地址映射到主机本地地址。
apt update
apt install iproute2 -y
echo "`ip route | awk '/default/ { print }'`\tdocker.host.internal" >> /etc/hosts
然后,您可以在容器内使用 docker.host.internal
.
而不是使用 localhost
我正在尝试使用 nginx 的 dockerized 版本作为我的节点 (ExpressJS) 应用程序的代理服务器。在没有对 nginx 进行任何配置和为容器发布端口 80 的情况下,我能够看到默认的 nginx 登录页面。所以我知道很多都在起作用。
现在我可以挂载我的启用站点的目录,其中包含 proxy_pass localhost:3000
的配置。我的节点应用程序在本地运行(不在任何 Docker 容器中),我可以通过端口 3000(即 localhost:3000
)访问它。但是,我假设 nginx 容器正在运行,映射到端口 80,并代理我的 localhost:3000,我将能够看到我的 very 简单(hello world)应用程序.相反,我收到了 502。
我需要将某些东西传递给 docker 吗?这可能是 nginx 配置错误吗?这是我的 nginx 配置:
server {
listen 0.0.0.0:80;
server_name localhost;
location / {
proxy_pass http://localhost:3000;
}
}
我试过使用 this question,但似乎没有用。那是除非我做的事情完全错误。
是的。 Docker 需要了解您的主机。您可以使用 --add-host
开关为其设置别名。在 *nix 框上为名称 "localbox" 创建别名,这将是:
docker run my_repo/my_image --add-host=localbox:<host_name>`
在 boot2docker 上它将是:
docker run my_repo/my_image --add-host=localbox:192.168.59.3`
你应该用 boot2docker ip
returns.
然后,您应该始终通过别名 localbox 访问您的主机,因此只需将您的 nginx 配置更改为:
location / {
proxy_pass http://localbox:3000;
}
您可以得到您当前的IP地址,如图here:
ifconfig en0 | grep inet | grep -v inet6 | awk '{print }'
然后你可以使用 --add-host
标志和 docker run
:
docker run --add-host localnode:$(ifconfig en0 | grep inet | grep -v inet6 | awk '{print $2}') ...
在您的 proxypass
中使用 localnode
而不是 localhost
。
如果您使用 docker-for-mac 18.03 或更新版本,它会自动创建一个特殊的 DNS 条目 host.docker.internal
,动态绑定到主机 inet ip。然后,您可以使用 dns 名称从容器内部的主机 machine 上代理服务 运行 作为 localhost
.
即nginx 配置文件:
server {
listen 0.0.0.0:80;
server_name localhost;
location / {
proxy_pass http://host.docker.internal:3000;
}
}
最后,如果您使用 Nginx 作为多个服务的反向代理,您可以使用 docker-compose 旋转所有这些。确保仅在 Nginx 服务上公开端口“80:80”。其他服务您可以只公开服务端口而不映射到底层网络,如下所示:
web:
.....
expose:
- 8080
nginx:
.....
port:
- “80:80”
然后使用Nginx配置proxy_passhttp://service-name:port 您根本不需要上游应用程序部分
在 linux,这对我有用:
在docker-compose.yml中,将入口点脚本挂载到nginx容器中:
nginx:
image: nginx:1.19.2
# ...
volumes:
- ./nginx-entrypoint.sh:/docker-entrypoint.d/nginx-entrypoint.sh:ro
入口点的内容将本地地址映射到主机本地地址。
apt update
apt install iproute2 -y
echo "`ip route | awk '/default/ { print }'`\tdocker.host.internal" >> /etc/hosts
然后,您可以在容器内使用 docker.host.internal
.
localhost