I have followed the following guide: Running ASP.NET 5 applications in Linux Containers with Docker and I cannot get this to work on my Windows PC or Linux server. My dockerfile looks like this:
FROM microsoft/aspnet
COPY . /app
WORKDIR /app
RUN ["dnu", "restore"]
EXPOSE 5000/tcp
ENTRYPOINT ["dnx", "-p", "project.json", "web"]
I then ran docker build -t myapp . and then docker run -d -p 80:5000 myapp it says it is running but I cannot open the website in the browser. I know on Windows you are supposed to find the ip address that the actual virtual machine is running against by using docker-machine ip default which ended up being 192.168.99.100 but when I navigated to http://192.168.99.100 I just get the generic "This webpage is not available" error message. I have also tried different variations of this docker run command, such as docker run -it -p 80:5000 myapp, docker run -p 80:5000 myapp, and I have also tried different ports, such as docker run -d -p 5000:5000 myapp but nothing seems to work.
I have tried this both on my windows machine and on my linux server, but they both do not work.
I am able to run dnx web without docker and everything works as expected.
Take a look at my answer here: ASP.NET 5.0 beta 8 in Docker doesn't start
Essentially, Docker is forwarding requests to your container on the 0.0.0.0 network interface, but Kestrel is only listening on localhost by default.
So yes, the requests are being passed off to your docker container, but they are not being accepted by the Kestrel webserver. For that reason, you need to override the server.urls property as others have posted:
ENTRYPOINT ["dnx", "web", "--server.urls", "http://0.0.0.0:5000"]
You should then see:
Now listening on: http://0.0.0.0:5000
when running your container. You can also do a quick docker ps command to verify that 0.0.0.0 is in fact the network interface that Docker is forwarding requests for.
I also wrote a bit about how to get ASP.NET 5 running on Docker on Windows - it's a bit more involved since not only does Docker have to forward requests to the container, but we have to get VirtualBox to pass off requests to the Docker virtual machine boot2docker (typically called default in Virtual Box) before Docker can hand them off to our container.
Post is here: http://dotnetliberty.com/index.php/2015/10/25/asp-net-5-running-in-docker-on-windows/
For a more complete understanding of your app environment, please post your project.json file and the beta version of ASP.net you are working with.
For now you can try cleaning up your Dockerfile by taking out "project.json" and "-p" arguments from the ENTRYPOINT instruction, remove tcp from the EXPOSE command, and finally, specify the "--server.urls" argument in the ENTRYPOINT instruction so that it uses 0.0.0.0 instead of the default localhost as follows:
FROM microsoft/aspnet
COPY . /project
WORKDIR /project
RUN ["dnu", "restore"]
EXPOSE 5000
ENTRYPOINT ["dnx", "web", "--server.urls"]
Alternatively, you can try dropping the EXPOSE command altogether and expose the docker port, 5000, in the ENTRYPOINT instruction as follows:
FROM microsoft/aspnet
COPY . /project
WORKDIR /project
RUN ["dnu", "restore"]
ENTRYPOINT ["dnx", "web", "--server.urls", "http://0.0.0.0:500"]
Either way you would then build your container and run it using something like the following:
$ docker run -it -p 80:5000 myapp
For anyone having this issue now in RC2, commands no longer exists. You have to update Program.cs by chaining in .UseUrls("http://0.0.0.0:5000"). You can also change from 5000 to whatever your desired port is here.
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseUrls("http://0.0.0.0:5000")
.Build();
host.Run();
}
}
You can find a working, step-by-step tutorial for Docker and ASP.NET Core RC1 here:
https://www.sesispla.net/blog/language/en/2015/12/recipe-asp-net-5-net-core-to-the-docker-container/
The tricky part probably you are missing is to modify your projects.json command as follows:
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel --server.urls http://0.0.0.0:5000"
},
By default, kestrel only accepts localhost connections... With this change you allow connection from any source.
Related
My Code:
public static void Start()
{
tcpListener = new TcpListener(IPAddress.Any, 26950);
tcpListener.Start();
tcpListener.BeginAcceptTcpClient(TCPConnectCallback, null);
while(true){Thread.Sleep(500);}
}
private static void TCPConnectCallback(IAsyncResult _result)
{
TcpClient _client = tcpListener.EndAcceptTcpClient(_result);
//Assign _client to local server
}
My Dockerfile to create and upload an Image:
FROM mcr.microsoft.com/dotnet/sdk
COPY . /app
WORKDIR /app
RUN dotnet publish -c Release -o out
ENTRYPOINT ["dotnet", "Test.dll"]
Command in Cloud Shell:
gcloud builds submit --tag gcr.io/t****/i****
After this, I deploy it on Kubernetes Engine>Workloads
Error: CrashLoopBackOff
Solution:
FROM mcr.microsoft.com/dotnet/sdk:3.1
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "run"]
The error CrashLoopBackOff indicates that a container is repeatedly crashing after restarting. A container might crash for many reasons
For example:
The application inside the container keeps crashing
Some type of parameters of the pod or container have been configured incorrectly
An error has been made when deploying Kubernetes
You can get more info about your error the CrashLoopBackOff error to know why your Pod's container is crashing
To see all Pods running in your cluster, run the following command:
kubectl get pods
And to get the Pod's logs, run the following command:
kubectl logs [POD_NAME]
You can also pass in the -p flag to get the logs for the previous instance of a Pod's container, if it exists.
Check "Exit Code" of the crashed container
You can find the exit code by performing the following tasks:
Run the following command:
kubectl describe pod [POD_NAME]
Review the value in the containers: CONTAINER_NAME: last state: exit code
Additionally, check if it has restarts.
For example you can use the command
watch -n1 kubectl get pods POD_NAME
To see if the pod got some of the following states:
creatingContainer --> running --> completed --> crashloopbackoff
You could see more information about it in the following link
Also you can check this article that can help you with this issue What is a CrashLoopBackOff? How to alert, debug / troubleshoot, and fix Kubernetes CrashLoopBackOff events.
Finally, if you provide more information like the logs and more details, the community could help you more.
Edit 1
Looks like your problem come from the FROM mcr.microsoft.com/dotnet/sdk
I have found the following documentation: Create a Dockerfile for an ASP.NET Core application
You could try to use something like:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
According to the official documentation : microsoft-dotnet-sdk these are the feature tags:
5.0 (Current)
docker pull mcr.microsoft.com/dotnet/sdk:5.0
3.1 (LTS)
docker pull mcr.microsoft.com/dotnet/sdk:3.1
working my way through tutorials on dockerized the API WeatherForecast web template from ASP.NET core:
https://code.visualstudio.com/docs/containers/quickstart-aspnet-core
https://code.visualstudio.com/docs/containers/docker-compose
I had to start from here, because I wasn't getting a new image to build using the tutorial here: https://docs.docker.com/compose/aspnet-mssql-compose/
"1" works, which is great. However, "2" will not work on the localhost:5000/WeatherForecast port as advertised, and I'm having some trouble debugging why after many reviews of the available docs.
I should make a note that in creating the templated app from the command line, I did choose the --no-https option.
I then used docker ps to bring up the PORTS . The web app is using 5000/tcp, 0.0.0.0:32779->80/tcp . When I substitute 5000 for 32779 , I get the API string returned instead!
I know I'm missing something within docker-compose and could use some extra eyes on it. Thank you!
EDIT: For reference, the files below were generated by my VSCode editor.
1. I ran dotnet new webapi --no-https
2. I then brought up the VSCode "command pallete" and ran Docker: Add Dockerfiles to Workspace and selected 'yes' for the inclusion of docker-compose.yml file and Linux. I also choose to use port 5000. I use Fedora 30.
4. I run dotnet build from the project root in the terminal.
5. If I run from docker commands and make the ports explicit it will work as advertised, but if I run docker-compose -f <yml-file> up -d- --build, it will not.
I just re-read this and find it annoying that I'm stuck within VSCode to fix the issue (according to the docs)
By default Docker will assign a randomly chosen host port to a port exposed by a container (the container port). In this case the exposed (container) port is 5000, but it will be exposed on the host via a random port, such as 32737.
You can use specific port on the host by changing the Docker run options used by docker-run: debug task (defined in .vscode/tasks.json file). For example, if you want to use the same port (5000) to expose the service, the docker-run: debug task definition would look like this:
a. Dockerfile
# Please refer https://aka.ms/HTTPSinContainer on how to setup an
https developer certificate for your ASP .NET Core service.
version: '3.4'
services:
aspdotnetdocker2:
image: aspdotnetdocker2
build:
context: .
dockerfile: Dockerfile
ports:
- 5000
b. docker-compose.yml
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 5000
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["aspdotnet_docker2.csproj", "./"]
RUN dotnet restore "./aspdotnet_docker2.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "aspdotnet_docker2.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "aspdotnet_docker2.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "aspdotnet_docker2.dll"]
Have a look at docker-compose docs:
SHORT SYNTAX
Either specify both ports (HOST:CONTAINER), or just the container port (an ephemeral host port is chosen).
So try:
ports:
- "5000:<port in ASPNETCORE_URLS>"
# e.g.
# - "5000:80"
# - "44388:443"
I know this is such a noob problem but I am having trouble understanding how to get my .Net Core website to connect to my MySql container. So some background, both the MySql and the .Net core website are in their separate containers. I have already started the MySql container and setup the root account to work. I am using Entity Framework inside of .Net Core project.
I created the MySql container using this statement:
docker run --name mysql_container -d -p 3306:3306
Below is the dockerfile that Visual Studio generated for me.
So what do I tell my .Net Core program to is the IP address of the MySql container if the IP can change?
Inside of .Net Core Program:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var connection = $"Server={GetDBAddress()};Database=myDataBase;Uid=root;Pwd=root;";
services.AddDbContext<ToDoContext>(options => options.UseMySQL(connection));
}
If I write the GetDBAddress function what goes in there? I cannot simply return localhost because it's another docker container? As of right now I am trying to use localhost and I get connection refused. But I am able to connect to the MySql db using workbench.
Also I am not sure but can these two setups be combined into some file I think they're called docker-compose files maybe?
Dockerfile
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY ["ToDoService/ToDoService.csproj", "ToDoService/"]
RUN dotnet restore "ToDoService/ToDoService.csproj"
COPY . .
WORKDIR "/src/ToDoService"
RUN dotnet build "ToDoService.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "ToDoService.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "ToDoService.dll"]
If you've launched MySQL exposing the ports you should be able to reach it connecting from localhost, with the port 3306.
Otherwise, as you suggested, there is the possibility to set up a docker-compose file. This file usually contains all the configuration your application needs to run. So, for example, a suitable configuration for your application (note: I'm assuming you're using MySQL 5.7 since you haven't specified one) could be:
version: '3.3'
services: # list of services composing your application
db: # the service hosting your MySQL instance
image: mysql:5.7 # the image and tag docker will pull from docker hub
volumes: # this section allows you to configure persistence within multiple restarts
- db_data:/var/lib/mysql
restart: always # if the db crash somehow, restart it
environment: # env variables, you usually set this to override existing ones
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: todoservice
MYSQL_USER: root
MYSQL_PASSWORD: root
todoservice: # you application service
build: ./ # this tells docker-compose to not pull from docker hub, but to build from the Dockerfile it will find in ./
restart: always
depends_on: # set a dependency between your service and the database: this means that your application will not run if the db service is not running, but it doesn't assure you that the dabase will be ready to accept incoming connection (so your application could crash untill the db initializes itself)
- db
volumes:
db_data: # this tells docker-compose to save your data in a generic docker volume. You can see existing volumes typing 'docker volume ls'
To launch and deploy your application, now you need to type in a terminal:
docker-compose up
This will bring up your deploy. Note that no ports are exposed here: only your service will be able to access the database from db:3306 (you don't need to refer by IP, but you can reach other services using the service name).
For debug purposes, you can still open your db ports adding this line under image:
ports:
- "3306:3306"
Note that this port has to be free (no other system services are using it), otherwise the entire deployment will fail.
Final note: since docker-compose will try to avoid to build your images every time you bring up the service, to force it to build a new one you have to append --build to the docker-compose up command.
To bring down your deploy just use docker-compose down. To delete all the persistent data related to your deploy (i.e. starting with a new db) append the -v flag at the end of the previous command.
Hope it helps!
I'm attempting to run a asp.net core application from a raspberry pi using docker, I think I have the main parts down. I have a repository on github that is a simplistic asp.net core project. I have setup an account on docker cloud which build everytime I push to my github repo.
I have docker pulled my repository onto my pi:
I run the command:
docker run -d -p 8080:80 joro550/radiusnet --network=host
and I can see that it is running:
But when I go to my pi's ip address on port 8080 then I get this:
When I've been searching around for this people have suggested adding these flags (which I have tried and come up with the same results:
adding --network=host to the docker run command
adding -it to the docker run command
Adding Expose 80 into the docker file
I think at this point I'm at a bit of a lose as to how to access this thing.
The docker documentation does suggest running
`docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" myapp`
If I'm using windows 10 Nano containers, which I don't believe I'm using but when I run this command I get a resounding <no value>
Cutting it back to docker inspect -f "{{ .NetworkSettings.IPAddress }}" myapp gives me a different ip address to my ips internal ip address, which I've tried on port 8080 and get the same result
Doing a curl on both addresses gives me the same result of connection refused:
Here's my docker file for anyone interested:
FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app
# copy csproj and restore as distinct layers
COPY /src ./
RUN dotnet restore
# copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out -r linux-arm
# build runtime image
FROM microsoft/dotnet:2.0.0-runtime-stretch-arm32v7
WORKDIR /app
COPY --from=build-env /app/src/RadiusNet.Web/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "RadiusNet.Web.dll"]
If any more information is needed please ask, I'm pretty new to Docker so I just did a bit of a knowledge dump of my current situation.
Link to github project (if it's needed): https://github.com/joro550/RadiusNet
Any help - at this point will be greatly appreciated
Cutting it back to docker inspect -f "{{ .NetworkSettings.IPAddress }}" myapp gives me a different ip address to my ips internal ip address, which I've tried on port 8080 and get the same result
Try curling the port 5000 and 80 with this IP address from inside the raspbery pi rather than 8080. Plus, are you sure you are exposing the right port? You have "expose 80" but the port 8080 is mapped to 5000, and docker ps shows no mapping for 80
I'm trying to run multiple instances of a Docker image on a single node and send requests to the node allowing Docker to load balance between the instances.
If I use the Run command shown below the container behaves as expected, I can send a request from another machine on port 80 and the request is serviced by container. However, if I try to spin up a service with the Service command shown below I do get 5 replicated tasks running but the request only returns a 404 error.
How can I communicate with the service through my exposed port?
This sample includes a ASP.Net Core 2.0 api that returns a Guid unique to the instance of the app.
Controller
using Microsoft.AspNetCore.Mvc;
using System;
namespace MinimalDockerTest.Controllers {
[Route("api/[controller]")]
public class NodeController : Controller {
[HttpGet]
public IActionResult Get() {
return Ok(NodeId);
}
private static Guid NodeId {
get;
} = Guid.NewGuid();
}
}
Dockerfile
#Context is binary output folder, i.e. bin/publishoutput
FROM microsoft/aspnetcore:2.0-nanoserver-sac2016
EXPOSE 80
WORKDIR /app
Copy . .
ENTRYPOINT ["dotnet", "MinimalDockerTest.dll"]
Build Command
docker build -t minimaltest .
Run Command
docker run -p 80:80 --name minimaltest minimaltest
Service Command
docker service create -p 80:80 --replicas 5 --name minimaltest minimaltest
Request
GET: http://node_ip/api/node
System
Windows 10 1703 Build 15063.0
Docker CE 17.12.0-ce-win46 (15048)
Edit
Found some good info here on SO.
I beleive you need to publish port in "host" mode (learn.microsoft.com/en-us/virtualization/windowscontainers/…). Also it will be one to one port mapping between running container and host and hence you will not be able to run several containers on the same port. Routing mesh is not working on Windows yet.
Source
Now the question remains; When will mesh routing be supported?
Make sure you aren't pulling a different image from the registry. By default, docker service will resolve the image name from the registry so that it will work on multiple nodes in the cluster. While docker run will use the image as it exists on the local node. You can disable this resolution process with the --no-resolve-image option:
docker service create -p 80:80 --replicas 5 --name minimaltest \
--no-resolve-image minimaltest
Apparently mesh routing is not available for Windows 10 Version 1703. Mesh Routing was made the default option on Windows with version 1709.
Box Boat
MS Blog
SO