Search code examples
dockernginxdocker-composeproxyreverse-proxy

Reverse proxy to another machine


Explanation of what I am trying to do:

I have 2 servers on the ip 192.168.1.10 (docker reverse proxy) and 192.168.1.20 (other services). I want 10 to redirect requests to 20 (many of these requests are with SSL).

Example:

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;
        }
    }
}

(In several places I have read that I must put in "/etc/hosts" the resolution of the dns, which would be something like "192.168.1.20 example_external.host.com")

The truth is that this is my first time using this technology and I have not been able to find much information and what I have found has been quite difficult to understand.


Solution

  • This is the configuration that has worked for me:

    Comments:

    Some details are missing such as the nginx.conf file automatically taking the example_external.host.com in the server_name field, but it will be later.

    On the other hand, you have to be careful with DEFAULT_HOST= if it is declared, you may get errors. I recommend commenting on it until it works and then uncommenting it

    I recommend using this command: docker-compose up -d --remove-orphans --build

    Files:

    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;
        }
      }
    }
    

    A special thanks to @richardsefton for his dedication