【问题标题】:Reverse proxy to another machine反向代理到另一台机器
【发布时间】:2021-07-14 05:01:35
【问题描述】:

解释我要做什么:

我在 ip 192.168.1.10(docker 反向代理)和 192.168.1.20(其他服务)上有 2 台服务器。我希望 10 将请求重定向到 20(其中许多请求使用 SSL)。

示例:

user request answer back return
example_internal.host.com 192.168.1.10 https://example_internal.host.com
example_external.host.com 192.168.1.20 https://example_external.host.com



docker-compose.yaml:

version: '3'

services:
  nginx-proxy:
    image: budry/jwilder-nginx-proxy-arm:0.6.0
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - certs:/etc/nginx/certs:ro
      - confd:/etc/nginx/conf.d
      - vhostd:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
    labels:
      - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
    environment:
      - DEFAULT_HOST=example_external.host.com
    networks:
      - frontend

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion:stable
    restart: always
    volumes:
      - certs:/etc/nginx/certs:rw
      - confd:/etc/nginx/conf.d
      - vhostd:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - DEFAULT_EMAIL=example@email.com
    networks:
      - frontend
    depends_on:
      - nginx-proxy

  nginx_internal:
    image: nginx:stable-alpine
    hostname: example_internal.host.com
    restart: always
    expose:
      - "80"
    volumes:
      - /var/www/html:/usr/share/nginx/html:rw
    environment:
      - VIRTUAL_HOST=example_internal.host.com
      - LETSENCRYPT_HOST=example_internal.host.com
      - NGINX_HOST=example_internal.host.com
      - LETSENCRYPT_EMAIL=example@email.com
    depends_on:
      - nginx-proxy
      - letsencrypt
    networks:
      - frontend


  nginx_external:
    hostname: example.host.com
    restart: always
    build:
      context: ./scm-proxy
    expose:
      - "80"
    environment:
      - VIRTUAL_HOST=example_external.host.com
      - LETSENCRYPT_HOST=example_external.host.com
      - LETSENCRYPT_EMAIL=example@email.com
      - ENABLE_NGINX_REMOTEIP=1
    depends_on:
      - nginx-proxy
      - letsencrypt
    networks:
      - frontend

networks:
   frontend:
     driver: bridge

scm-proxy/Dockerfile:

FROM nginx:1.15-alpine
COPY nginx.conf /etc/nginx/nginx.conf

scm-proxy/nginx.conf:

worker_processes 1;

events {
  worker_connections 1024;
}

http {

    sendfile on;
    client_max_body_size 0;
    chunked_transfer_encoding on;

    server {
        listen 80;
        location / {
            proxy_pass        http://localhost:80;
            proxy_redirect    off;
            proxy_set_header  Host              $http_host;   # required for docker client's sake
            proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
            proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Host $http_host;
            proxy_set_header  X-Forwarded-Proto $scheme;
        }
    }
}

(在我读过的几个地方,我必须在“/etc/hosts”中输入 dns 的分辨率,类似于“192.168.1.20 example_external.host.com”)

事实上,这是我第一次使用这项技术,我还没有找到太多信息,而且我发现的东西很难理解。

【问题讨论】:

    标签: docker nginx docker-compose proxy reverse-proxy


    【解决方案1】:

    nginx 配置在端口 80 上对其自身进行反向代理。如果您想反向代理到其他容器之一,请将 lacalhost 更改为您为容器提供的任何服务名称。例如http://nginx_external:80

    如果这不起作用,请尝试将您的配置修改为:

    upstream app {
        server app:8080;
    }
    
    server {
        listen 80;
        listen [::]:80;
        server_name <your_host_here>;
        return 301 https://<your_host_here>$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 http2;
        server_name <your_host_here>;
    
        ssl_certificate /etc/nginx/ssl/certificate.crt;
        ssl_certificate_key /etc/nginx/ssl/key.key;
    
        location / {
            proxy_pass http://app;
            proxy_set_header        X-Real-IP           $remote_addr;
            proxy_set_header        X-Forwarded-For     
            $proxy_add_x_forwarded_for;
            proxy_set_header        X-Forwarded-Proto   $scheme;
            proxy_set_header        Host                $host;
            proxy_set_header        X-Forwarded-Host    $host;
            proxy_set_header        X-Forwarded-Port    $server_port;
            proxy_http_version      1.1;
            proxy_set_header        Upgrade             $http_upgrade;
            proxy_set_header        Connection          'upgrade';
            proxy_cache_bypass      $http_upgrade;
            proxy_buffer_size       128k;
            proxy_buffers           4                   256k;
            proxy_busy_buffers_size 256k;
        }
    }
    

    以上是在我自己的开发容器堆栈中尝试和测试的

    【讨论】:

    • 我必须试试这个。我有一个问题,我可以以某种方式将“nginx_external”作为变量传递吗?这个想法是能够为不同的主机重用相同的文件。我也有兴趣重定向其他服务,而不仅仅是 http。我能做到吗?
    • 恐怕我没有答案
    • 我已经尝试过了,但无法让它工作。它始终返回“502 Bad Gateway”
    • 尝试完全删除 proxy_redirect
    • 它也不起作用。我真的开始认为由于某些外部原因我不能这样做
    【解决方案2】:

    这是对我有用的配置:

    评论:

    缺少一些细节,例如nginx.conf 文件自动获取server_name 字段中的example_external.host.com,但会在以后。

    另一方面,你必须小心DEFAULT_HOST=,如果它被声明,你可能会得到错误。我建议对它进行评论,直到它起作用,然后取消评论它

    我推荐使用这个命令:docker-compose up -d --remove-orphans --build

    文件:

    docker-compose.yaml:

    version: '3'
    
    services:
      nginx-proxy:
        image: budry/jwilder-nginx-proxy-arm:0.6.0
        restart: always
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - /var/run/docker.sock:/tmp/docker.sock:ro
          - certs:/etc/nginx/certs:ro
          - confd:/etc/nginx/conf.d
          - vhostd:/etc/nginx/vhost.d
          - html:/usr/share/nginx/html
        labels:
          - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
    #    environment:
    #      - DEFAULT_HOST=example_internal.host.com
        networks:
          - frontend
    
      letsencrypt:
        image: jrcs/letsencrypt-nginx-proxy-companion:stable
        restart: always
        volumes:
          - certs:/etc/nginx/certs:rw
          - confd:/etc/nginx/conf.d
          - vhostd:/etc/nginx/vhost.d
          - html:/usr/share/nginx/html
          - /var/run/docker.sock:/var/run/docker.sock:ro
        environment:
          - DEFAULT_EMAIL=example@email.com
        networks:
          - frontend
    
      nginx_external1:
        container_name: tests
        restart: always
        build:
          context: ./scm-proxy
        expose:
          - "80"
        environment:
          - VIRTUAL_HOST=example_external.host.com
          - LETSENCRYPT_HOST=example_external.host.com
          - LETSENCRYPT_EMAIL=example@email.com
        extra_hosts:
          - "example_external.host.com:192.168.1.20"
        depends_on:
          - nginx-proxy
          - letsencrypt
        networks:
          - frontend
    
    networks:
       frontend:
         driver: bridge
    

    scm-proxy/Dockerfile:

    FROM nginx:stable-alpine
    COPY nginx.conf /etc/nginx/nginx.conf
    

    scm-proxy/nginx.conf:

    events {
      worker_connections 1024;
    }
    
    http {
      server {
        listen 80;
        listen [::]:80;
        server_name example_external.host.com;
    #
        location / {
    #        proxy_pass         http://example.com;
    #        proxy_pass         http://192.168.1.20;
            proxy_pass         http://example_external.host.com;
        }
      }
    }
    

    特别感谢@richardsefton 的奉献

    【讨论】:

      猜你喜欢
      • 2018-01-20
      • 1970-01-01
      • 2019-01-15
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      相关资源
      最近更新 更多