Docker nginx代理到主机

Jah*_*hel 11 nginx docker docker-compose

简短的介绍:

Nginx在docker上运行,如何配置nginx以便它将调用转发给主机.

详细描述:

我们有一个Web应用程序与几个后端通信(让我们说rest1,rest2和rest3).我们负责rest1.

让我们考虑一下,我rest1在我的电脑上手动启动并在2345端口上运行.我希望nginx(在docker中运行)将所有调用重定向rest1到我自己的运行实例(注意,实例在主机上运行,​​而不是任何容器,而不是在docker中).对于rest2rest3其他一些docker节点或者可能是其他一些服务器(谁在乎).

我在寻找的是:

  1. docker-compose.yml 配置(如果需要).
  2. nginx配置.

提前致谢.

Far*_*ahi 10

像下面这样配置nginx(确保你替换了Docker Host的IP)并将其保存为default.conf

server {
    listen       80;
    server_name  _;
    location / {
        proxy_pass http://<IP of Docker Host>;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在调出容器:

docker run -d --name nginx -p 80:80 -v /path/to/nginx/config/default.conf:/etc/nginx/conf.d/default.conf nginx
Run Code Online (Sandbox Code Playgroud)

  • 使用 bash 脚本,首先是 `hostname -I`,然后是 `grep` 范围,然后是 `sed` 到配置文件中并替换。 (3认同)
  • @MarissaLevy 如果 docker-host 在 DNS 服务器上有一个可供容器使用的名称,那么您也可以使用 dns。 (2认同)
  • 如果 docker-for-mac 是主机,则 IP 是 `host.docker.internal` - https://docs.docker.com/docker-for-mac/networking/#per-container-ip-addressing-is-not-可能的 (2认同)

小智 8

如果您使用的是 Docker Compose 文件版本 3,则根本不需要任何特殊的docker-compose.yml文件配置,只需使用特殊的 DNS 名称host.docker.internal即可访问主机服务,如下nginx.conf例所示:

events {
    worker_connections  1024;
}

http {
    upstream host_service {
       server host.docker.internal:2345;
    }

    server {
        listen 80;

        access_log  /var/log/nginx/http_access.log  combined;
        error_log   /var/log/nginx/http_error.log;

        location / {
            proxy_pass http://host_service;

            proxy_set_header    Host                $http_host;
            proxy_set_header    X-Real-IP           $realip_remote_addr;
            proxy_set_header    X-Forwarded-Proto   $scheme;
            proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;

            proxy_http_version 1.1;
            proxy_set_header Connection "";
        }
    }
 }

Run Code Online (Sandbox Code Playgroud)

  • host.docker.internal 看起来在 Linux 上不支持 https://github.com/docker/for-linux/issues/264 (5认同)

ija*_*vid 5

解决方案1

使用network_mode: host,这会将您的 nginx 实例绑定到主机的网络接口。这可能会在运行多个 nginx 容器时导致冲突:每个暴露的端口都绑定到主机的接口。

解决方案2

我正在为我想向外界公开的每项服务运行更多的 nginx 实例。为了保持 nginx 配置简单并避免将每个 nginx 绑定到主机,请使用容器结构:

dockerhost - 一个虚拟容器 network_mode: host

proxy - nginx 容器用作托管服务的代理,

链接dockerhostproxy,这将/etc/hostsproxycontianer 中添加一个条目- 我们可以在 nginx 配置中使用“dockerhost”作为主机名。

docker-compose.yaml

version: '3'
services:
  dockerhost:
    image: alpine
    entrypoint: /bin/sh -c "tail -f /dev/null"
    network_mode: host
  proxy:
    image: nginx:alpine
    links: 
     - dockerhost:dockerhost
    ports:
     - "18080:80"
    volumes:
     - /share/Container/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
Run Code Online (Sandbox Code Playgroud)

默认配置文件

 location / {
        proxy_pass http://dockerhost:8080;
Run Code Online (Sandbox Code Playgroud)

这种方法允许我们为我的服务器上运行的每个服务自动生成 let's encrtypt 证书。如果有兴趣,我可以发布有关解决方案的要点。

  • 看来解决方案2已经不起作用了。代理容器的 /etc/hosts 中没有出现 dockerhost 记录 (3认同)