projectkudu / kudu

Kudu is the engine behind git/hg deployments, WebJobs, and various other features in Azure Web Sites. It can also run outside of Azure.
Apache License 2.0
3.12k stars 653 forks source link

Kudu can't deploy ASP.NET Core Web App projects out of the box #2344

Closed javicrespo closed 6 months ago

javicrespo commented 7 years ago

Can't get Kudu to deploy asp.net core projects created with VS 2017 RC2

Example: https://github.com/javicrespo/AspNetCoreKuduTest

Kudu log: Found solution 'D:\home\site\repository\AspNetCoreKuduTest.sln' with no deployable projects. Deploying files instead.

Is that supported?

davidebbo commented 7 years ago

It works with my test project https://github.com/davidebbo-test/AspNetCoreDemo but not with yours. @watashiSHUN, what logic are we using to detect core that's causing @javicrespo's project not to be properly detected?

davidebbo commented 7 years ago

@javicrespo for now, try setting this App Setting in Azure Portal:

SCM_SCRIPT_GENERATOR_ARGS=--aspNetCore AspNetCoreKuduTest\AspNetCoreKuduTest.csproj
watashiSHUN commented 7 years ago

@davidebbo I don't think using SCM_SCRIPT_GENERATOR_ARGS will help in this case, @javicrespo in your csproj, you are including wwwroot folder, but I don't see it anywhere in your test repo. you can take a look at David's test regarding project structure.

Kudu is using this logic to identify dotnet core web project before build

I am not sure whether you forget to upload your wwwroot/web.config or you are trying to deploy a webjob (core project with no web interface)?

davidebbo commented 7 years ago

Actually, SCM_SCRIPT_GENERATOR_ARGS does allow it to deploy as a Core Web App, and it runs fine as a Web API (e.g. accessing /api/Values). @javicrespo please verify.

I think the problem is that our detection heuristic assumes that it's an MVC app, and fails to account for Web API apps. In a Web API app, you just won't have a wwwroot. As for web.config, my project doesn't have it either (it gets generated at build time).

Now the question becomes: what is the right detection logic that would cover Web API projects. The problem is that in the Core world, web apps are hard to differentiate from plain console apps (without looking at the code, which we don't want to do!).

Possible modifications to the heuristic is to check if the csproj includes a package reference to Microsoft.AspNetCore. I think that will get us closer is most scenarios.

And when all else fails, there is always SCM_SCRIPT_GENERATOR_ARGS.

watashiSHUN commented 7 years ago

I looked at a webAPI test project (with no wwwroot) which was created two months ago using visual studio 2017 (VisualStudioVersion = 15.0.26014.0). a web.config was generated for me, whereas a more recent version of visual studio 2017 does not (VisualStudioVersion = 15.0.26206.0).

but yes, we should add detection for the <PackageReference Include="Microsoft.AspNetCore" Version="..." /> (or maybe using this only?) since it covers all three cases in the latest dotnet cli:

  1. dotnet new web
  2. dotnet new mvc
  3. dotnet new webapi
davidebbo commented 7 years ago

I think to be safe we should keep the old check even after you add this one. e.g. consider this older .csproj file. It doesn't have Include="Microsoft.AspNetCore", but it has a bunch of other similar packages. So if you had an exact check for Microsoft.AspNetCore, you'd break that repo.

So just add an addition detection option and we should be in pretty good shape.

javicrespo commented 7 years ago

SCM_SCRIPT_GENERATOR_ARGS setting does the trick, thx.

davidebbo commented 7 years ago

I renamed issue to more precisely capture the problem.

snobu commented 7 years ago

Not sure if this got pushed to PROD yet. Probably not?

dotnet new webapi

Results in:

remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id '678d061a2d'.
remote: 'D:\home\site\repository\bench-aspnetcoreapi.csproj' is not a deployable project.
remote: Error - Changes committed to remote repository but deployment to website failed.

If i add a web.config that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <!-- To customize the asp.net core module uncomment and edit the following section.
  For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
  <!--
  <system.webServer>
    <handlers>
      <remove name="aspNetCore"/>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
  -->

</configuration>

then it deploys successfully as ASP.NET Core Web Application:

Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 632 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'c24f2c3615'.
remote: Generating deployment script.
remote: Project file path: .\bench-aspnetcoreapi.csproj
remote: Generated deployment script files
remote: Running deployment command...
remote: Handling ASP.NET Core Web Application deployment.
remote: ....
$ curl  https://bench-aspnetcoreapi.azurewebsites.net/api/values
["value1","value2"]
watashiSHUN commented 7 years ago

yes, adding a web.config will fix the issue since core web projects used to be created with one. The fix will probably be ready in Azure by the end of this week

davidebbo commented 7 years ago

More likely early next week.

davidmatson commented 7 years ago

I'm getting the same kind of error message when trying to deploy a CPS console app csproj as a web job. Any update on a fix for this issue (or should I open another one since the scenario is a little different)? Update: The problem appears to be here: https://github.com/projectkudu/kudu/blob/af1b4c524926ed0ad9ec6cb5b3789157256eaaf6/Kudu.Core/Infrastructure/VsHelper.cs#L141 The namespace isn't used for Common Project System-style csprojs.

watashiSHUN commented 7 years ago

@davidmatson this fix was already deployed, can you open a new issue and giving details about your project structure, deployment process and error messages you encountered?

ManfredLange commented 6 years ago

@davidebbo I saw your comment with the link to an ASP.NET Core test project where the test project is the only (web) project in the solution.

Do you happen to also have a recent working example of an ASP.NET Core web project that uses a kudu deploy.cmd script to deploy to Azure Web Services? It is my understanding that a custom deploy script is required if you have multiple web projects in your solution. Thank you!

watashiSHUN commented 6 years ago

you just need to specify your project: https://github.com/projectkudu/kudu/wiki/Customizing-deployments#deploying-a-specific-folder-for-a-node-php-or-aspnet-site or https://github.com/projectkudu/kudu/wiki/Customizing-deployments#deploying-a-specific-aspnet-or-aspnet-core-project-file

ManfredLange commented 6 years ago

@watashiSHUN Thank you for that link, very much appreciated. Yes, I saw that. It would work if didn't have to do other things in deploy.cmd as well. Hence my question regarding a working custom deploy.cmd script.

Do you or @davidebbo happen to have an example of a working custom deploy.cmd script for an ASP.NET Core MVC application created using the most recent wizard in VS2017 (version 15.5.6) with all the default settings?

davidebbo commented 6 years ago

@ManfredLange if you start out without a custom script, you can download the script that it uses and use that as a starting point for your custom script. It's an option under Kudu's Tools menu.

ManfredLange commented 6 years ago

@davidebbo Yes, thank you, David. I found that as well and am experimenting with it at the moment.

Challenge will be to get it working with a solution that has a mix of new and old project file formats. And then there is also the challenge of getting the version 15 tools working with it. Note that I have a working version for an old-style ASP.NET MVC 5.0 project targeting the full framework. Now I have an ASP.NET Core MVC targeting netcoreapp2.0.

I also noticed that using the kudu locally to generate the custom deploy script, the result seems to be different to what is produced in Azure for the same project file. The locally created one uses msbuild while the one downloaded from Azure uses 'dotnet publish' (which may or may not use msbuild, and if yes, which version? I don't know).

Perhaps I'm overlooking something. I'll keep experimenting.

davidebbo commented 6 years ago

@ManfredLange when you refer to doing it locally, what exactly are you using? Is it the azure CLI? I wonder if that's outdated. Note that you can install KuduScript from npm (https://www.npmjs.com/package/kuduscript), and that should normally be up to date.

ManfredLange commented 6 years ago

@davidebbo I used npm install the latest kuduscipt locally. It's claiming to install version 1.0.15 successfully, and that version is also reported in deploy.cmd. It creates a deploy.cmd that uses 'msbuild'. It does not create the version with 'dotnet publish'.

I have deleted files '.deployment' and 'deploy.cmd' again, the recreated them using version 1.0.15 of kuduscript using the command suggested at https://github.com/projectkudu/kudu/wiki/Custom-Deployment-Script#custom-deployment-script-generator. I then have it use nuget.exe version 4.5.1.

When I now execute 'deploy.cmd' I run into "error MSB4041: The default XML namespace of the project must be the MSBuild XML namespace." I can resolve this one by using version 15.3.409.57025 which I downloaded from Azure App Service using the diagnostic console.

With version 15.3 of MSBuild in place I then get this error: 'error MSB4057: The target "pipelinePreDeployCopyAllFilesToOneFolder" does not exist in the project.". I can resolve it by removing this from script but I have to assume that I'm missing something. What is the prerequisite for this parameter? How do I diagnose this issue?

Some additional background: We have a solution with about a dozen projects. It's a mix of old-style and new-style csproj-file (no xproj, though). Also it's a mix of projects targeting full framework 4.6.1 and netstandard2.0. At the top-level we have an ASP.NET Core MVC targeting netcoreapp2.0. Using VS Publish this works. Using deploy.cmd it doesn't even work locally. For example it doesn't copy binaries that are the output of any of the dependent projects, e.g. a class library.

It's been a very frustrating experience over many months, and I really would like to sort this out "the official way" or "the correct way". How would you like me to approach this in terms of error reporting?

Edit: I also updated azure-cli to the latest version 0.10.17 using npm. No difference.

davidebbo commented 6 years ago

Sorry about the frustrating experience. Let's separate the discussion into two parts:

  1. Getting the latest kuduscript
  2. Help in authoring a custom script that works with your Core project

For 1., I found that kuduscript on npm was in fact outdated (our bad!). I just updated it to v1.0.16, which has the very latest code. So please give that a try.

For 2. (assuming it's still needed after getting latest kuduscript) I'll let @watashiSHUN help with it as he's the expert.

ManfredLange commented 6 years ago

@davidebbo Thank you, David. I'll re-run my experiment using 1.0.16 of kuduscript.

ManfredLange commented 6 years ago

@watashiSHUN I have now recreated deploy.cmd using version 1.0.16 of kuduscript. I had to tell it to use version 15 of the build tools. I am using version 15.3.409.57025 which I got directly from Azure via diagnostics console. I'm not aware that a later version is available in Azure that we could use.

Running deploy.cmd and having it use msbuild 15.3.409.57025 (same as in Azure) results in compiler error: 'MSB4057: The target "pipelinePreDeployCopyAllFilesToOneFolder" does not exist in the project'.

I notice that locally VS2017 version 15.5.6 and also nuget.exe v4.5.1 (via "MSBuild auto-detection") are using version 15.5.180.51428 of MSBuild. Using this version doesn't change the problem. Still the MSB4057 error regarding missing target "pipelinePreDeployCopyAllFilesToOneFolder".

What am I missing? How could I further diagnose or better resolve this?

watashiSHUN commented 6 years ago

for dotnet core web project, we use dotnet cli to build and I just verified that it uses a higher version of msbuild15

D:\Program Files (x86)\dotnet\sdk\2.1.4>dotnet Msbuild.dll Microsoft (R) Build Engine version 15.5.180.51428 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved.

what are the command line arguments you passed to kuduscript? here is a dummy example

ManfredLange commented 6 years ago

watashiSHUN, I'm used the following command:

"kuduscript -y --aspWAP pathToYourWebProjectFile.csproj -s pathToYourSolutionFile.sln"

with the names for project and solution file adjusted. In both cases I use the absolute path and file name.

Edit: I note that the dummy example uses 'dotnet publish' instead of msbuild. Is this because of different parameters for kuduscript? Do I have to use '--aspNetCore' instead of '--aspWAP' when creating the custom scripts. I'll give that a try.

watashiSHUN commented 6 years ago

yes, as mentioned in the description of --aspNetCore:

Create a deployment script for ASP.NET Core web application, specify the project file path

my dummy example is generated by kudu, which detects what kind of project is to be deployed and call kuduscript with corresponding arguments

ManfredLange commented 6 years ago

Yes, with '--aspNetCore' I have now a working version locally. Next I'll try to deploy this.

A suggestion: perhaps at https://github.com/projectkudu/kudu/wiki/Custom-Deployment-Script#custom-deployment-script-generator it would be worth considering to add a remark that there are different options for kuduscript and that 'kuduscript -y' will show that list. In my case it might have triggered curiosity to explore '--aspNetCore' further. Just a thought.

Edit: I also tested this successfully in an Azure Cloud App. As a summary to other readers: To create a custom deployment script for an ASP.NET Core MVC application, do this:

  1. Update kuduscript to latest (1.0.16 as of writing)
  2. run kuduscript as follows: 'kuduscript -y --aspNetCore pathToYourWebProjectFile.csproj -s pathToYourSolutionFile.sln'
  3. Execute deploy.cmd
  4. Optional: Execute your web site locally using 'AspNetCoreWeb.exe' replacing 'AspNetCoreWeb' with the name of your ASP.NET Core project. By default your site will be available at http://localhost:5000
ManfredLange commented 6 years ago

@davidebbo @watashiSHUN Problem solved for the solution at hand. I'll have a look at another, even larger solution (50+ projects) with a mix of new and old project file format as well as targeting netstandard2.0 and net461. If there are further issues I'll log them accordingly.

Thank you for your awesome and timely assistance in resolving this! :-)

wireddown commented 5 years ago

I encountered this today 😢

Perhaps AspNetCoreHelper.IsDotnetCoreFromProjectFile() needs to also consider

Project Sdk="Microsoft.NET.Sdk.Web"

as an indicator that this is a ASP.NET Core Web API because new webapi doesn't generate a web.config or project.json file nor does it create a wwwroot folder.

C:\src\tmp ♥ dotnet new webapi
The template "ASP.NET Core Web API" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\src\tmp\tmp.csproj...
  Restore completed in 46.56 ms for C:\src\tmp\tmp.csproj.

Restore succeeded.

C:\src\tmp ♥ ls
appsettings.Development.json  appsettings.json  Controllers/  obj/  Program.cs  Properties/  Startup.cs  tmp.csproj  WeatherForecast.cs

C:\src\tmp ♥ cat tmp.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
  </ItemGroup>

</Project>
jvano commented 6 months ago

Hi

If the problem persists and is related to running it on Azure App Service, please open a support incident in Azure: https://learn.microsoft.com/en-us/azure/azure-portal/supportability/how-to-create-azure-support-request

This way we can better track and assist you on this case

Thanks,

Joaquin Vano Azure App Service