.Net Core WebApi refuses connection in Docker container - docker

I am trying out Docker with a small WebApi which I have written in dotnet core.
The Api seems to work fine because when I run it with dotnet run it starts normally and is reachable on port 5000. But when I run it in a Docker container it starts, but I cannot reach it on the exposed/mapped port. I'm running Docker on Windows 10 withing VirtualBox.
My Dockerfile looks like this:
FROM microsoft/aspnetcore-build:latest
COPY . /app
WORKDIR /app
RUN dotnet restore
EXPOSE 5000
ENV ASPNETCORE_URLS http://*:5000
ENTRYPOINT ["dotnet", "run"]
I am building the dontainer like this:
docker build -t api-test:v0 .
And run it with this command:
docker run -p 5000:5000 api-test:v0
The output of the run command is:
Hosting environment: Production
Content root path: /app
Now listening on: http://localhost:5000
I have also tried different approaches of binding the URL:
as http://+:5000, http://0.0.0.0:5000, http://localhost:5000, ...
via CLI parameters --urls / --server.urls
but without success. Does anyone see what I'm doing wrong or missing?

Now listening on: http://localhost:5000
Binding to localhost will not work for your scenario. You need to get the app to bind to 0.0.0.0 for the docker port forwarding to work. Once you do that, you should be able to reach the app on the VM IP, port 5000

Make sure your service is listening on all ports using http://*:500 or similar (if it prints localhost when running, it won't work).
If you set up your docker environment with VirtualBox and used e.g. docker-machine, you n need to use the IP address of the virtual machine that runs the docker containers. you can get the IP via docker-machine ip default.

I found a way round this. All you need to do is edit launchSettings.json change to "applicationUrl": "http://*:5000/" of your app setting. Build the image. Then run the image docker run -d -p 81:5000 aspnetcoreapp after it runs get ip address of the container docker exec container_id ipconfig. Then in browser http://container_ip:5000/api/values. For some reason it does not work http://localhost:81 still need to figure out why that is.

I had the same issue recently with Docker version 20.x. The comment above provided good lights. If anyone faces the same issue here is how I've solved: Edit launchSettings.json to
"applicationUrl": "http://localhost:5001;http://host.docker.internal:5001",
This will let you test your web API locally and also to be consumed from the container.

Related

Trouble connecting to a TCP server through Docker on WSL 2

I'm using WSL2 on Windows 10 using an Ubuntu image, and Docker for Desktop Windows (2.2.2.0) with the WSL integration.
I have a super basic rust tcp server. I think the only relevant bit is:
let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
println!("Listening on 8080");
for stream in listener.incoming() {
println!("Received connection");
let stream = stream.unwrap();
handle_connection(stream);
}
I can cargo install and run the binary without issue; the line above prints, I can curl localhost:8080 from WSL and see the response as I'd expect from the rest of the code.
I wanted to turn it into a docker image. Here's the Dockerfile.
FROM rust:1.40 as builder
COPY . .
RUN cargo install --path . --root .
FROM debian:buster-slim
COPY --from=builder ./bin/coolserver ./coolserver
EXPOSE 8080
ENTRYPOINT ["./coolserver"]
I then do:
docker build -t coolserver .
docker run -it --rm -p 8080:8080 coolserver
I see Listening on 8080 as expected (i.e. no panic), but attempting to curl localhost:8080 yields curl: (52) Empty reply from server. This, I don't know what to make of. Logging suggests my program gets to the point where it reaches listener.incoming(), but does not enter into the block.
To see if it was something to do with my setup (Docker for Desktop, WSL, etc.) or my Dockerfile, I followed the README for the docker-http-https-echo image, successfully. I can curl it on the specified ports.
I don't know how to debug further. Thanks in advance.
EXPOSE keyword is to open up ports for inter container communication for using these ports from host you have to use -p 8080:8080 while running docker via docker run
#CarlosRafaelRamirez resolved it for me. It was as simple as binding to 0.0.0.0 rather than the loopback address 127.0.0.1. More info here: https://pythonspeed.com/articles/docker-connection-refused/

Docker Port Not Exposing Golang

I am building a golang WebService in docker. The build seems fine but I am unable to expose the port for external (outside of container) access. When I curl from the command line (inside the container) the app appears to work fine.
I saw quite a few posts of similar problems but unfortunately many were not resolved or didn't seem applicable.
FROM golang:alpine
RUN mkdir /go/src/webservice_refArch
ADD . /go/src/webservice_refArch
WORKDIR /go/src/webservice_refArch
RUN apk add curl
RUN cd /go/src/webservice_refArch/ && go get ./...
RUN cd /go/src/webservice_refArch/cmd/reference-w-s-server && go build -o ../../server
EXPOSE 7878
ENTRYPOINT ["./server", "--port=7878"]
I have tried both:
:7878
localhost:7878
I was facing the same issue. Then what I did is change the ListernHost from localhost to 0.0.0.0 and it worked.
To debug this tried curl inside the container it was working fine but outside the container the response of the curl was blank. The port mapped but the content was not served outside the container. Once you change the "localhost" to 0.0.0.0 it will work.
See https://docs.docker.com/engine/reference/run/#expose-incoming-ports, just expose port in dockerfile is not enough.
You can add -p 7878:7878 when start container, or use -P to let docker set a automatical host port mapping for you.
If you do not want to do above, you can also add --net=host when start the container, then container will use host's network, if also works for you.
if you are trying to access the port inside your docker container from your local machine, you need map it to the desired port on your local machine
docker run -p 7878:7878 IMAGE
Then you should be able to access it on your host

Can't connect to ASP.NET core through docker

Hi people have been looking at this for far too long and need some help.
I have made a ASP.NET core website nothing fancy just the template that goes with VS 2017 (v 1.1). I publish the site using dotnet core cli and build an image using this dockerfile:
FROM microsoft/dotnet:1.1-runtime
COPY /Publish /dotnetapp
WORKDIR /dotnetapp
EXPOSE 8444
ENTRYPOINT ["dotnet", "Inqu.dll"]
When i run the image created with:
docker run -it <image_name:tag> -p 8444:8444
The image starts up waiting for request:
Hosting environment: Production
Content root path: /dotnetapp
Now listening on: http://*:8444
Application started. Press Ctrl+C to shut down.
but i can't reach the site and getting an ERR_CONNECTION_REFUSED when trying to access the site thought http://local-ip:8444/
I have modified the WebHostBuild to:
var host = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://*:8444")
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
So it should listen to port 8444, I have also tried to set:
ENV ASPNETCORE_URLS http://*:8444
in the Dockerfile but it doesnt help.
I have some other images in docker up and running (gogs and mysql) and i can access them with my local ip:port with no problems, but i can't connect to the kestrel server.
Can somebody please help me out?
Was a stupid mistake arguments were in wrong order
docker run -it -p 8444:8444 <image_name:tag>
and it worked :\

Add xserver into Docker container (the host is headless)

I'm building a Docker container which have maven and some dependencies. Then it execute a script inside the container. It seems, one of that dependencies needs an Xserver to work. Nothing is shown on screen but it seems necessary and can't be avoided.
I got it working putting an ENV DISPLAY=x.x.x.x:0 on Dockerfile and it connects to the external Xserver and it works. But the point is to make a Docker self-sufficient container.
So I need to add a Xserver to my container adding in Dockerfile the necessary. And I want that Xserver only accessible by the Docker container itself and not externally.
The FROM of my Dockerfile is FROM ubuntu:15.04 and that is unchangeable because my Dockerfile have a lot of things depending of that specific version.
I've read some post about how to connect from docker container to Xserver of the Docker host machine, like this. But as I put in question's title, the Docker host is headless and doesn't have Xserver.
Which would be the minimum apt-get packages to install into the container to have a Xserver?
I guess in my Dockerfile will be needed the display environment var like ENV DISPLAY=:0. Is this correct?
Is anything else needed to be added in docker run command?
Thank you.
You can install and run a x11vnc inside your docker container. I'll show you how to make it running on a headless host and connect it remotely to run X applications(e.g. xterm).
Dockerfile:
FROM joprovost/docker-x11vnc
RUN mkdir ~/.vnc && touch ~/.vnc/passwd
RUN x11vnc -storepasswd "vncdocker" ~/.vnc/passwd
EXPOSE 5900
CMD ["/usr/bin/x11vnc", "-forever", "-usepw", "-create"]
And build a docker image named vnc:
docker build -t vnc .
Run a container and remember map port 5900 to host for remote connect(I'm using --net=host here):
docker run -d --name=vnc --net=host vnc
Now you have a running container with x11vnc inside, download a vnc client like realvnc and try to connect to <server_ip>:5900 from local, the password is vncdocker which is set in Dockerfile, you'll come to the remote X screen with an xterm open. If you execute env and will find the environment variable DISPLAY=:20
Let's go to the docker container and try to open another xterm:
docker exec -it vnc bash
Then execute the following command inside container:
DISPLAY=:20 xterm
A new xterm window will popup in your vnc client window. I guess that's the way you are going to run your application.
Note:
The base vnc image is based on ubuntu 14, but I guess the package is similar in ubuntu 16
Don't expose 5900 if you don't want remote connection
Hope this can help :-)

Deploy ASP.NET core to Azure Container Service (Swarm mode)

I've set up an Azure Container Service cluster, as shown here https://learn.microsoft.com/en-us/azure/container-service/container-service-deployment with SWARM. Then I've connect to it as shown here https://learn.microsoft.com/en-us/azure/container-service/container-service-connect.
I've installed docker for windows (I've shared drives) and the visual studio docker tools.
I've created the default ASP.NET Core app that has this dockerfile
FROM microsoft/aspnetcore:1.0.1
ENTRYPOINT ["dotnet", "MyTest.dll"]
ARG source=.
WORKDIR /app
EXPOSE 80
COPY $source .
I've changed it (because it doesn't do anything) to something that looks like :
FROM microsoft/aspnetcore:1.0.1
WORKDIR /app
EXPOSE 80
COPY out ./
ENTRYPOINT ["dotnet", "MyTest.dll"]
Then, I've opened a command prompt and moved to my root folder and i've done :
set DOCKER_HOST = tcp://localhost:2375
docker version
(docker version is OK)
then :
dotnet publish -c Release -o out
docker build -t testaspnetcore .
then :
docker run -d -p 8080:80 testaspnetcore
then :
docker ps
and I see the container in the list, but when I connect to my cluster ACS with SSH and I do
docker -H 172.16.0.5:2375 ps -a
I can't see my container in the cluster.
note : when I do docker ps on local, i can see in putty event log : Forwarded port closed due to local error: Network error: Software caused connection abort. Tried to turn of firewall, and many others things, but no results
How can I deploy to the swarm cluster my own image ?
There is a tutorial at https://learn.microsoft.com/en-us/azure/container-service/container-service-docker-swarm
With respect to your Putty problem it might me that you have Docker running on your client machine thus you have a port conflict. You can change the client port to something different to avoid this clash.

Resources