How to publish Visual Studio ASP.NET 5 projects to Docker Hub? - asp.net

I'm looking for a way to publish my website to DaoCloud, a Docker container service provider.
The provider doesn't open their API for you. They just let you build your APP from source on GitHub or pulling image from Docker Hub. If you're building from GitHub, you can specify the Dockerfile which should be used for building.
But as you can see the Dockerfile in a ASP.NET 5 project
It doesn't specify any ports. Neither does projects.json/commands/web. I have tried to add ports specification manually and then build it, but with no success. All contents in the wwwroot folder return 404 error.
How can I create a buildable repository or create a Docker Hub image by Visual Studio?

Your Dockerfile seems to be right. Here is the one I used to build:
FROM microsoft/aspnet
COPY . /app
WORKDIR /app
RUN ["dnu", "restore"]
EXPOSE 5004
ENTRYPOINT ["dnx", "-p", "project.json", "web"]
Maybe you could share your project.json. Here is the command into the project.json that matches the entrypoint declared in the dockerfile.
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5004"
},
The (*) allows kestrel for listening requests from all domains.
You can find some samples here: AspNet Home Samples
Hope this helps !

Related

.Net Dockerizing excluding build stage in the dockerfile

I am new to docker and AKS, I am working on a .Net project that is migrated from .Net core 3.1 to .Net 6 , I am trying to containerize and deploy to AKS. First i wanted to test in the local machine so i had setup docker in the macbook m1 and followed this link https://learn.microsoft.com/en-us/visualstudio/mac/docker-quickstart?view=vsmac-2022 to create a dockerfile, I am able to run the dockerfile from Visual Studio if i follow the steps given in the link but if i run docker compose command from terminal i am getting issues with SDK version, however what i am trying to achieve is remove the build stage and directly run the .net application as the build stage is taken care by Jenkins and the DLL is placed in a folder
Here is the complete dockerfile with all the stages
FROM mcr.microsoft.com/dotnet/core/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:6.0 AS build
WORKDIR /src
COPY DockerDemo/DockerDemo.csproj DockerDemo/
RUN dotnet restore "DockerDemo/DockerDemo.csproj"
COPY . .
WORKDIR "/src/DockerDemo"
RUN dotnet build "DockerDemo.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DockerDemo.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DockerDemo.dll"]
I modified dockerfile excluding build stage, I am taking DLL file from a "lib/net6.0" that is built by jenkins and placed in this folder
FROM mcr.microsoft.com/dotnet/core/aspnet:6.0 AS base
COPY ["lib/net6.0","/src/"]
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM base as final
WORKDIR /app
COPY --from=base /src/ .
ENTRYPOINT["dotnet","DockerDemo.dll"]
If i build the dockerfile the image is getting created but when i run I am getting following error
unhandled exception system.io.filenotfoundexception could not load
file or assembly 'NLog, Version=.5.0.0.0
The project is using NLog.Web.ASPNetCore 5.1.4 version, i tried downgrading it to 5.0.0 but i am still getting the same error, i also tried adding just NLog 5.0.0 package but no luck
As i said i am new to Docker and also to the .net development on macbook
My Questions
Q1) Is it possible to exclude the build stage in dockerfile and directly run
Q2) Does the macbook m1 completely supports .Net Core and .Net 6 development so that it can be deployed to AKS via Jenkins pipeline

How to add sub-directory to my web application on IIS running in a Docker Container?

I have a solution containing 2 projects, 1 is my WCF web service and 1 is a front-end web page made on ASP.NET MVC 4. I decided to containerize these 2 projects so I can do API testing with CI.
But I am having trouble making a subdirectory just like the one in a locally installed IIS. This is where I normally deploy my builds on my local machine without Docker:
Since I am deploying this way, each applications has sub-directories like this
Now that I am using Docker, I wanted to replicate this setup. I have tried adding WORKDIR /inetpub/wwwroot/FormulaBuilder on my dockerfile whereas FormulaBuilder is the sub-directory, but it didn't work. I get this error instead:
Both my web service and the front-end web-page works if you setup both on different ports. But I wanted to remove the ports so I don't have to deal with conflicts when I'm updating Service References on my project. In addition, I wanted to be as close to the production setup as possible when performing API testing.
Is it possible to add sub-directories with the use of IIS that came with the base image? If so, how do you do it? Below are my docker files:
FBSVC (WCF web service project)
FROM mcr.microsoft.com/dotnet/framework/wcf:4.8
ARG source=bin/app.publish
WORKDIR /inetpub/wwwroot/
COPY ${source:-obj/Docker/publish} .
EXPOSE 80
FormulaBuilder (Front-end web page project)
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8
ARG source=bin/app.publish
WORKDIR /inetpub/wwwroot/FormulaBuilder
COPY ${source:-obj/Docker/publish} .
EXPOSE 80
Docker Compose
version: "3"
services:
web-service:
build: ./FBSVC
container_name: "FBSVC"
ports:
- "5001:80"
front-end:
build: ./FormulaBuilder
container_name: "FormulaBuilder"
ports:
- "5000:80"
I am new to Docker and I am still exploring things. Any help would be appreciated. Thanks!

What could cause a "TypeError: (0 , d.__decorate) is not a function" of an angular function inside a docker container?

I'm building a web application. The frontend is in angular and the backend in .Net Core.
Currently, I'm doing the following, to build my final docker image:
Build angular app
Copy the built angular files in the wwwroot of asp.net core
Building the asp.net core app
Publishing the asp.net core app
Copying the publish result inside a docker image.
Here is my current dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM node:latest as node
WORKDIR /app
COPY Frontend .
RUN npm install
RUN npm run build
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Backend/my-project.csproj", "Backend/"]
RUN dotnet restore "Backend/my-project.csproj"
COPY Backend Backend
WORKDIR "/src/Backend"
COPY --from=node /app/dist/app/ /wwwroot/
RUN dotnet build "my-project.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "my-project.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "my-project.dll"]
The whole process finish without errors, but when I'm trying to access to http://localhost/, I get the html, but there is a javascript error:
Uncaught TypeError: (0 , d.__decorate) is not a function
at Object.619 (main.3ba20fe70ead0a4b.js:1:45137)
at r (runtime.834ae414fca175dc.js:1:127)
at Object.1983 (main.3ba20fe70ead0a4b.js:1:45670)
at r (runtime.834ae414fca175dc.js:1:127)
at main.3ba20fe70ead0a4b.js:1:512504
at n (runtime.834ae414fca175dc.js:1:2649)
at main.3ba20fe70ead0a4b.js:1:57
But:
the result of ng serve work
serving with a test server the result of npm build works
Copying the result of npm build to wwwroot of my asp.net core works in debug
Publishing the asp.net core app(with the wwwroot populated) also works
When I try to access to each individual file present in my npm build folder, it seems to be accessible(not sure, because names have this number that is not exactly the same)
If I deleted nodes_modules, packages-lock.json and run npm install and npm run build, it also works
I deleted the angular app, created another one, run the whole docker build, it works.
I tried to change node to the version I'm using on my computer(node 16.14)
Edit
I started to remove everything from my app to see when it starts working again. It appears that once I remove my State(s) of NgxsModule.forFeature([]), it works.
So basically, if I've a module with:
NgxsModule.forFeature([])
It works, but NgxsModule.forFeature([UiState]) doesn't, even if UiState is almost empty:
#State<UiStateModel>({
name: 'ui',
defaults: {
isMenuOpen: true,
},
})
#Injectable()
export class UiState {}
I'm kind of desperate, any idea what could cause this error?
I'm not exactly sure what did the trick, but I finally solved it.
What I did:
I had some ngxs packages that were refered as dev dependencies AND dependencies(with different version), I kept only the one in the dependencies
In my tsconfig.json, I was having a paths specified for "tslib"(to the nodes_modules one). I remember I added it, but I don't remember why, I think at some point I was having a compilation error and I found on SO this solution. I did remove this path for tslib, which is what probably solve the issue.

Containerrizing Hosted Blazor WebAssembly for Raspberry Pi Docker Swarm

I’m developing a DotNet Core hosted Blazor WebAssembly, as a frontend to my backend ASPNet Core API, running on Raspberry Pi’s, containerised in a Docker Swarm.
I’m developing on a MacBook Pro, using VSCode for Mac, and it’s really a great tool. I created the solution as “dotnet new blazorwasm —hosted” and got the solution created and build.
I have installed Docker Desktop, and created a Buildx builder for arm, which works great with all my other solutions (DotNet Core API, DotNet Background solutions), but with the hosted blazorwasm solution, I run into several problems, probably caused by my lacking knowledge on setting up build options.
So I installed Visual Studio 2019 (I have used VS on Windows for 20 years) and was actually surprised over the look and feel, a really great tool.
I created the hosted Blazor WebAssembly solution, which works great om Mac, and even the Docker desktop integration work without problems.
Building the Docker Image was easy, I just used my Buildx builder, and executed below command from the command line:
“docker buildx build --file ./SnakeConsole/Server/Dockerfile --platform linux/arm/v7 -t jagdriver/wavesnake:SnakeConsole3 --push .”
On the Raspberry Swarm, I then created the Stack/Container. The Stack installed but the container refused to start, and the log was:
standard_init_linux.go:211: exec user process caused “exec format error”.
I have seen this error before, and as far as I remember I added “-r ubuntu.19.10-arm” to the dotnet publish command to ensure that the code is generated for linux-arm.
So I tried to add “-r ubuntu.19.10-arm” to the dotnet publish command in below dockerfile, and execute the Docker buildx build command again, but then the Build Engine run into below error.
project.assets.json' doesn't have a target for '.NETCoreApp,Version=v5.0/browser-wasm'. Ensure that restore has run and that you have included 'net5.0' in the TargetFrameworks for your project. You may also need to include 'browser-wasm' in your project's RuntimeIdentifiers
Can anyone out the give me a helping hand on this, thanks in advance.
FACTS:
The solution I’m mentioning is the standard Hosted Blazor
WebAssembly template without any changes.
The target framework is .Net 5.0
Visual Studio for Mac community is version 8.7.2 (build 4)
Docker file from the default hosted Blazor WebAssembly template.
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY SnakeConsole/Server/SnakeConsole.Server.csproj SnakeConsole/Server/
COPY SnakeConsole/Client/SnakeConsole.Client.csproj SnakeConsole/Client/
COPY SnakeConsole/Shared/SnakeConsole.Shared.csproj SnakeConsole/Shared/
RUN dotnet restore "SnakeConsole/Server/SnakeConsole.Server.csproj"
COPY . .
WORKDIR "/src/SnakeConsole/Server"
RUN dotnet build "SnakeConsole.Server.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "SnakeConsole.Server.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "SnakeConsole.Server.dll"]
Have faced similar issue, documentation says:
Deploying a standalone Blazor WebAssembly app to Azure App Service for Linux isn't currently supported. A Linux server image to host the app isn't available at this time. Work is in progress to enable this scenario.
https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-5.0#standalone-deployment
Looks like this is a Docker OS compatibility and framework functionality issue. I would suggest to target your app to Server (Blazor Server Hosting model scenario).

Is it possible to run my development asp.net core server out of a docker container

When developing node.js projects I will normally use docker compose to bring up an entire stack of docker containers in order to develop on my local host. I mount volumes in and use nodemon to automatically update the running server. This works well. However, it does not seem to work quite the same way with asp.net core.
Is it possible to run a development container for an asp.net core application? I would like to have the server restart when there is a change on the host machine to a file. I know you can do this with the dotnet watch run command but I'm yet to see it working inside a running docker container. How can I get this working within a docker compose stack? What docker base image should I be using? Ideally this solution will work from the command line without using visual studio as I'm using Visual Studio code on a mac.
A little bit late to the party, but maybe it will help someone.
Here is the sample project setup that will leverage dotnet watch command
in a docker container, while source code is being edited on the host system.
As far as I know dotnet watch now is a global tool so you can use it with
different versions of .netcore.
Here is the documentation for
dotnet watch command.
Sample project overview
Here is a small example project for demo purposes, made with help of minimal api.
It has one endpoint /freshbread which returns "Baked bread".
Folder structure:
Bakery
│ Dockerfile
└───src
│───Bakery.csproj
└───Program.cs
Content of Program.cs:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/freshbread", () => "Baked bread");
app.Run("http://*:80");
Content of Bakery.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
Content of Dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:6.0
WORKDIR /app
ENTRYPOINT ["dotnet", "watch"]
Based on a Microsoft .net core SDK image. It just defines an /app workdir and launches there dotnet watch command.
The "trick" here is to mount into /app folder your source code from the host machine and let container handle compilation
and server restart, so:
Build an image (from Bakery folder):
docker build -t dev-container .
Run a container:
docker run \
--rm \
--detach \
--volume /path/to/the/Bakery/src:/app \
--publish 5000:80
dev-container
Publish port outside, so api will be accessible from the host machine.
Now, container is watching files in mounted folder and whenever there are chages
it will perform hot-reload.
Demo
Here is a short demo of this setup, note that top and bottom-right splits are host machine terminals and bottom-left split is log of the container.

Resources