I'm trying to call "dotnet publish" with a specific publish profile pubxml file as documented here :
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/visual-studio-publish-profiles?view=aspnetcore-2.1&tabs=aspnetcore2x
However, everything I try seems to result in the default behaviour, and the /p:PublishProfile part is ignored.
dotnet publish /p:PublishProfile="MyFolderProfile"
Doesn't work, and logs no error, building to the default location under "/obj".
I do note that an intentionally incorrect command has the same result though, eg:
dotnet publish /p:PublishProfile="MyFolderProfile-XXXXX"
What am I doing wrong? - Any pointers would be greatly appreciated!
My response is late. My solution has a simple .NET Core console application ConsoleAppCore.csproj. I used Visual Studio IDE to generate a publish profile with the name FolderProfile.pubxml and then the following commands worked for me:
Relative path - From the solution root
dotnet publish ConsoleAppCore\ConsoleAppCore.csproj /p:PublishProfile=ConsoleAppCore\Properties\PublishProfiles\FolderProfile.pubxml
Absolute path - From any location
dotnet publish "C:\work\ConsoleAppCore\ConsoleAppCore.csproj" "/p:PublishProfile=C:\work\ConsoleAppCore\Properties\PublishProfiles\FolderProfile.pubxml"
On Azure dev ops
Task name=.NET Core
Task version=2
Command=publish
Path to projects=I left this empty
Arguments=
$(System.DefaultWorkingDirectory)\ConsoleAppCore\ConsoleAppCore.csproj /p:PublishProfile=$(System.DefaultWorkingDirectory)\ConsoleAppCore\Properties\PublishProfiles\FolderProfile.pubxml --configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)\ConsoleAppCore-Publish\
In the Azure Dev Ops build pipeline scenario, I have redirected the output to a folder under $(Build.ArtifactStagingDirectory) . I also have a Publish Artifact task which is configured to use the staging directory variable.
I have made use of the publish profile XML file because I wanted a single file to govern the complete behavior while on Azure Devops. Relying on a single file for all parameters simplifies management on Azure.
Azure Dev ops - Artifacts Explorer
The Publish Artifact task created a drop for me and this is how it looks. Please notice that the file name in the explorer tallies with the name specified along with the --output option in the dotnet publish task
I ran into the same issue a while ago. I managed to fix it by instead calling:
dotnet build [projectname] /p:PublishProfile=[PublishProfile]
There is an open (as of Oct 2021) issue for Folder Publish with the similar symptoms https://github.com/dotnet/sdk/issues/12490
Workaround I use for now is to manually edit *.pubxml file produced by VS.Net to have both PublishUrl and PublishDir keys with the same values.
With this dotnet publish -p:PublishProfile=... works as expected.
You might need the full path, e.g.
dotnet publish -c Release /p:PublishProfile=Properties\PublishProfiles\FolderProfile.pubxml
Try this based on: https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/visual-studio-publish-profiles?view=aspnetcore-3.1#publish-profiles
dotnet build ..\project\project.csproj /p:DeployOnBuild=true -c Release /p:PublishProfile="Folder Staging"
I included a relative csproj path and a publish profile name with a space in it to clarify how to deal with those cases. The -c flag is optionally used to specify the configuration to use.
See https://github.com/dotnet/docs/issues/19677. The PublishProfile is only the name, any directory before it is disregarded.
PublishProfile property is treated as a file name and the directory is
constructed separately.
The PublishProfileFullPath property should be used if specifying a custom path.
I used this on VS build events
dotnet publish $(SolutionDir)DIRECTORI_1/PROJECT_1.csproj -c Release -o C:\Deployments\FOLDER_1
To solve the problem you must add a < PublishDir > property to your .pubxml file. Then the
dotnet publish /p:Configuration=Release /p:PublishProfile=FolderProfile
command works fine.
Example below.
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<DeleteExistingFiles>false</DeleteExistingFiles>
<ExcludeApp_Data>false</ExcludeApp_Data>
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>C:\MyApp\PUBLISH</PublishUrl>
<PublishDir>C:\MyApp\PUBLISH</PublishDir>
<WebPublishMethod>FileSystem</WebPublishMethod>
<_TargetId>Folder</_TargetId>
</PropertyGroup>
</Project>
you can also use a relative path like
<PublishUrl>PUBLISH</PublishUrl>
<PublishDir>PUBLISH</PublishDir>
Related
I have a .net-core 3.1 project (Microsoft.NET.Sdk.Web) in gitlab, and am setting up a CI/CD pipeline for it. As the final step, I want to have all the .dll and .exe output files signed by our key. I can do this by manually putting in some 'signtool' commands as a part of the gitlab-ci.yml file, however that requires going into each project and manually tweaking the file to reflect the specifics of that project.
On the other hand, I have been able to add a generic target in the .csproj file which calls signtool as an exec/command on $(TargetDir)$(TargetFileName). This works to a degree - but it doesn't sign everything. In this case, it signs (e.g.) cthulhu.dll, but not also cthulhu.Views.dll (both of which are shown in the CLI output of 'dotnet msbuild') and there's also a cthulhu.exe that is generated but is not shown in the msbuild output and also not signed.
The csproj file has this as the target (tried running both after rebuild and after publish):
<Target Name="SignAssembly" AfterTargets="Rebuild">
<Message Text="Signing assembly '$(TargetDir)$(TargetFileName)'" Importance="high" />
<Exec Command="signtool sign /f "mykey.pfx" /p "snip" /tr http://timestamp.digicert.com "$(TargetDir)$(TargetFileName)"" />
And the gitlab-ci.yml file looks like this (I'm aware that I'm using the sdk docker container, but it seems to let me support .net-core builds anyway, whereas there is a bug preventing the specific .net-core container from working):
image: mcr.microsoft.com/dotnet/framework/sdk:4.8
stages:
- build
- release
build:
stage: build
script:
- 'dotnet build -r win-x64'
release:
stage: release
script:
- 'dotnet add package signtool --version 10.0.17763.132'
- 'dotnet msbuild cthulhu.csproj /t:"Restore;Rebuild;SignAssembly;Publish" /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=Release /p:Platform=x64 /p:TargetFrameworks=netcoreapp3.1 /p:PublishDir=bin\Release\netcoreapp3.1\publish\win-x64 /p:RuntimeIdentifier=win-x64 /p:PublishReadyToRun=False /p:PublishTrimmed=True'
artifacts:
name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
paths:
- '.\bin\Release\netcoreapp3.1\publish\win-x64'
Why not use standard tools - Directory.Build.props?
However, now you can add a new property to every project in one step
by defining it in a single file called Directory.Build.props in the
root folder that contains your source. When MSBuild runs,
Microsoft.Common.props searches your directory structure for the
Directory.Build.props file (and Microsoft.Common.targets looks for
Directory.Build.targets). If it finds one, it imports the property.
Directory.Build.props is a user-defined file that provides
customizations to projects under a directory
Indicates that the assembly should be signed:
<SignAssembly>true</SignAssembly>
The key is specified using the following property:
<AssemblyOriginatorKeyFile>key.pfx</AssemblyOriginatorKeyFile>
That is, as a result, these properties will be imported into the projects and you will achieve the desired result.
I tried to use Azure App Service Deployment Center to set up an auto deployment using git (mine is hosted on bitbucket)
It produced an error MSB3073 on Running deployment command ...
[XDT] Transform file not found: D:\home\site\repository\Cairo.Portal\\web.Release.config
D:\home\site\repository\Cairo.Portal\Cairo.Portal.csproj(77,5): error MSB3073: The command "dotnet transform-xdt --xml "D:\home\site\repository\Cairo.Portal\\web.config" --transform "D:\home\site\repository\Cairo.Portal\\web.Release.config" --output "D:\home\site\repository\Cairo.Portal\bin\Release\net46\\web.config"" exited with code 4.
Failed exitCode=1, command=dotnet publish "D:\home\site\repository\Cairo.Portal\Cairo.Portal.csproj" --output "D:\local\Temp\8d6e8bf7c33ddc9" --configuration Release
An error has occurred during web site deployment.
If I deploy directly from Visual Studio it works fine, but I am trying to set up the git auto deployment for convenience.
Please advice on what configuration I missed. Thank you
EDIT:
I've found a solution, it's to edit the deploy.cmd script under D:\home\site\deployments\tools\
There the command to publish was
call :ExecuteCmd dotnet publish "%DEPLOYMENT_SOURCE%\Cairo.Portal\Cairo.Portal.csproj" --output "%DEPLOYMENT_TEMP%" --configuration Release
Note that the configuration is fixed to Release thus didn't use the Configuration I set in my Solution Configuration Manager
I added a variable called ASPNETCORE_CONFIGURATION on the Axure webapp Configuration and changed the command in deploy.cmd as below:
call :ExecuteCmd dotnet publish "%DEPLOYMENT_SOURCE%\Cairo.Portal\Cairo.Portal.csproj" --output "%DEPLOYMENT_TEMP%" --configuration %ASPNETCORE_CONFIGURATION%
It works for now, but is there a proper way to make the deploy.cmd to use the solution config setting? instead of having to manually edit it on Kudu.
I have a dotnet core 2.1 web API project with a publish profile to a folder that lately I plan to copy to an IIS as in dotnet publish documentation.
I created the publish profile with VS and the resulting file is
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<PublishProvider>FileSystem</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<ProjectGuid>b3155c62-817f-4eba-8856-e5941137f4ed</ProjectGuid>
<SelfContained>true</SelfContained>
<_IsPortable>false</_IsPortable>
<publishUrl>bin\publish\</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
</Project>
If I run the profile from VS it creates a bin\publish folder that I can copy to IIS.
If I do the same with dotnet publish /p:PublishProfile=FolderProfile (as in the CI server) after updating to latest VS I get the following error
C:\Program Files\dotnet\sdk\2.1.400\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(122,5): error NETSDK1067: Self-contained applications are required to use the application host. Either set SelfContained to false or set UseAppHost to true. [C:\Users\Guillem.Sola\source\repos\ASG.DHW.HealthCheck\ASG.DHW.HealthCheck.API\ASG.DHW.HealthCheck.API.csproj]
I can achieve something similar excuting in cmd
dotnet publish .\HealthCheck.API\HealthCheck.API.csproj -o .\bin\publish -r win-x64 -c Release
What is going on, why the profile is not behaving the same when calling from CLI?
I think that the key to your (updated) issue might be in this part of the error message:
Self-contained applications are required to use the application host. Either set SelfContained to false or set UseAppHost to true.
The difference in behaviors could easily be explained by a number of things, like MSBuild target files brought in by various VS conditions, for example.
Because you don't want to use the AppHost, you'll need to change<SelfContained>true</SelfContained> to <SelfContained>false</SelfContained>. You could also consider adding an explicit <UseAppHost>false</UseAppHost> - that might help mitigate differences between a VS and a CI build.
Turning on/up the MSBuild verbosity is a good way to get more data to help you understand why the operation has the observed results.
I'm new to ASP.NET Core and docker.
I've created a simple ASP.NET Core 2.0 app and try to use docker with it on Windows. However, I get this error:
Your Docker server host is configured for 'Linux', however the docker-compose project targets 'Windows'.
Although it seems to be pretty informative error, I can't find where to 'configure host for Windows'
It is docker-compose.dcproj file where you can set up the OS you want to target:
<DockerTargetOS>Linux</DockerTargetOS>
To switch docker daemon to the same OS you can use Docker tray icon or Docker Settings window (accessible from the same menu):
Well basically the answer of Celestin Bochis and Pavel Agarkov are great. However since .net core 2.2 at least, the os of docker is stored in the .csproj file.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
...
</PropertyGroup>
...
</Project>
And also don't forget to modify your docker file. The images should be the correct one. For .net core 2.2 That is :
Linux:
Microsoft/dotnet:2.2-aspnetcore-runtime AS base
microsoft/dotnet:2.2-sdk AS build
Windows:
microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803
microsoft/dotnet:2.2-sdk-nanoserver-1803
Make sure to choose the correct OS when you Enable docker support:
Your docker daemon has to target Linux containers as well.
If the docker is running on the windows machine then you need to change the value of "DockerTargetOS" should be "Windows" in .dcproj file.
Unload the docker project from visual studio and edit the project and set the value "Windows" to "DockerTargetOS".
<DockerTargetOS>Windows</DockerTargetOS>
I got this error when I created the project to target Windows and later wanted to switch it to target to Linux. The steps are a little bit more involved if you want to use Linux containers instead:
Unload docker-compose, edit the DockerTargetOS to Linux, then reload the project
Go to docker-compose.yml. Make sure that the backslash is a forward slash. Should look like "WebApplication/Dockerfile"
On the Dockerfile, for the base use "microsoft/aspnetcore:2.0" and for build, use "microsoft/aspnetcore-build:2.0" so it should look like this:
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY WebApplication7/WebApplication.csproj WebApplication/
RUN dotnet restore WebApplication/WebApplication.csproj
COPY . .
WORKDIR /src/WebApplication
RUN dotnet build WebApplication.csproj -c Release -o /app
Right click on the Docker tray icon > settings > Shared Drives > pick the drive your project resides in.
I am running a .net core app in a docker container. Here is my docker file (just to build a dev environment):
FROM microsoft/dotnet:1.0.1-sdk-projectjson
ENV ASPNET_ENV Development
COPY bin/Debug/netcoreapp1.0/publish/ /root/
EXPOSE 5000/tcp
ENTRYPOINT dotnet /root/AVP.WebApi.dll
I have an appSettings.Development.json file in the /publish/ folder. If I build and run this Docker file, I end up with a strange issue where the .NET app can't find the appsettings it needs to start (they're in the appSettings.Development.json file).
I have confirmed that from the command line in windows if I run dotnet publish/AVP.WebAPI.dll the app throws the same exceptions for missing configuration settings. However if I cd to /publish and run dotnet AVP.WebAPI.dll the app starts and runs just fine.
Any ideas how to change my docker file so it will run the app properly with the appSettings.Development.json values? (I've also tried to run the app with all the values copied into the regular appSettings.json files with no luck)
I've also tried running a the COPY command to / instead of /root and doing dotnet AVP.WebApi.dll as the entry point, but that results in the project being unable to find dependencies.
Try replacing this line:
ENV ASPNET_ENV Development
With this:
ENV ASPNETCORE_ENVIRONMENT Development
Your original Environment Variable name was used in older .NET Core, but has been changed. It can be a pain finding tutorials, etc. for .NET Core because of all of the changes that have happened since it first started!
Don't get me started on project.json files!
More info:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments
As a follow up to everyone (I posted this is a comment originally), this is what ended up fixing it:
From what I can tell it looks like dotnet expects the appsettings files to be in the same directory it is run from. So I added COPY bin/Debug/netcoreapp1.0/publish/appsettings.json /appsettings.json to the dockerfile (this line copies the appsettings file to the directory below /root/ where I copied the publish folder to). Everything started working at this point. It appears that the dotnet executable runs from the directory below /root/ so it couldn't find it before, now that appsettings is in the same folder, it's all happy.
It late, but i think my solution will help other.
Step 1. Put appseting in folder "Settings/appsettings.json".
Here is my appsettings.json
{
"ConnectionString": "Data Source=local;Initial Catalog=mydb;User Id=username;Password=myStr0ngPassword#;"
}
Step 2. Edit code from asp netcore.
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
namespace Repos.Configs
{
public static class ConfigurationManager
{
public static string currentPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
public static IConfiguration AppSetting { get; }
static ConfigurationManager()
{
AppSetting = new ConfigurationBuilder()
.SetBasePath(currentPath)
.AddJsonFile("Settings/appsettings.json") // your path here
.Build();
}
}
}
And use AppSetting.
var connectionString = ConfigurationManager.AppSetting["ConnectionString"];
Step 3. now u must config your dockerfile, in my case, create by visual studio in linux container.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["Api/Api.csproj", "Api/"]
COPY ["Repos/Repos.csproj", "Repos/"]
COPY ["DataContext/DataContext.csproj", "DataContext/"]
RUN dotnet restore "Api/Api.csproj"
COPY . .
WORKDIR "/src/Api"
RUN dotnet build "Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Api.dll"]
Step 4. Build image.
docker build -t tagForProject .
Step 5. Map volume and run your container from image.
docker run -p 44382:80 --volume c:\Docker\Volumes\MyProjectNetCore:/app/Settings --name nameWillDisplayInDockerDashboard -d tagForProject
OK, one problem here, because docker will override c:\Docker\Volumes\MyProjectNetCore to /app/Settings. So, you must put appseting.json to c:\Docker\Volumes\MyProjectNetCore.
If not, your app cant read appsetting because it not exist in docker volume.
Step 6. Restart your app in docker dashboard and see it work.
There are three problems i can think of why it can't find the appsettings:
They are not in the right folder in the container (did you copy the publish folder and does the publish folder contain the appsetting
You did not define using appsettings for the environment in the StartupClass: appSettings.${Environment}.json
It works locally because windows filesystem is case-insensitive and linux is case sensitive and thus it can't find the file. (check your capitalization).
I use docker-compose with .net 5, I put this on my yaml :
container_name: heroapi
environment:
- ASPNETCORE_ENVIRONMENT=alpha
for use appsettings.alpha.json file and it's work
Just came across this issue myself and the problem was the file is not being copied by default.
This was fixed by editing the .csproj file and adding :
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
This can also be done through UI by right clicking the appsettings file within visual studio, selecting properties and setting sopy to directory to "Always".
My problem was, through all this docker container stuff.. I never built the project in Release Mode, so the appsettings.json file in /bin/release/publish was very old.
I just hit this issue myself, and Sam's answer did solve it. Just to propose a different solution, you can also set the WORKDIR /root directive in the Dockerfile and then use ENTRYPOINT dotnet AVP.WebApi.dll which will call dotnet in the context of the root directory.
Full Dockerfile:
FROM microsoft/dotnet:1.0.1-sdk-projectjson
ENV ASPNET_ENV Development
COPY bin/Debug/netcoreapp1.0/publish/ /root/
WORKDIR /root
EXPOSE 5000/tcp
ENTRYPOINT dotnet AVP.WebApi.dll
for compose:
environment:
- ASPNETCORE_ENVIRONMENT=Production
For Docker:
ENV ASPNETCORE_ENVIRONMENT: "Production"
there is a quick and easy way to Update/edit the AppSettings.json file:
for example my AppSettings.json file :
{
"GrpcOption": {
"ServerAddress": "oldurl"
},
}
now i can modify it by -e command
docker run -e "GrpcOption:ServerAddress=newurl" [imagename]