Deploying DotNet Core app on IIS
How to setup your environment, TFS agent and run the deploy
Update: I’ve also blogged about building with TFS agents here.
In the past few days I’ve been working on deploying a Dot Net Core app on IIS (7.5) via an on-premise Team Foundation Sever 2018. This article is a summary and a step-by-step guide for deployment. The assumptions is that there is a build artifact published by a successful build.
Prerequisites
- Windows machine (or VM) with IIS ≥ 7.5
- ASP Net Core Hosting bundle
- PowerShell 3.0 required for agent
- Dotnet 4.5 required for agent
Note: TFS and VSTS and Azure Dev Ops are all the same product and the documentation is the same. I’ll mention TFS and that’s because I worked on premise. The same should apply one-to-one for the cloud version of TFS — Azure Dev Ops (formerly known as VSTS -Visual Studio Team Services and VSO — Visual Studio Online)
Install TFS agent
The agent will do the TFS build server’s bidding on our deployment machine(s). When installing it there is a catch that I want to mention: Adding the agent in TFS server’s agent pool requires one set of permissions 1) and the running agent requires another set of permissions 2).
1. We need a user that has permissions to add an agent to an agent pool ON TFS server.
2. The agent needs all the security permissions for its operations — i.e. stop app pool, copy or delete files in app folder etc.
Details here.
For example:
config --unattended --url https://tfshostserver ^
--auth pat --token gafx2geyfd6ypfipx3uttopklhc52iwncxywkkndkne5wyux6zaa ^
--pool Release --agent DevDeploy1 ^
--acceptTeeEula --runAsService ^
--windowsLogonAccount DeployAgentUser --windowsLogonPassword Depl0yAg3ntUserP4$$word @ the symbol ^ is just continuing the command to next row
The part --auth pat --token gafx2geyfd6ypfipx3uttopklhc52iwncxywkkndkne5wyux6zaa
can be “translated” I’ll be authorizing as a TFS user with a this token (pat — personal access token) and I have permissions to add this agent on the server — — url https://tfshostserver
.
And then the part --windowsLogonAccount DeployAgentUser --windowsLogonPassword Depl0yAg3ntUserP4$$word
concerns the windows user that will do the actual deployment — app pool management, files deleting copying etc. Test permissions by %SYSTEMROOT%\System32\inetsrv\appcmd recycle appPool DefaultAppPool
expect to see “DefaultAppPool” successfully recycled.
Create an IIS App
For example MyApp - with the appPool having the same name. When using the GUI to create an app IIS Manager will provision an application pool and a windows user running the app "IIS AppPool\MyApp". This is a kind of a shortcut user that allows for running applications without the need to manually add user for each one separately. This user is also part of the group IIS_IUSRS. Details here. App user (IIS AppPool\MyApp) needs to have write permissions on app\logs folder - in there it would keep its logs should the web.config stdoutLogEnabled
be enabled (disabled by default - see web.config)
Deployment steps
- Create a release with the empty template
- Add Command line tasks to:
- stop the app pool
%SYSTEMROOT%\System32\inetsrv\appcmd stop appPool $(appName)
I strongly recommend using variables for app’s name, deployment folder, configuration folder etc. makes it that much easier to maintain the release.
- copy the artifacts from build to the app folder
xcopy /E/Y $(artifactsFolder) $(appFolder)
/E will copy subdirectories and /Y will confirm overwrite - copy over the configuration — it seems a good idea to keep configuration specific for each deployment rather than use the developer machine appsettings.json
xcopy /Y $(configFolder) $(appFolder)
- start the app pool at the end of every deploy. Even on failed deployments. That’s required because
Appcmd stop apppool ..
fails if the AppPool is already stopped and will break all subsequent deploys - Done
The predefined variables are listed here: https://docs.microsoft.com/en-us/azure/devops/pipelines/release/variables?view=vsts&tabs=batch. Alternatively you can add a command line task : cmd set
which will list the environment variables specific for the deployment machine.
Debug
There are 2 approaches for showing logs if our app needs to be debugged:
1. Run dotnet app.dll
and read through the console log
2. Edit web.config to stdoutLogEnabled=”true”
and allow the app user to write in \logs folder of the app
2.1. App user (IIS AppPool\MyApp) needs to have write permissions on app\logs folder and that folder needs to have been created — not created automatically
2.2. Restart the app pool in order for the config changes to take effect: %SYSTEMROOT%\System32\inetsrv\appcmd recycle appPool myApp