Deploy ASP.Net Application to Window Server Core Container - asp.net

I'm having an issue with manually building and running a windows server core container with a legacy asp.net web application. From Visual Studio I can run the container with the auto-generated dockerfile/yml file.
I want to do a docker build and docker run powershell command using the dockerfile instead of with Visual Studio.
This is current yml file:
version: '3'
services:
fulldotnetwebapplication:
image: fulldotnetwebapplication
build:
context: .\FullDotNetWebApplication
dockerfile: Dockerfile
This is the current dockerfile:
FROM microsoft/aspnet:4.7.1-windowsservercore-ltsc2016
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .
Let's say my ASP project is FullDotNetWebApplicationand it contains App_Data, Content, Controllers, etc folders plus Master/ASPX pages along with web/packages/config.
I tried this for my Dockerfile:
FROM microsoft/aspnet:4.7.1-windowsservercore-ltsc2016
WORKDIR /inetpub/wwwroot
COPY . .
COPY ./bin ./bin
and am getting this error:
docker : COPY failed: GetFileAttributesEx \\?\C:\Windows\TEMP\docker-builder977521850\bin: The system cannot find the file specified.
At line:1 char:1
+ docker build -t fulldotnetwebapplication .
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (COPY failed: Ge...file specified.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
What should my docker file look like to deploy this application to IIS from Powershell? I'm not understanding what magic VS is doing to make this work? Is it building the application or some sort of deployment file being generated? Any examples I could be pointed to or sample Dockerfile's would be great.

${source:-obj/Docker/publish}
That is why you can run it in VS but not from PowerShell/CMD, VS injects the source part of that path, to map it to the special docker publish folder for the current project.
If up replace that with . ., that means copy everything recursively from my current executing directory (which is usually the same as the dockerfile location if you didn't specify the file manually) to the working directory in the container. As such, your attempt COPY ./bin ./bin is unnecessary, as the proceeding COPY . . will have already copied that directory (assuming it does actually exist)
Is it building the application or some sort of deployment file being generated?
The container is the unit of deployment, you cannot deploy a container to IIS, it must be run on a container Host. Docker will not build your solution either, before building the container you should build your solution, and then copy just the required output (which is what the VS source path is attempting to do).
It is possible to get your container workflow to also build your solution using a multi-stage container, where by you use a container with VS installed to build the project, then copy the output to another container for running it, but that is a fairly advanced setup that I wouldn't recommend if you can't even get normal build copying working.

Related

Dockerfile COPY ${source:-obj/Docker/publish} not finding the correct source after upgrade to 3.1

I am using Jenkins to build and deploy a .Net Core microservice application. For each microservice, I am building a docker container. My dockerfile has the following in it:
ARG source
COPY ${source:-obj/Docker/publish} .
Prior to upgrading from .Net Core 2.2 to 3.1, this worked. After the upgrade, when I try to deploy, I am getting the following error:
COPY failed: stat /var/lib/docker/tmp/docker-builder609391151/obj/Docker/publish: no such file or directory
script returned exit code 1
From what I've read, it looks like .Net Core 2.2 compiled into the /obj/Docker/publish directory, but .Net Core 3.1 compiles into the /bin/Release/netcoreapp3.1 directory, however the source is still pointing to /obj/Docker/publish. I'm trying to figure out where the source arguement is defined, and how I should change this.
Update:
I decided to leave the source out entirely and hard-code the build path. I changed the copy line to
COPY /var/lib/jenkins/jobs/fusion-core/branches/master/workspace/src/CustomerAPI/obj/Release/netcoreapp3.1 .
I'm still getting an error when I try to build the docker container that says
COPY failed: stat /var/lib/docker/tmp/docker-builder356954794/var/lib/jenkins/jobs/fusion-core/branches/master/workspace/src/CustomerAPI/obj/Release/netcoreapp3.1: no such file or directory
script returned exit code 1
I'm not sure where the "/var/lib/docker/tmp/docker-builder356954794" is coming from, or why it is appending it to the front of my path, but it doesn't exist.
Still not sure how to get around this.
Some debugging suggestions in no certain order.
Default Value
${source:-obj/Docker/publish} is bash syntax that evaluates to the value of the variable source if it was defined, or obj/Docker/publish if it was not.
I'm trying to figure out where the source argument is defined, and how I should change this.
If you can't find anything that defines it to another value, it just means that the default value obj/Docker/publish was being used.
Publish directory
3.1 still uses the publish directory, but it will be at bin/Release/netcoreapp3.1/publish. Use a RUN find -type d -iname publish to find the publish directories in your container.
Dont use the full path, it will change every build. See the tmp/docker-builder356954794 in the path?
The COPY command uses relative files, based on the path in your machine (outside the docker container). So use a path that's relative to where the context directory (or Dockerfile) is. If the dockerfile is at /var/lib/jenkins/jobs/fusion-core/branches/master/workspace/src/CustomerAPI/Dockerfile and the publish directory on your machine is at /var/lib/jenkins/jobs/fusion-core/branches/master/workspace/src/CustomerAPI/bin/Release/netcoreapp3.1/publish, then use a COPY command like this:
COPY bin/Release/netcoreapp3.1/publish .
Funny paths
I'm not sure where the "/var/lib/docker/tmp/docker-builder356954794" is coming from
Containers need to share files from one directory (in your host) to another (in your container). Depending on the container technology, it uses one or more file systems or file directories.
One of those is /var/lib/docker/tmp/...

What to copy for a .Net Core console application publish?

I have an incredibly simple .NET core console application that I'd like to publish into a self contained executable. My application uses an the Microsoft.Extensions.Configuration.Json package so I can use an appsettings.json file.
From the command line, in the .csproj folder, I run
dotnet publish --self-contained true -r win-x64
. Inside my Debug folder, I see a netcoreapp2.1 folder and then the win-x64 folder. Inside that folder, I see the following:
publish -> folder
myapp.deps.json
myapp.dll
myapp.exe
myapp.pdb
myapp.runtimeconfig.dev.json
myapp.runtimeconfig.json
appsettings.json
hostfxr.dll
hostpolicy.dll
Am I supposed to copy just the files from this directory or do i have to copy the entire publish folder along with the files to my destination on a Windows Server? Or did I miss a switch to condense these items down further so movement from server to server is even simpler?
Copying just the files from the win-x64 directory was not enough. I needed to copy up the entire publish folder and run the application from that directory, otherwise error messages such as not being able to find a dependency would occur.

Docker: Installed component of parent image disappear after run container

I want to make a docker image that contains an Asp.net core app and some other components. I have decided to pull the debian image, install the necessary components (in this case is the asterisk system), then commit and push it as my own image, let's call it A.
In the Asp.net core app, I use A as a parent component in dockefile and build a image, let's call it B.
But when I run B as a container, I can not find the components I already installed in the image A.
This is my dockerfile:
FROM vocaoson7/asterisk:king
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app
# copy csproj and restore as distinct layers
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore
# copy everything else and build app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /app/aspnetapp
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
WORKDIR /app
COPY --from=build /app/aspnetapp/out ./
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
You are trying to use a multi-stage build and the way it works is that your final image is defined by your last FROM command in your Dockerfile and whatever follows that.
So for your case, all you will find in your final image is the aspnet:3.1 installation (from the base image used for the runtime stage) and an /app folder containing with what your build step generated in the out directory.
Your very first FROM has no influence whatsoever on the final image.

Docker run gives "CreateProcess: failure in a Windows system call: The system cannot find the file specified. (0x2)"

I am very new to docker. And I am trying to dockerize a helloworld API.
But when I tried to docker run the image, I got this error:
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error
response from daemon: container
f891d7fc7af6e1183256043e6105fc87e25c6959d9745cc972b42c7b2e6f5a06
encountered an error during CreateProcess: failure in a Windows system
call: The system cannot find the file specified. (0x2) [Event Detail:
Provider: 00000000-0000-0000-0000-000000000000] [Event Detail:
Provider: 00000000-0000-0000-0000-000000000000] [Event Detail:
vm\compute\management\orchestration\vmhostedcontainer\processmanagement.cpp(168)\vmcomputeagent.exe!00007FF683797B25:
(caller: 00007FF68377A312) Exception(4) tid(108) 80070002 The system
cannot find the file specified.
CallContext:[\Bridge_ProcessMessage\ComputeSystemManager_ExecuteProcess\VmHostedContainer_ExecuteProcess]
Provider: 00000000-0000-0000-0000-000000000000] extra info:
{"CommandLine":"dotnet
HelloWorldDocker.dll","WorkingDirectory":"C:\app\bin","Environment":{"COMPLUS_NGenProtectedProcess_FeatureEnabled":"0","ROSLYN_COMPILER_LOCATION":"c:\\RoslynCompilers\\tools"},"CreateStdInPipe":true,"CreateStdOutPipe":true,"CreateStdErrPipe":true,"ConsoleSize":[0,0]}.
I have a simple asp.net api. And I have it published to the same folder ./publish
And here is my docker file
FROM microsoft/aspnet:4.7.1-windowsservercore-1709
WORKDIR /app
COPY ./publish .
WORKDIR bin
RUN ls
ENTRYPOINT ["dotnet", "HelloWorldDocker.dll"]
ls shows that the HelloWorldDocker.dll is in the directory ./bin (app/bin). IDK what is wrong here...
This line COPY ./publish . will copy all publish files into your current work directory. The bin folder that contains your DLL now lives here: /app/bin/{your dll}.
It is not necessary to then change the work dir to bin like you did; instead, you could either leave your work dir alone (stay in /app) and specify your entrypoint as:
ENTRYPOINT ["dotnet", "./bin/HelloWorldDocker.dll"]
-OR-
You could set your WORKDIR to /app/bin and specify your entrypoint as you already did: ENTRYPOINT ["dotnet", "HelloWorldDocker.dll"]
The main thing you need to keep in mind is where the files are in relation to your workdir, which you can manage by changing your workdir as well as copying files, as you did by copying all publish files into /app
this may happen when you are rebuilding the image , in fact when you build a docker image it creates some intermediate containers and images so by deleting these containers and images from the previous build fail it worked for me.
In my case, I was with this error (little similar):
Command: docker run -it henriqueholtz/node-win:16.15.1 cmd
docker: Error response from daemon: container 1edc7d95388e28604239457fd47ced188b968ab825f8da400c8bea84cfbb7ceb encountered an error during hcsshim::System::CreateProcess: failure in a Windows system call: The system cannot find the file specified. (0x2)
[Event Detail: Provider: 00000000-0000-0000-0000-000000000000]
[Event Detail: Provider: 00000000-0000-0000-0000-000000000000]
[Event Detail: onecore\vm\compute\management\orchestration\vmhostedcontainer\processmanagement.cpp(174)\vmcomputeagent.exe!00007FF744D6C00A: (caller: 00007FF744D3ECEA) Exception(2) tid(368) 80070002 The system cannot find the file specified.
CallContext:[\Bridge_ProcessMessage\ComputeSystemManager_ExecuteProcess\VmHostedContainer_ExecuteProcess]
Provider: 00000000-0000-0000-0000-000000000000].
How I've fix it?
After some hours trying with no success, I've removed all similar images, pulled the image again (in my case from docker hub), and then it worked.
In the runner config.toml, my runner was configured to use the shell pwsh.
I replaced it with powershell and it worked.
The error comes from the fact that, for whatever reason, pwsh is not available.

ASP.NET Core Project w/ JavaScriptServices in Docker Unable to Launch Node

I am having issues getting a site to run properly inside of a docker container. The container builds fine and runs, however when navigating to a page it fails on loading JavaScript services.
Here is the Dockerfile
FROM microsoft/aspnetcore-build:2.0 AS builder
WORKDIR /app
ADD company_cas.pem /usr/local/share/ca-certificates/company_cas.crt
RUN update-ca-certificates
COPY company_cas.pem ./
RUN npm config set cafile company_cas.pem
# Run NPM install for dependencies
COPY package.json ./
RUN npm install
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=builder /app/out .
ENTRYPOINT ["dotnet", "web.dll"]
I am using the microsoft/aspnetcore-build:2.0 base image, and npm does run so Node is installed to the best of my knowledge.
The output of the failed request is -
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
web | An unhandled exception has occurred: Failed to start Node process. To resolve this:.
web |
web | [1] Ensure that Node.js is installed and can be found in one of the PATH directories.
web | Current PATH enviroment variable is: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
web | Make sure the Node executable is in one of those directories, or update your PATH.
web |
web | [2] See the InnerException for further details of the cause.
web | System.InvalidOperationException: Failed to start Node process. To resolve this:.
web |
web | [1] Ensure that Node.js is installed and can be found in one of the PATH directories.
web | Current PATH enviroment variable is: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
web | Make sure the Node executable is in one of those directories, or update your PATH.
web |
web | [2] See the InnerException for further details of the cause. ---> System.ComponentModel.Win32Exception: No such file or directory
Full Error Stack # Pastebin
Is this a matter of setting a new PATH for ASP.NET to find Node? If so, any idea on what that path should be in Docker?
I guess I overlooked the runtime image base container.
Changed to FROM microsoft/aspnetcore-build:2.0 and now I'm good.

Resources