【问题标题】:Docker Nginx Proxy: how to route traffic to different container using path and not hostnameDocker Nginx 代理:如何使用路径而不是主机名将流量路由到不同的容器
【发布时间】:2017-01-23 16:01:42
【问题描述】:

可以说现在我在不同路径上的同一台服务器上运行了不同的应用程序:

  • 10.200.200.210/app1
  • 10.200.200.210/app2
  • 10.200.200.210/app3

我想使用 nginx 作为代理在不同的 Docker 容器上运行每个应用程序。

我尝试了jwilder/nginx-proxy,如果我使用不同的域名(app1.domain.com、app2.domain.com 等)效果很好,但我无法使用域,我需要使用相同的 IP .

我也不能使用不同的端口,例如:

  • 10.200.200.210:81/app1
  • 10.200.200.210:82/app2
  • 10.200.200.210:83/app3

所有都必须在端口 80 上工作。

  1. 有没有办法配置 jwilder/nginx-proxy 来做到这一点?
  2. 是否有另一个像 jwilder/nginx-proxy 这样的 Docker 映像可以制作它。
  3. 或者请您给我一些提示,让我自己构建一个 nginx docker 容器?

【问题讨论】:

标签: nginx docker proxy


【解决方案1】:

只需使用nginx 镜像创建容器,**记得设置 net "host" **这将使您的容器与主机共享相同的地址和端口。挂载 nginx.conf 文件和配置代理表。例如:

泊坞窗命令:

docker run --name http-proxy -v /host/nginx.conf:/etc/nginx/nginx.conf --net host -itd --restart always nginx

nginx.conf:

server {
  listen 80;
  location /app1 {
    proxy_pass YOUR_APP1_URL;
  }
  location /app2 {
    proxy_pass YOUR_APP2_URL;
  }
}

【讨论】:

    【解决方案2】:

    如果有人仍在寻找答案。 jwilder/nginx-proxy 允许您在代理范围或每个 VIRTUAL_HOST 基础上使用自定义 Nginx 配置。

    以下是使用 Per-VIRTUAL_HOST 位置配置的方法。

    1. 在您的项目文件夹中创建另一个文件夹 - “vhost.d”。
    2. 在“vhost.d”文件夹中使用自定义 nginx 配置创建文件“whoami.local”。 此文件必须与 VIRTUAL_HOST 同名!

    ./vhost.d/whoami.local

    location /app1 {
      proxy_pass http://app1:8000;
    }
    
    location /app2 {
      proxy_pass http://app2:8000;
    }
    
    1. 创建 docker-compose.yml 文件。

    ./docker-compose.yml

    version: '3'
    
    services:
      nginx-proxy:
        image: jwilder/nginx-proxy
        ports:
        - "8080:80"
        volumes:
        - /var/run/docker.sock:/tmp/docker.sock:ro
        - /path/to/vhost.d:/etc/nginx/vhost.d:ro
    
      gateway:
        image: jwilder/whoami
        environment:
        - VIRTUAL_HOST=whoami.local
    
      app1:
        image: jwilder/whoami
    
      app2:
        image: jwilder/whoami
    
    1. 运行 docker-compose up
    2. 检查配置

    在 bash 中运行:

    $ curl -H "Host: whoami.local" localhost:8080
    I'm 1ae273bce7a4
    $ curl -H "Host: whoami.local" localhost:8080/app1
    I'm 52b1a7b1992a
    $ curl -H "Host: whoami.local" localhost:8080/app2
    I'm 4adbd3f9e7a0
    $ docker ps
    CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                  NAMES
    6a659a4d4b0a        jwilder/nginx-proxy   "/app/docker-entrypo…"   54 seconds ago      Up 53 seconds       0.0.0.0:8080->80/tcp   nginxreverseproxy_nginx-proxy_1
    4adbd3f9e7a0        jwilder/whoami        "/app/http"              54 seconds ago      Up 53 seconds       8000/tcp               nginxreverseproxy_app2_1
    52b1a7b1992a        jwilder/whoami        "/app/http"              54 seconds ago      Up 53 seconds       8000/tcp               nginxreverseproxy_app1_1
    1ae273bce7a4        jwilder/whoami        "/app/http"              54 seconds ago      Up 53 seconds       8000/tcp               nginxreverseproxy_gateway_1
    

    您也可以将“whoami.local”域添加到 /etc/hosts 文件并直接调用该域。

    /etc/hosts

    ...
    127.0.0.1   whoami.local
    ...
    

    结果:

    $ curl whoami.local:8080
    I'm 52ed6da1e86c
    $ curl whoami.local:8080/app1
    I'm 4116f51020da
    $ curl whoami.local:8080/app2
    I'm c4db24012582
    

    【讨论】:

    • 我正在寻找的解决方案!
    【解决方案3】:

    这是完整的nginx.conf

    它将所有重定向到根目录,并且仅将/api 重定向到不同的容器。

    Source and an example container using it

    user  nginx;
    worker_processes  1;
    
    error_log  /var/log/nginx/error.log;
    
    events {
        worker_connections  1024;
    }
    
    
    http {
      server {
            listen 80;
            location / {
                proxy_pass http://frontend:3000/;
            }
            location /api {
                proxy_pass http://backend/api;
        }
      }
    }
    

    【讨论】:

      【解决方案4】:

      只要把它放在 /etc/nginx/nginx.conf 中

          worker_processes  1;
      
          error_log  /var/log/nginx/error.log;
      
          events {
              worker_connections  1024;
          }
      
      
          http {
            server {
                  listen 80;
      
                  location /api {
                      proxy_pass http://awesome-api;
                      proxy_redirect     off;
                      proxy_set_header   Host $host;
                      proxy_set_header   X-Real-IP $remote_addr;
                      proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
                      proxy_set_header   X-Forwarded-Host $server_name;
                  }
            }
          }
      
      

      【讨论】:

        【解决方案5】:

        默认桥接网络在172.17.0.1 上有网关。你可以在你的nginx.conf中使用这个IP地址

        server {
            listen 80;
            server_name example.com;
        
            location /app1 {
                proxy_pass  http://172.17.0.1:81;
            }
            location /app2 {
                proxy_pass  http://172.17.0.1:82;
            }
        }
        

        它们可以使用端口80从外部访问

        您可以通过运行命令docker network inspect bridge检查您的网桥网关IP地址

        【讨论】:

          【解决方案6】:

          我的情况有点不同。我正在开发一个项目,其中 Django 和其他几个应用程序位于 nginx 后面(充当反向代理)

          接受的解决方案对我不起作用,我认为这是因为各种应用程序不提供文件(即 /app1-uri/bla/blo/bli//app1-uri/bla/blo/bli 完全相同)。收集所有静态文件供 nginx 服务。

          in the docs here 解释了“有问题的”行为。本质上,nginx 会在不带斜杠的情况下获取 uri,并尝试将它们解析为资源,如果不能,则重定向到 /bla/blo/bli/ 而不是 /app1-uri/bla/blo/bli/

          这最终对我有用。在此示例中,app1-urirepairapp

          server {
              listen 80;
              listen 443 ssl http2;
              
              ...
          
              # This is the line that fixes the issue.
              rewrite ^/repairapp/([^static].*[^/])$ /repairapp/$1/ permanent;
              
              # This is nginx serving my static files
              location /repairapp/static/ {
                  alias /var/www/repairapp/static/;
              }
              
              # This is the uri that maps to my app (no file serving here)
              location /repairapp/ {
                  proxy_pass http://repairappcontainer:8000/;
                  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                  proxy_set_header Host $host;
                  proxy_redirect off;
              }
              
              ...
          

          注意rewrite ^/repairapp/([^static].*[^/])$ /repairapp/$1/ permanent;这一行 它重写并在任何(我的应用程序)错过它的 uris 中添加一个尾部正斜杠;以/repairapp/static 开头的除外。这些 uris 映射到 nginx 将服务的资源。

          要调试,请在 nginx 容器中打开一个 shell 并运行 curl -IL http://[server-name]/repairapp/[string-of-uris-without-trailing-slash] 以查看究竟发生了什么。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多