Could someone who knows explain how Docker Desktop computes the URL of the page that is launched when user clicks Open in Browser command for a running ASP.NET 5.0 Core microservice container? Specifically:
How does it figure whether to use HTTP or HTTPS (or does it always use one or the other)?
What does it do to construct the rest of the URL and/or Where does it look to get the info it needs to construct the URL?
Assume the following about the microservice (if needed to answer the question):
It is implemented in ASP.NET 5.0 Core in Visual Studio 2019.
It supports both HTTP and HTTPS
The Visual Studio Project of the microservice is enabled with Docker support - but NOT Container Orchestration. Therefore, the project has a Dockerfile, launchSettings.json and an appsettings.json - but it does NOT have a docker compose project and file.
launchUrl (in the Docker profile in launchSettings.json) is set to “{Scheme}://{ServiceHost}:{ServicePort}” - where Scheme can be either http or https, ServiceHost is “localhost” and ServicePort is either <httpPort> or <sslPort> (depending on Scheme).
sslPort and httpPort are also specified in the Docker profile in launchSettings.json - and are different from one another.
Both the above URLs launch the Swagger page of the microservice.
The microservice and its Docker container are launched from Visual Studio itself (not from a terminal prompt).
The Docker container os is Debian GNU/Linux version 10 (buster)…
Please let me know if you need any other information in order to answer the questions.
I am hoping the above information will help me find root cause of an issue I am seeing when I use Open in Browser on containers of microservices that I am working on.
I’d guess it’s just using the lowest internal port one has published. At least, that is what it seems to be doing for a container that does not even serve any web pages. Like the following makes it show only port 81 in the GUI, and clicking the button tries to open http://localhost:81 (which won’t work as busybox is not serving anything on port 123):
Same goes for a different order of the command line arguments, which makes me assume it’s using the lowest port number in the container, not the first port that is published:
And both the following make it use port 443, but always http://, not https://:
docker run --rm -it -p 443:125 busybox
docker run --rm -it -p 443:443 busybox
So, I also assume that your browser is boldly trying HTTPS for you. It may even do that for non-443 ports, but you may not notice if the browser cannot connect, and then tries HTTP.
In short: just eye candy in Desktop.
Are you sure you don’t get redirected to that URL when going to just the domain name and port number?
However, in my case it seems to be doing the exact opposite - which is what is causing the issue that I am investigating.
In my case, there are only 2 internal ports exposed in the docker run command issued by Visual Studio - 443 and 80.
These ports are mapped to 2 different ports on the host via the launchSettings.json of the microservice and you can see the mapping in the docker run command issued by VS (see below for the full run command).
If DD was taking the lowest internal port number, then “Open in Browser” should be using the port mapped to port 80 when constructing the URL - is that correct?. If it did that (and continued to use http as the protocol), then I wouldn’t have the issue that I do.
But, instead, it seems to be using the port mapped to port 443 (the “higher” port number) and trying to open that with http (instead of https) - this leads to page load failure with error code ERR_EMPTY_RESPONSE.
I have tried swapping the mapped ports - but behavior does not change. It seems to always use whatever port is mapped to port 443.
So I was hoping you or someone else on this forum has access to the Docker Desktop source code and can look it up and explain how exactly it constructs the URL - which would help me figure out the root cause of the issue.
Here is the docker run command issued by Visual Studio for your reference:
Are you sure you don’t get redirected to that URL when going to just the domain name and port number?
Yes - but only if I have a call to app.UseHttpsRedirection() in the Configure method of the Startup class of the microservice. If I do not include that line, then the Swagger page comes up under both HTTP and HTTPS without redirection.
For busybox we know there’s nothing in the container that provides any hints to Desktop, if (which I doubt) Desktop is somehow being smart about a .NET container. (Busybox is not serving any web application.) So, running at least docker run --rm -it -p 443:125 -p 80:124 -p 81:126 busybox may tell you more.
Like shown in my tests: not for me, with busybox.
I’m running Desktop 4.1.1 (69879) here, with the same Engine.
But I’m afraid one can say it’s not a reliable way to help people open your application in their browser. (I’ve seen Desktop offer opening a web browser for database containers, also not serving HTTP at all.)
Clicking Open in Browser gives me the same ERR_EMPTY_RESPONSE error page - URL is http://localhost (without port number). Editing the URL and hitting Enter does not resolve the issue. I am assuming this is expected behavior since busybox does not serve a web application.
So it looks like in my case, something is making it think that 443 is the “lowest” numbered internal port - and not 80. Either that or (as you said) it is using a different algorithm to select the port number for Open in Browser in case of a .NET Core container.
Let me know if you have any additional thoughts.
Regardless, I do appreciate your time and help on this.