Change dotnet core port in docker container - docker

I'm very new to Dockers and I've been reading documentation and been doing some experiment's but there are few things I'm not getting.
The Case is I've two application one is dotnet core web application and the other one is dotnetcore web Api. I'm running dotnet core web application inside a container. Below is the docker file:
WORKDIR /source
COPY . ./DockerTest/
WORKDIR /source/DockerTest
RUN dotnet publish -c release -o /app
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
EXPOSE 50/TCP
EXPOSE 50/UDP
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "DockerTest.dll","--environment=development"]
and the command I execute to run this image is: docker run -d -p 90:50 myapp
Now here I'm trying to map 50 on which my dotnetcore application should be running to port 90 on my host machine. But unfortunately what ever port I give in EXPOSE my application always run on port 80 inside the container I want to know why is that so and how can I change that. Second thing is from inside the container I'm trying to access my web api which is running on host machine:
public async Task<string> GetData()
{
var data = "";
var request = new HttpRequestMessage(HttpMethod.Get,
"http://localhost:51468/weatherforecast");
using (var context = ClientFactory.CreateClient()){
var response = await context.GetAsync(request.RequestUri);
if (response.IsSuccessStatusCode)
{
data = await response.Content.ReadAsStringAsync();
}
else
{
data = "error happen";
}
}
return data;
}
This is how I'm trying to send request to my api which is outside the container but it gives this error:HttpRequestException: Cannot assign requested address.
Now I'm blocked and I need help and suggestions here.

First about you Docker:
The docker EXPOSE 50 is only known for docker, dotnet knows nothing about docker. So in your DockerTest.dll you must also specify the listening port.
dont use port 50, it is too low. Anything below 1024 is seen as well-known ports or system ports and should not be used. dotnet normally listening on port 5000 - when it is not 80/443.
Second about you access to the host:
When using localhost inside the docker container, it will not reach the host but only th container itself. So you have to use the Host LAN ip i.e. 192.168.. or something...

Related

Can't access Web API hosted inside Docker container from external device on same Network

I've created a default ASP.NET Core 5 Web API through Visual Studio 2019 and have it running inside a Docker container (no https to make this example simple). I am using Windows, but the image is running as a Linux Docker Container. When I run the application from Visual Studio, it is started with Docker Compose. When the application runs I'm able to access it from my browser on the Docker host machine, but I'm not able to access it from another device on the same network.
Below are the files I'm using. You can see that I am exposing port 61234 from docker-compose.yml. Assuming my Host IP address is 192.168.1.12, if I were to navigate to http://192.168.1.12:61234/weatherforecast from a web browser on the host machine, I get a REST response from the controller. If I access that same endpoint from a different laptop on the same Wi-Fi network, the endpoint is unreachable.
I have validated that the laptop can reach the REST endpoint if the application is not running within a Docker container. For this reason, I don't believe the Windows Firewall is getting in the way.
I've looked at everything I can think of. So my question is: Is there anything else I should look at? I assume I'm missing something simple, but just can't seem to find what that might be.
The only change I made to the C# code generated by Visual Studio is making a UseUrls() call when creating the web host builder: webBuilder.UseUrls("http://*:80").UseStartup<Startup>();
Here is my docker-compose.yml file. Note the exposed TCP port and the bridge network:
version: '3.4'
services:
webapplication1:
image: ${DOCKER_REGISTRY-}webapplication1
build:
context: .
dockerfile: WebApplication1/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "61234:80"
networks:
- practice-webapi-network
networks:
practice-webapi-network:
driver: bridge
And here is the auto-generated Dockerfile that Visual Studio created:
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
RUN dotnet restore "WebApplication1/WebApplication1.csproj"
COPY . .
WORKDIR "/src/WebApplication1"
RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebApplication1.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication1.dll"]
One thing I want to point out. I believe I would be able to work around this by changing the network driver to Host instead of Bridge, but I need to use a Bridge network for my application. This is just a proof of concept.
Edit 1: Added missing port to example endpoint

How to handle redirection between docker container services?

I'm trying to introduce docker for local development into an existing project.
I have two services A (previously being run on localhost:5000) & B (previously being run on localhost:5001). A is a login application whereas B is the main application. A takes the username/password from the user, validates credentials & if valid, redirects the user to appropriate service B's entry point i.e. localhost:5001/<user_role> from where application B takes over.
When running without docker, this redirection between services works fine. But when using docker and running the projects, this redirection breaks (except when I use host network driver). I can access service A, login successfully but when the redirection happens, the browser's address bar shows the redirected entry point of service B and the browser says "The site can't be reached" and the request fails.
Here are my docker files:
Service A
Run as: docker run -p 5000:5000 --name service_a_1 service_a
FROM node:10
WORKDIR /home/node/serviceA
COPY ./package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
EXPOSE 5000
Service B
Run as: docker run -p 5001:5001 --name service_b_1 service_b
FROM node:10
WORKDIR /home/node/serviceB
COPY ./package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
EXPOSE 5001
But when I use --network=host when running these containers, the redirection works fine but it fails with a bridge network driver. I have done my research going through the docker's documentation on networking and some tutorials on docker networking.
Questions:
Can the behavior that I want be achieved using bridge network?
Why is it not working for bridge network driver but works on host?
Found Cannot run webpack-dev-server inside docker after some additional research. This solved my issue.
Additional resources:
https://pythonspeed.com/articles/docker-connection-refused/
https://github.com/webpack/webpack-dev-server/issues/147

Problem acessing server on docker container

I am trying to build and run docker image from example on this site: https://kubernetes.io/docs/tutorials/hello-minikube/
//server.js
var http = require('http');
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);
//Dockerfile
FROM node:6.14.2
EXPOSE 8080
COPY server.js .
CMD node server.js
I use commands
docker build -t nsj .
docker run nsj
They run without error but I cannot access the server on localhost:8080.
What is wrong?
Seems like at least two things are wrong:
You need to map the port from your docker host
You need to bind your server to 0.0.0.0
So, probably these changes (untested):
In your code:
www.listen(8080, "0.0.0.0");
In your docker command:
docker run nsj -p 8080:8080
Note that having EXPOSE 8080 in your Dockerfile does not actually expose anything. It just "marks" this port in the docker engine's metadata and is intended for both documentation (so people reading the Dockerfile know what it does) and for tools that inspect the docker engine.
To quote from the reference:
The EXPOSE instruction does not actually publish the port. It
functions as a type of documentation between the person who builds the
image and the person who runs the container, about which ports are
intended to be published

Application not loading on host port - Docker

Docker service is unable to load on exposed port
I have created a simple DOCKERFILE and have built image "sample-image" from it inside a docker swarm, but whenever I am trying to run a container by creating docker service and exposing it on respective port but its unable to load on my browser. Kindly help
First I have initialised docker swarm and created an image "sample-image" from dockerfile, after that I created overlay network "sample-network" inside swarm and created a service to run container on it "docker service create --name sample-service -p 8010:8001 --network sample-network sample-image". Service gets created but it couldn't loads up on a browser as I have enabled my ufw for port 8010 also.
DOCKERFILE:
FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8001
CMD [ "npm", "start" ]
server.js:
'use strict';
const express = require('express');
const PORT = 8001;
const HOST = '0.0.0.0';
const app = express();
app.get('/', (req, res) => {
res.send('Hello world\n');
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
I expect my web browser to display "Hello world" on exposed port number.
Did you check the docker logs ? That should give you what is going wrong.
$ docker logs <containerid>
Could you try "curl -v http://127.0.0.1:8081" and paste the output here please? Also, did you manipulate ufw after the service or dockerd started?
I think your listening port inside docker is 8010, and outside docker is 8001, can you try changing -p 8001:8001? if it works try -p 8001:8010.

Could not access Web API inside docker container from localhost

I know that there are many discussion about this, but none of the proposed solutions worked for me, so I will have to know at least if I was doing something wrong or I was hitting a limitation.
Step 1.
I created the default .NET Core 2.0 WEB API project from Visual Studio, nothing special here, output type set to Console Application, running OK from Visual Stuido 2017 Community.
Step 2. I installed latest Docker Toolbox since I am running Windows 10 Home Edition, that installed also the Virtual Box.
Step 3. I added the following docker file next to the sln:
FROM microsoft/aspnetcore-build:2.0
WORKDIR /app
EXPOSE 80
COPY . .
RUN dotnet restore
RUN dotnet build
WORKDIR /app/DockerSample
ENTRYPOINT dotnet run
Next
Step 4. I successfully build the image with a command like 'docker build -t sample1 .'
Step 5. The container successfully started to run, it was started by the following command 'docker run -d -p 8080:80 sample1'
Step 6. Pull info about the container using command docker logs c6
The following info was shown:
Interesting here is the address where the service is listening, this seems to be the same with the address I was getting when running the service directly from Visual Studio.
Is this the service address from the virtual machine that is running inside Virtual box ? Why the port is not 8080 or 80 as I mentioned inside of the "run" command ?
The container looks ok, something like:
Step 7.
Now starts the fun trying to hit the service from Windows 10 machine, was impossible using calls like http://localhost:8080/values/api I also tried calls like http://192.168.99.100:8080/values/api where 192.168.99.100 is the address of the default docker machine.
I also tried with something like 'http://172.17.0.2:8080/values/api' where the IP address was got after a call like 'docker inspect a2', changing the port to 80 did not help :).
Trying to change the port number to 80 or 58954 , the one shown in red as listening, did not help. Also Windows Firewall or any other firewalls were stopped.
I tried to port forward from VirtualBox having something like
Trying to change the 80 and 8080 ports between them for host and guest also did not work.
Basically none of the suggested solutions I found did not gave me the chance to hit the service from my Windows machine.
Mainly I was following this tutorial https://www.stevejgordon.co.uk/docker-for-dotnet-developers-part-2 which explains quite well what should be done only that at some point is using the Docker Desktop for Windows so the Docker Toolbox was left behind.
Do you know what should I do so that I can hit the service from the docker container ?
In docker compose (visual studio add docker integration "docker-compose.yml") set this:
version: '3.4'
services:
webapi.someapi:
image: ${DOCKER_REGISTRY-}somenamesomeapi
build:
context: .
dockerfile: ../webapi/Dockerfile
environment:
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_HTTPS_PORT=443
ports:
- "80:80"
- "443:443"
in lunch settings specify your app to start on ports 80 and 443 https
Docker for visual studio code: https://marketplace.visualstudio.com/items?itemName=PeterJausovec.vscode-docker
Follow this steps to orchestrate your containers:
https://marketplace.visualstudio.com/items?itemName=PeterJausovec.vscode-docker
For your issue, it is caused by that you run the container under Development environment which did not use the port 80 for the application.
For FROM microsoft/aspnetcore-build:2.0, it seems you could not change the ASPNETCORE_ENVIRONMENT to Production.
For a solution, you could change your docker file like below which change the base image with microsoft/aspnetcore:2.0.
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY ["TestAPI/TestAPI.csproj", "TestAPI/"]
RUN dotnet restore "TestAPI/TestAPI.csproj"
COPY . .
WORKDIR "/src/TestAPI"
RUN dotnet build "TestAPI.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "TestAPI.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TestAPI.dll"]

Resources