I have a Asp.Net core MVC application running inside a Docker Container, but I can't reach it from localhost, Any thoughts?
Dockerfile:
FROM microsoft/dotnet:runtime
ARG source=publish/
WORKDIR /usr/src/project
COPY $source .
EXPOSE 5000
ENTRYPOINT ["dotnet","project.dll"]
And the run command:
docker run -t the/image . -p 5000:5000
And I get the message
Now listening on: http://*:5000
But I still can't access it through localhost:5000 or 192.168.99.100:5000
Everything after the image name will be passed as an argument to the container, so you need to put the -p earlier. Try:
docker run -p 5000:5000 the/image
Related
Fact 1. I've got 2 windows containers for:
MSSQL Server Developer Edition (microsoft/mssql-server-windows-developer)
Asp.Net Core API 5.0 (5.0.102) (solomiosisante/consequence:api)
Fact 2. No problem accessing the SQLServer container data from Management Studio (SSMS).
Fact 3. No problem when I run the API project from Visual Studio accessing the SQLServer container.
Fact 4. The problem is when I run both containers, the error says:
fail: Microsoft.EntityFrameworkCore.Database.Connection[20004]
An error occurred using the connection to database 'Consequence' on
server 'localhost,14344'.
fail: Microsoft.EntityFrameworkCore.Query[10100]
An exception occurred while iterating over the results of a query for
context type 'Consequence.EF.Models.ConsequenceContext'.
Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related
or instance-specific error occurred while establishing a connection to
SQL Server. The server was not found or was not accessible. Verify
that the instance name is correct and that SQL Server is configured to
allow remote connections. (provider: TCP Provider, error: 0 - No
connection could be made because the target machine actively refused
it.)
SQL Server Container:
The SQL Container came from the image I built using microsoft/mssql-server-windows-developer. I attached my db and created an image and uploaded it to my docker hub existing repo solomiosisante/consequence:sqlexpress. I used the sqlexpress image before, thus the tagname :sqlexpress. I've yet to change it to :developer.
API Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Consequence.API/Consequence.API.csproj", "Consequence.API/"]
RUN dotnet restore "Consequence.API/Consequence.API.csproj"
COPY . .
WORKDIR "/src/Consequence.API"
RUN dotnet build "Consequence.API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Consequence.API.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS="https://+;http://+"
ENV ASPNETCORE_HTTPS_PORT=44388
ENV ASPNETCORE_Kestrel__Certificates__Default__Password="P#ssw0rd123"
ENV ASPNETCORE_Kestrel__Certificates__Default__Path=/src/certs/consequence.pfx
ENTRYPOINT ["dotnet", "Consequence.API.dll"]
I also tried:
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
#COPY ["Consequence.API/Consequence.API.csproj", "Consequence.API/"]
#COPY ["Consequence.EF/Consequence.EF.csproj", "Consequence.EF/"]
#COPY ["Consequence.Repositories/Consequence.Repositories.csproj", "Consequence.Repositories/"]
COPY . .
RUN dotnet restore "Consequence.API/Consequence.API.csproj"
Build and Run Scripts:
SQL Container:
docker run --name=sqlserver-container -d -p 14344:1433 -e sa_password=P#ssw0rd123 -e ACCEPT_EULA=Y solomiosisante/consequence:sqlexpress
ASP.Net Core 5.0.102 Container:
dotnet dev-certs https -ep certs\consequence.pfx -p P#ssw0rd123
dotnet dev-certs https --trust
docker build --pull -t consequenceapi:latest --file Consequence.API/Dockerfile .
docker run -d -p 8088:80 -p 44388:443 -v C:\SolRepo\Consequence\certs\:C:\src\certs --name consequenceapi consequenceapi:latest
Dockerhub repo for API: solomiosisante/consequence:api
I also tried:
docker run -d -p 8088:80 -p 44388:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="P#ssw0rd123" -e ASPNETCORE_Kestrel__Certificates__Default__Path=\https\aspnetapp.pfx -v $env:USERPROFILE\.aspnet\https:C:\https\ --name consequenceapi solomiosisante/consequence:api
I've read about docker network and tried all sorts. Still no luck. I'm hoping that this is not because I'm using Windows containers and that is one of the limitations of using it.
Given these facts, any ideas, comments, thanks in advance.
TL;DR: Why does an aspnet core app run on port 80 from within a Docker image, but 5000 outside a docker image.
Elaborate
I went through the aspnet core / docker tutorial found here:
https://learn.microsoft.com/en-us/dotnet/core/docker/building-net-docker-images
Half way through the page, I start the application with the following as prescribed:
dotnet run
Among other things, this prints this:
Now Listening on: http://localhost:5000
Great. That is what I expected. The next thing in the tutorial is to start the exact same application from within a Docker image.
docker build -t aspnetapp .
docker run -it --rm -p 5000:80 --name aspnetcore_sample aspnetapp
This results in
Now listening on: http://[::]:80
Wait. Wat? Why is the aspnet core app running on port 80? It was running on port 5000 when I ran it directly from the machine. There were no configuration file changes.
I suspect that it has something to do with the base docker images, but am not yet skilled enough in docker to track this down.
The microsoft/aspnetcore-build container builds on top of the
microsoft/aspnetcore container. The dockerhub page for that says:
A note on ports
This image sets the ASPNETCORE_URLS environment variable to http://+:80 which means that if you have not explicity set a URL in your application, via app.UseUrl in your Program.cs for example, then your application will be listening on port 80 inside the container.
So this is the container actively setting the port to 80. You can override it, if you want, by doing this in your Dockerfile:
ENV ASPNETCORE_URLS=http://+:5000
Also, it is worth noting that because of the docker command you are using, you will still be able to access the application at http://localhost:5000 whether you are running the application directly or in a container.
without dockerfile you can set any port out of the docker container. (.NET Core 3.1, .NET 5, .NET 6, .NET 7+) with docker args
docker run -it --rm -p 5000:80 -p 5001:443 -e ASPNETCORE_HTTPS_PORT=https://+:5001
-e ASPNETCORE_URLS=http://+:5000 --name aspnetcore_sample aspnetapp
more details:
https://github.com/dotnet/dotnet-docker/blob/17c1eec582e84ba9cbea5641cd9cc13fe1a41c39/samples/run-aspnetcore-https-development.md?plain=1#L85
https://github.com/dotnet/dotnet-docker/blob/5926a01d44bd47b6202ba71e30f9faa08fad1aec/samples/run-in-sdk-container.md?plain=1#L109
If you are using .NET Core 2.2 or higher, then you should to use another image: mcr.microsoft.com/dotnet/core/aspnet:2.2. In that case specifying ENV ASPNETCORE_URLS=http://+:5000 does not help. You still can force app to listen to port 5000 by using UseUrls("http://*:5000") in Programs.cs file.
Some links in other answers are for older versions, or no longer exist. The below applies to v6.
All the mcr.microsoft.com/dotnet/aspnet images are here. Suppose you are using the alpine version.
The aspnet image is based on the runtime image, as shown here.
The runtime image is based on the runtime-deps image, as shown here.
The runtime-deps image is based on the amd64/alpine image, as shown here (an older version, but with the same structure). And it sets ENV ASPNETCORE_URLS=http://+:80, as shown here, which means the container is listening on port 80.
Windows Networking Stack Limitation plays hard on Windows Docker Container.Reference Video
docker run -it --rm -p ${host_computer_port}:${container_port} --name ${container_name} ${image_name}
Example of the command:
docker run -it --rm -p 5000:8090 --name dockerwebapp9172020c dockerwebapp9172020
What is above command mean?
Your machine Port (5000) is mapped to container Port (8090). It does not mean that application running in container listening on PORT: 8090. See docker file below on how to map container port to application port.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1903 AS base
WORKDIR /app
EXPOSE 8090
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-nanoserver-1903 AS build
WORKDIR /src
COPY ["DockerWebApp/DockerWebApp.csproj", "DockerWebApp/"]
RUN dotnet restore "DockerWebApp/DockerWebApp.csproj"
COPY . .
WORKDIR "/src/DockerWebApp"
RUN dotnet build "DockerWebApp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DockerWebApp.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://*:8090
ENTRYPOINT ["dotnet", "DockerWebApp.dll"]
Testing
Windows Networking Stack Limitation will not allow to run following command directly.
http://localhost:5000
Let's get on with first workaround.
Workaround-1 Directly hit Container. (Below command in PowerShell or Command Prompt)
ps c:/>docker inspect f31e8add55af
Find IP Address of a container from "NETWORKS" node at very end and run command in browser.
http://{container IP}:8090
Workaroud-2 From Windows Host
Let's find Your Machine IP address first.
c:\>ipconfig
Once you find your Machine IP, run following command.
http://{Your Machine IP}:5000
since 5000 is mapped to container port(8090) and asp.net core application is also listening to 8090 port within container.
Reference:Windows Containers and Docker: 101
I want nginx in a Docker container to host a simple static hello world html website. I want to simply start it with "docker run imagename". In order to do that I added the run parameters to the Dockerfile. The reason I want to do that is that I would like to host the application on Cloud Foundry in a next step. Unfortunately I get the following error when doing it like this.
Dockerfile
FROM nginx:alpine
COPY . /usr/share/nginx/html
EXPOSE 5000
CMD ["nginx -d -p 5000:5000"]
Error
Error starting userland proxy: Bind for 0.0.0.0:5000: unexpected error Permission denied.
From ::
https://docs.docker.com/engine/reference/builder/#expose
EXPOSE does not make the ports of the container accessible to the host. To do that, you must use either the -p flag to publish a range of ports or the -P flag to publish all of the exposed ports. You can expose one port number and publish it externally under another number
CMD ["nginx -d -p 5000:5000"]
You add your dockerfile
FROM nginx:alpine
its already starts nginx.
after you build from your dockerfile
you should use this on
docker run -d -p 5000:5000 <your_image>
Edit:
If you want to use docker port 80 -> machine port 5000
docker run -d -p 5000:80 <your_image>
I'm currently trying to launch a Docker component with a ASP.NET Core application.
I use the following repo for my test : https://github.com/aspnet/cli-samples
I ran the following commande without any issue :
git clone https://github.com/aspnet/cli-samples aspnet-Home
cd aspnet-Home/HelloWeb
cat Dockerfile
FROM microsoft/aspnetcore
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "helloweb.dll"]
sudo docker build –t helloweb .
sudo docker run -d helloweb
The image is visible using the sudo docker images, but the container doesn't launch and is not visible with sudo docker ps:
And if I browse my website, obsviously I do not see data.
Is the repo not good for my test ? Is there any mistake I do on the docker container creation ?
Running the -it command give me the following output:
The error you highlighted is because helloweb.dll you set as the ENTRYPOINT doesn't exist. There could be two reasons for it
1 You didn't build the project yet
In this case you should run dotnet restore from the project home directory, then navigate to HelloWeb directory and run dotnet publish. When I run this command, I see the following:
publish: Published to /code/HelloWeb/bin/Debug/netcoreapp1.0/publish
Published 1/1 projects successfully
2 You built the project, but the ENTRYPOINT path is wrong
COPY . . directive will copy everything from the current directory into your app directory. That means HelloWeb.dll will actually be in bin/Debug/netcoreapp1.0/publish/ (or bin/Release/... for release builds).
Option 1: Modify your entrypoint with the full path
ENTRYPOINT ["dotnet", "bin/Debug/netcoreapp1.0/publish/HelloWeb.dll"]
Your application should happily start and serve requests.
Option 2: Modify your COPY directive
Once your project has been published, everything you'll need to run it will be in the publish directory. You could copy the contents of that into the /app directory and your entrypoint will be correct. That would look like this
FROM microsoft/aspnetcore
WORKDIR /app
COPY ./bin/Debug/netcoreapp1.0/publish/ .
EXPOSE 80
ENTRYPOINT ["dotnet", "HelloWeb.dll"]
You will also probably want to add the EXPOSE directive to tell Docker that your container will be listening on port 80.
When that succeeds, you should see (if you run in interactive mode)
docker run -it helloweb
Hosting environment: Production
Content root path: /app
Now listening on: http://+:80
Application started. Press Ctrl+C to shut down.
You could also use the microsoft/dotnet:latest image instead. That image comes with the SDK installed and a very convenient run command. The Dockerfile would look like this
FROM microsoft/dotnet:latest
COPY . /app
WORKDIR /app
RUN dotnet restore
ENV ASPNETCORE_URLS http://*:5000
EXPOSE 5000
ENTRYPOINT ["dotnet", "run"]
and you should be able to modify your source and build and run your container.
I was playing with ASP.net 5 beta 4 docker image.
I am running the container with the entrypoint dnx /app kestrel.
The Dockerfile is standard from tutorials:
FROM microsoft/aspnet:1.0.0-beta4
MAINTAINER "xxxx" <xxxx>
#this contains project.json etc
COPY ./app /app
WORKDIR /app
RUN ["dnu", "restore"]
EXPOSE 5004
ENTRYPOINT ["dnx", "/app", "kestrel"]
The container starts and exits immediately, the logs for the container shows:
"Started" which indicates that there were no errors starting kestrel.
The docker command I used was docker run -d -p "5004:5004" my_asp_net_5_docker_image:1.0.0
What intrigues me is that if I run the container with a pseudo-tty, by doing
docker run -t -i -p "5004:5004" --entrypoint="/bin/bash" my_asp_net_5_docker_image:1.0.0
and then when I am inside the docker container I run the entrypoint command manually dnx /app kestrel, kestrel starts, the output is "Started" and it remains alive, and I can access the HelloWorld website successfully.
I wonder why this difference of behaviour. Why doesn't dnx /app kestrel
keep the container alive when I run it in the entrypoint but it does when I run it from inside the container.
UPDATE:
I found something interesting here
This is a change in asp.net git hub that says "Don't require a TTY on Unix." there was a line after "Started" that did a Console.ReadLine(), it could be that this code still be in the asp.net docker image therefore it only works with tty...
UPDATE 2:
I can get it working by opening stdin (-i): docker run -d -i -p "5004:5004" my_asp_net_5_docker_image:1.0.0
Which suggests that the Console.ReadLine() could be the issue. This solves the problem for me now, but I don't think we should have to use -i to get the container running.