0

I am trying to make a simple reverse proxy with nginx. The goal is to have a request routing api (nginx) which can be called from my host and then access and call some http listeners in some window services.

My docker-compose.yml:

version: "3"
services:
  nginx:
    image: nginx
    ports:
      - 5003:5003
    volumes:
      - ./nginx-proxy.conf:/etc/nginx/nginx-proxy.conf
nginx-proxy.conf:

server {
    listen 5003;

    location / {
        proxy_pass http://localhost:5004/foo/;
    }
}
  1. Running docker compose in my host network by setting network_mode: "host" in my docker compose file:

by calling http://localhost:5003 I get

Error: connect ECONNREFUSED 127.0.0.1:5003

  1. Adding an extra host to docker compose and use it in my nginx config file

My docker compose :

version: "3"
services:
  nginx:
    image: nginx
    ports:
      - 5003:5003
    volumes:
      - ./nginx-proxy.conf:/etc/nginx/nginx-proxy.conf
    extra_hosts:
      - "host.docker.internal:host-gateway"

My nginx config file:

server {
    listen 5003;

    location / {
        proxy_pass http://host-gateway:5004/foo/;
    }
}

by calling http://localhost:5003 I get

Error: socket hang up

  1. Also tried docker.for.win.localhost or host.docker.internal in my nginx config (without adding the extra host in my docker compose) and I get

Error: socket hang up

Edit:

Docker compose :

version: "3"
services:
  nginx:
    image: nginx
    ports:
      - 5003:5003
    volumes:
      - ./nginx-proxy.conf:/etc/nginx/nginx-proxy.conf
    extra_hosts:
      - "host.docker.internal:host-gateway"

My nginx config:

server {
    listen 5003;

    location / {
        proxy_pass http://host.docker.internal:5004/foo/;
    }
}

By calling http://localhost:5003, I get

Error: socket hang up

Edit 2:

This is my http listener in my servie:

_httpListener = new HttpListener();
_httpListener.Prefixes.Add("http://+:5004/foo/");
_httpListener.Start();

        
        while (!stoppingToken.IsCancellationRequested)
        {
            HttpListenerContext ctx = null;
            try
            {
                ctx = await _httpListener.GetContextAsync();
            }
            catch (HttpListenerException ex)
            {
                if (ex.ErrorCode == 995) return;
            }

            if (ctx == null) continue;

            var response = ctx.Response;
            response.ContentType = "text/plain";
            response.Headers.Add(HttpResponseHeader.CacheControl, "no-store, no-cache");
            response.StatusCode = (int)HttpStatusCode.OK;

            string message = "FooBar";

            var messageBytes = Encoding.UTF8.GetBytes(message);

            response.ContentLength64 = messageBytes.Length;
            await response.OutputStream.WriteAsync(messageBytes, stoppingToken);
            response.OutputStream.Close();
            response.Close();

Which can be reached by calling http://localhost:5004/foo/

Edit 3 :

By running the answer below I get this in browser:

This page isn’t working. localhost didn’t send any data. ERR_EMPTY_RESPONSE

stof2023
  • 1
  • 2
  • Does this answer your question? [From inside of a Docker container, how do I connect to the localhost of the machine?](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach) – Luuk May 14 '23 at 17:29

1 Answers1

0

You're almost there. You need to add the extra_host in your docker-compose file, like this

version: "3"
services:
  nginx:
    image: nginx
    ports:
      - 5003:5003
    volumes:
      - ./nginx-proxy.conf:/etc/nginx/nginx-proxy.conf
    extra_hosts:
      - "host.docker.internal:host-gateway"

That gives you the address host.docker.internal that you can use from inside the container to reach the host.

Then forward the requests to host.docker.internal:5004, like this

server {
    listen 5003;

    location / {
        proxy_pass http://host.docker.internal:5004/foo/;
    }
}

Your service that runs on the host needs to be coded in a way that it accepts connections from outside the machine. Traffic from a container looks like it originates from a different machine.

To get it to do that, you need to change your listener from

_httpListener.Prefixes.Add("http://localhost:5004/foo/");

to

_httpListener.Prefixes.Add("http://+:5004/foo/");
Hans Kilian
  • 18,948
  • 1
  • 26
  • 35