Connection refused on API request between containers with docker compose Connection refused on API request between containers with docker compose docker docker

Connection refused on API request between containers with docker compose


ServiceA's HTTP requests were being redirected (HTTP 307 status code) to https://serviceb:44359/api/bar being :44359 the host port for HTTPS. Host ports are not accessible between containers, container ports do. So if I access to serviceA's terminal and send an HTTP request with curl verbose -v following redirections -L to the URI http://serviceb/api/bar I got the Connection Refused error:

root@serviceA_id:/app# curl -v -L http://serviceb/api/bar*   Trying 10.168.0.3...* TCP_NODELAY set* Connected to serviceb (10.168.0.3) port 80 (#0)> GET /api/bar HTTP/1.1> Host: serviceb> User-Agent: curl/7.52.1> Accept: */*>< HTTP/1.1 307 Temporary Redirect< Date: Wed, 19 Jun 2019 08:48:33 GMT< Server: Kestrel< Content-Length: 0< Location: https://serviceb:44359/api/bar<* Curl_http_done: called premature == 0* Connection #0 to host serviceb left intact* Issue another request to this URL: 'https://serviceb:44359/api/bar'*   Trying 10.168.0.3...* TCP_NODELAY set* connect to 10.168.0.3 port 44359 failed: Connection refused* Failed to connect to serviceb port 44359: Connection refused* Closing connection 1curl: (7) Failed to connect to serviceb port 44359: Connection refused

Why I were being redirected to host port?

In Startup.cs my services were using app.UseHttpsRedirection();, that line was causing the problem.

The default configuration of HttpsPolicyBuilderExtensions.UseHttpsRedirection(IApplicationBuilder) method redirects to HTTPS host port by default. If you want to use a different port for redirection you need to add that option so Startup.cs will look like this:

public class Startup    {        public Startup(IConfiguration configuration)        {            Configuration = configuration;        }        public IConfiguration Configuration { get; }        public void ConfigureServices(IServiceCollection services)        {            ...            services.AddHttpsRedirection(options =>            {                options.HttpsPort = 443;            });            ...        }        public void Configure(IApplicationBuilder app, IHostingEnvironment env)        {            ...            app.UseHttpsRedirection();            ...        }    }


but it doesn't when I do ping to serviceB's API REST:

root@serviceA_id:/app# ping -p 80 serviceb/api/barPATTERN: 0x80ping: serviceb/api/bar: Temporary failure in name resolution

That may be the cause of Connection Refused error when doing API requests from ASP.NET

That's not how ping works. Ping uses ICMP, not TCP, and not HTTP which works on top of TCP. You ping a host, not a TCP port or HTTP API. So the above is expected to fail.

I can also stablish connection with API REST endpoint with CURL but Content-Length recieved is 0

root@serviceA_id:/app# curl -v http://serviceb/api/bar*   Trying 10.168.0.3...* TCP_NODELAY set* Connected to serviceb (10.168.0.3) port 80 (#0)

This indicates you have correctly configured docker containers to communicate, there's nothing more to debug in the configuration of your networks, and you know your serviceb is is listening.

The only things left to debug are:

  • Make sure servicea is connecting to serviceb on port 80, not 65112 or any other host port. Containers communicate between each other on container ports.
  • Make sure you are running the code posted, and not a previous version. This is easy to mistake when building and deploying images, especially if you aren't changing your image tag for each build.
  • Make sure you give serviceb time to start. I've often seen these errors when servicea starts before serviceb.

If you still have issues, you can start debugging with tools like tcpdump. E.g.

docker run -it --rm --net container:$container_id \  nicolaka/netshoot tcpdump -i any port 80

Replace the $container_id with the id of serviceb to see any TCP requests to port 80 on that container.


You have to specify the port also when connecting from the same docker network:

var result = client.GetAsync("http://serviceb:80/api/actioname").Result;