反向代理到另一台机器

Reverse proxy to another machine

我正在尝试做的事情的解释:

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

示例:

用户请求 回复 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”)

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

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.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的奉献