如何使用 nginx docker 容器访问 localhost 上的服务器?

Posted

技术标签:

【中文标题】如何使用 nginx docker 容器访问 localhost 上的服务器?【英文标题】:How do I access a server on localhost with nginx docker container? 【发布时间】:2015-03-04 19:03:15 【问题描述】:

我正在尝试使用 nginx 的 docker 化版本作为我的节点 (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,但似乎没有帮助。除非我做错了什么。

【问题讨论】:

Connect to Local mysql Server Through Docker?的可能重复 我也试过了,但似乎无法让它工作。我知道这个类似的问题已经被问过很多次,甚至我得到的 502 错误也是如此,但这些都没有奏效。我下班回家后会重新检查。 DNS ftw,imo。主机有一个名字;) docker on linux, version >= 20.04 可以使用带有运行标志的host.docker.internal;见***.com/a/61424570/2014893 【参考方案1】:

如果您使用 docker-for-mac 18.03 或更高版本,它会自动创建一个特殊的 DNS 条目 host.docker.internal,该条目动态绑定到主机 inet ip。然后,您可以使用 dns 名称从容器内部代理在主机上运行的服务,作为 localhost 的替代。

即一个 nginx 配置文件:

server 
  listen 0.0.0.0:80;
  server_name localhost;

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

【讨论】:

我使用了这个解决方案!谢谢 简单易懂 注意:host.docker.internal 不适用于 linux。 除非你设置extra-hosts***.com/a/43541732/6790541 这在 Windows 10 主机上也适用于我。【参考方案2】:

你可以得到你当前的IP地址如图here:

ifconfig en0 | grep inet | grep -v inet6 | awk 'print $2'

然后您可以将--add-host 标志与docker run 一起使用:

docker run --add-host localnode:$(ifconfig en0 | grep inet | grep -v inet6 | awk 'print \$2') ...

在您的proxypass 中使用localnode 而不是localhost

【讨论】:

这是正确的,但并不完全适合我。一方面,我在笔记本电脑上工作,所以我提取 ip 的方法明显不同。我尝试使用相同的方法更改en0,但一直使用addr:192.xxx.x.xx 获得结果,所以我最终只是将其硬编码。我将使用什么实用程序来剥离开头addr:,因为前提是它不适用于docker。不过还是谢谢你。我正在为遇到此问题的其他人写此评论。 没关系,我使用sed 来去除开头的addr:。如您所知,我不是管理员 :) 很棒的建议。谢谢,伙计。【参考方案3】:

是的。 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`

您应该将“192.168.59.3”替换为boot2docker ip 返回的任何内容。

然后,您应该始终通过别名 localbox 访问您的主机,因此只需将您的 nginx 配置更改为:

location / 
  proxy_pass http://localbox:3000;
 

【讨论】:

【参考方案4】:

在 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 $3 '`\tdocker.host.internal" >> /etc/hosts

然后,您可以使用docker.host.internal,而不是在容器内使用localhost

【讨论】:

【参考方案5】:

最后,如果您使用 Nginx 作为多个服务的反向代理,您可以使用 docker-compose 来旋转所有这些。确保仅在 Nginx 服务上公开端口“80:80”。其他服务您可以只公开服务端口而不映射到底层网络,如下所示:

web:
.....
    expose:
       - 8080
nginx:
.....
    port:
        - “80:80”

然后使用Nginx配置proxy_pass http://service-name:port 你根本不需要上游应用部分

【讨论】:

不清楚您在这里所说的我们不需要的“上游应用程序部分”是什么意思。如果http://service-name 是您的外部域而不是本地主机,那么这最终也不是很便携。这是我找到的 localhost 的第一个替代方案,但我不喜欢它,因为我不能确定我的 nginx 重定向实际上不会返回到 Internet 只是为了进入不同的端口。跨度> 请阅读文档,这是一个您应该熟悉的技术术语。 nginx.org/en/docs/http/ngx_http_upstream_module.html 这是一个我熟悉的技术术语,但我不希望每个人都如此,我什至不确定你指的是什么。另外,我不知道您为什么提到它,因为上面没有其他人提到“上游”。我不会将“上游”模块视为初学者功能,因此说“您应该知道这一点”并不是很有趣。这就是 ***,人们来这里是因为他们不可能知道所有事情。

以上是关于如何使用 nginx docker 容器访问 localhost 上的服务器?的主要内容,如果未能解决你的问题,请参考以下文章

通过 nginx 或 traefik 通过 html 网页访问 docker 容器 websocket?

阿里云配置Nginx访问(docker部署)

访问docker中的nginx容器部署

linux下docker启动nginx无法访问80端口

使用 Docker 运行 Nginx 容器

Nginx - Docker 容器化 Nginx 部署前端 Vue 项目访问 404