How do I deploy my app to a folder underneath a website - iis

I have a deployment script to deploy an application to a website called admintools3t. After the deployment, I see the folders for the app directly underneath that website (when viewed in IIS). The code is deployed to the folder D:\applications\admintools\admintools_wwwroot\myapp1, which is where I (think?) want the code. However, my website is the generic site that needs to host multiple applications, myapp1, myapp2, myapp3, myapp4.
Here is the call I make to use msdeploy to perform the deployment:
call D:\temp\AdminTools\%APP%\%APP%.deploy.cmd /Y "-setParam:name='IIS Web Application Name',value='admintools3t'"
I'm doing this on-the-fly switch on the value because I have multiple environments where I will be deploying to and rather than having multiple profiles, I do this on-the-fly switch, which appears to be working.
How can I tweak this command or add additional parameters so when I view the website in IIS that I see a myapp1 underneath admintools3t?

Related

Deploy Client Web Part globally using SPFx on SharePoint 2016 (On Prem)

I have succedeed in deploying a simple client web part on a SharePoint 2016 site with the following steps (following many guides, including https://www.voitanos.io/blog/definitive-guide-sharepoint-framework-sharepoint-server-2016/):
I configured the required Service applications (subscription and app management) and managed the blocked file types.
I created an App Catalog site for my Web Application.
I wrote two urls in "Central Administration -> Apps -> Configure App URLs" (it seems that it doesn't matter what URLs I write, the important thing is that they are not empty or I can't add the App to my sites).
I set up my CDN by creating a Document Library and a folder. I specified this location in the write-manifest.json -> "cdnBasePath".
I uploaded the sppkg (output of gulp package-solution --ship) to the App Catalog and it got distributed succesfully.
I went to the root web of the site collection I was working on and added the App.
I created a web part page with an empty web part zone and.
I succesfully added the client web part that was in the default "Other" group, and it rendered fine in the page.
Until here everything is fine. There was some tweaking to do with yeoman, gulp and node versions, but it works.
The problem is that if I add the app to the site root web, the web part is not available to the other webs, since from what I read, if I add an app that way the scope is only that web. In order to make the web part available on other webs, I would have to go to every web and add the app there. This could be fine if I had 2 or 3 webs, but what if I have 1000 webs?
I also read that if you add the app to the App Catalog Site, the scope should be "tenant", and you can then choose where to distribute the app so that it's added for all webs from this page:
https://i.stack.imgur.com/MAX8K.png
If I add the target site here, and the press "OK", an exception occurs:
Exception in page: https://i.stack.imgur.com/S8cl1.png
Exception in log: https://i.stack.imgur.com/K2GMB.png
I tried debuggingg the Microsoft.SharePoint.ApplicationPages.AppInvPage.SetControlStateUsingAppInstanceId method with dotpeek and I think I was able to identify the problem with the AppManifest object, that seems to have some null fields that on which gets called a "ToString", but wasn't able to pinpoint the exact problem yet.
So I thought I could maybe write some PowerShell script to add the App to all subsites, but it seems the method require some parameters that somehow don't seem right. For example, Install-SPApp requires a SPApp object that is obtained with Import-SPAppPackage. Even if I manage to launch the command with the .sppkg file stream, when you launch Install-SPApp an exception occurs: "Install-SPApp : Value cannot be null.".
Honestly I'm running out of ideas.
TL;DR: Has anyone had issues with SharePoint 2016 and globally deployed client web parts? Is it possible to automatically add the app containing one or more client web parts to all subsite on SharePoint 2016?

How to structure code to have 2 web apps deployed to the same Azure App Service

I am starting a new project (let's call it MyWebProject) which will have
MyWebProject: a front-end app with AspNet Core serving a SPA with Angular2
MyWebProjectAPI: a back-end app with AspNet Core connected to a DB and exposing RESTful API
They don't have inter dependencies since MyWebProject access MyWebProjectAPI through http requests only. So we could say they are independent.
I have a single domain www.mywebproject.com linked to a single Azure App Service mywebproject.azurewebsites.net and I want to have both projects (front-end and RESTful API) deployed under the same Azure App.
If I access with a web browser www.mywebproject.com I want to access the front-end. I don't mind where the RESTful API is deployed (I'm guessing in a virtual directory under the same App Service IIS?)
I am also planning to have continuous deployment where pushing changes to a master branch in a Git repository would trigger a new deployment (ideally both deployments are configured separately but I don't mind that much)
The question is:
How to structure my solution/projects and what approach should I follow?
I am considering One single solution with the 2 main projects (front-end and back-end) plus library projects required by the back-end project, and therefore I am assuming they all would have to be in the same Git repository?. Would that be a problem? or is it better to have them in separate Git repositories and separate solutions? (this option would also be ok)
What would be the approach to follow when deploying into the same Azure App service? To use a virtual directory because they both are web projects (both have a wwwroot)?
Another option could be one single project for both RESTful API and front-end with one of the controllers simply serving the SPA and the other controllers acting as the API resources. This would certainly simplify everything, but somehow I wanted to have both projects independent.
Any reference, article or opinion would be appreciated.
I work with an app where we have one solution that two different Web Projects, both living at the same domain and both being deployed using continuous deployment. It works out fine. Here is how it works:
Have one Visual Studio Solution
Under that solution have the two web projects
In the Azure Application settings for your App Service, scroll to the bottom under "Virtual applications and directories" and set up a Virtual Directory for MyWebProjectAPI. Virtual directory would be "/MyWebProjectAPI" and Physical path would be "site\wwwroot\MyWebProjectAPI"
Create the deploy.cmd for doing the continuous deployment in the solution folder, just like normal
Edit the deploy.cmd to also deploy the second web project.
You'll find a line for the first project that looks like:
call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\MyWebProject\MyWebProject.csproj" /nologo /verbosity:m /t:Build /t:pipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempDir="%DEPLOYMENT_TEMP%";AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release /p:SolutionDir="%DEPLOYMENT_SOURCE%\.\\"
IF !ERRORLEVEL! NEQ 0 goto error
Copy that code and update it to build the API project into the virtual directory (notice the first path changed as well as the PackageTempDir):
call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\MyWebProjectAPI\MyWebProjectAPI.csproj" /nologo /verbosity:m /t:Build /t:pipelinePreDeployCopyAllFilesToOneFolder /p:_PackageTempDir="%DEPLOYMENT_TEMP%\MyWebProjectAPI";AutoParameterizationWebConfigConnectionStrings=false;Configuration=Release /p:SolutionDir="%DEPLOYMENT_SOURCE%\.\\"
IF !ERRORLEVEL! NEQ 0 goto error
After you deploy, your front end will be at www.mywebproject.com and the api will be at www.mywebproject.com/mywebprojectapi (of course you can rename everything).
Is this the right way to go? There are pros and cons. In our case we needed to do it this way because the 2nd Web Project came from a third party and had to live at the same domain. And that's a big pro - you avoid any possible cross domain issues. Also you have a lot of consolidation with only one DNS entry to worry about (including SSL certificates) and only one App Service to pay attention to.
I could argue, though, that it would be better to let your code run in two apps to get more distinct monitoring and scalability. You said you only want one App Service right now, so either way you don't get the ability to scale. But if you set up two projects as different apps, you could eventually move them to separate App Services later if you needed to scale one and not the other.
If you did want two separate apps with different DNS entries, you could still have just one solution file. I don't have an exact example of doing this, but you would have both apps monitor that branch. So a build would kick off in both apps when you pushed. But you would add a setting in your Azure Application Settings saying which project should be built, and you'd modify your deploy.cmd file to look for this parameter to build the right one.

How to restart a dnx website in production?

I updated a ASP.NET CORE/ASP.NET 5 RC1 controller cs file with a programming change.
The site has previously been deployed on production on IIS7.5 Windows 2012 Server which makes use of HTTPPlatformHandler installed in IIS.
This is a remote server I have to access via VPN.
The site is setup as an application in IIS and the folder points to the wwwroot directory of the deployed site.
I deploy it currently by deploying it first locally by right clicking on my project in Visual Studio 2015 and selecting publish to local folder. I then copy the contents of the local folder to the remote network IIS7.5 web server site folder.
If I copy for example the appsettings.json or a changed .cs file to the server, the change will not reflect.
If I copy the whole site to the production server I get folders and files in use messages. I have to kill the 'dnx' process in order to copy without getting these messages.
From my understanding if I kill the process dnx it will force a recompile. This is currently the only way I know of to restart the site after updating it but I imagine it is not the best way.
What is the standard practice to restart your website after you update your production sites that run ASP.NET5 RC1?
Also changing my app.settings json file aslo doesn't trigger a site reload like changing the web.config did in ASP.NET 4 so being able to restart a site is important.
If I have multiple sites on the same app pool and I only want to update one in production. How can I only restart the one site to reflect the latest changes?
Is it possibly to restart the website to reflect the change as updating it directly doesn't cause a recompile taking into consideration if I only have access to a shared folder and not the web server itself?
With IISPlatformHandler, DNX process is started by IIS (instructions are in wwwroot\web.config).
IIS knows nothing about your source files, all requests are forwarded to DNX.
DNX does NOT watch source files for changes, because there is no dnx-watch there.
IIS only watches for wwwroot\web.config file changes, so you need to change/edit/touch it to force IIS to restart website (and DNX process).
I use msdeploy to deploy, it has commands to stop and start app pools, using these commands has resolved my file in use errors. There are lots of ways to use msdeploy, below is how I happen to be using it.
msdeploy -verb:sync -source:recycleApp -dest:recycleApp="site/pool",recycleMode="StopAppPool",computername=COMPUTERNAME
msdeploy -source:contentPath='SOURCE PATH' -dest:contentPath='\\COMPUTERNAME\wwwroot\' -verb:sync -retryAttempts:2 -disablerule:BackupRule
msdeploy -verb:sync -source:recycleApp -dest:recycleApp="site/pool",recycleMode="StartAppPool",computername=COMPUTERNAME

Creating Web-Site and Web Application in IIS

Till date, I was thinking that we always create/host web-site in IIS.
But I was going through powershell tutorial today which says it is different to create web-site and a web application.
This is the tutorial link (check different section on creating web site and application) -
http://learn.iis.net/page.aspx/433/powershell-snap-in-creating-web-sites-web-applications-virtual-directories-and-application-pools/
Can please guide what is the difference between the two.
Any example will be really helpful.
Thank you!
A web site in IIS is the top level under Sites. The default one that is normally automatically created for you when installing IIS is named "Default Web Site".
This is the "root" that runs on port 80.
Under that, you can create virtual directories, which is basically sub-levels under the root web site, or you can create separate web applications that lives as separate applications under the root level.
A web application must live under a web site.
It is possible to create other web sites that can either be set up to run on other ports (i.e. 81), or to be named with a different host name which enables multiple sites to run on same port number. If named with a different host name, this name must be registered in a DNS server somewere to point to the IP address for your server. A workaround is also to to add it as an entry in the hosts file on the client computer that should access it.
This is example on how it looks in IIS Manager:
I have a script I use when creating a website and AppPool in IIS 7+, .net4, Integrated pipeline and thought you might find it useful.
Use it as so:
CreateSite.ps1 [WebsiteName] [AppPoolName] [Port] [Path]
If you are reinstalling the site, you will need to Stop it first. That is done as so:
StopSite.ps1 [WebsiteName] [AppPoolName]
you can grab the scripts from my gist
Update I have added/extended the scripts and put them in their own Github repository
Here is my CreateWebsite PowerShell script: http://www.zerrouki.com/create-website/

Setting Up Kudu On IIS

A couple of days ago, Microsoft released the engine they're using to do git deployments to Azure. I've had a task on my TODO list for a while to get that kind of functionality set up on my DEV IIS server, so I'm interested in trying out Kudu for that purpose.
The "Getting Started" document shows how to run the web front-end, but everything in there uses "http://localhost:PORTNUMBER" type URL's for git repositories, site URL's, etc.
I realize this is probably getting too far ahead of them, but I'm wondering if anyone has pointers for how to set it up using real domains on "regular" IIS instead of all of the localhost bits?
This is an old question, so I'm giving an updated answer with more current info since I just worked through setting up Kudu on an internal deployment server. The currently selected answer only deals with if you are directly running Kudu from within a development environment.
If you are deploying to a "production" type environment and don't want to install Visual Studio on the target server, there is a good guide on the project website on github.
https://github.com/projectkudu/kudu/wiki/Deploying-to-a-server
On the target server, you will need to install:
MSBuild ( http://go.microsoft.com/fwlink/?LinkId=309745 ) - comes with Visual Studio
NodeJS ( http://nodejs.org )
Git ( http://git-scm.com/downloads )
Back on your development machine, clone the git repo and build using the "build.cmd" file, following instructions in the above link.
In running build.cmd I got several test failures which blocked the build from producing artifacts. These were all related to Mercurial, which we don't use. Installing a Mercurial client didn't make them magically go away, so I disabled the tests rather than sink a bunch of time into debugging my environment.
Your build output will indicate the failures. I disabled by commenting out the [Fact] attribute.
These are the tests I disabled:
tests/Kudu.Core.Test/HgRepositoryFacts.cs (all tests)
Once you have a successful build that has created all the items in the artifacts you can move to deploying the Kudu website and web service code. The below instructions are for setting up a distinct web application instance, rather than dumping everything in c:\inetpub\wwwroot, which is how the instructions read.
Copy "artifacts\Release\KuduWeb" to the target area on the server where your website will run from. I run my kudu install with a separate host header, but you could as easily use a separate port or run as the root website. This directory will be the root for your web application.
Create an empty "App_Data" folder immediately under the KuduWeb folder.
Copy "artifacts\Release\SiteExtensions\Kudu" to the same level as the folder in step 1 and rename to "Kudu.Services.Web". This location is set as a relative path in the KuduWeb web.config file - setting serviceSitePath.
Open IIS Admin and create a website pointing to the "KuduWeb" folder from step 1.
Configure the app pool from step 4 to run as "LocalSystem". This is required to manage IIS Sites.
Create a new folder "apps" at the same level as KuduWeb. This is where deployments will be sent. Note: this location is controlled in the KuduWeb web.config file - setting "sitesPath"
Change filesystem permissions to grant "Users" full access to the "apps" folder created in the above step.
On starting my Kudu website, I got the following error.
Parser Error Message: Could not load file or assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
For some reason it didn't copy the appropriate MVC version into the deployment artifacts.
If you hit this error, the MVC 5 file can be obtained via NuGet. I found that my source code was built against 5.1.0, so this is the appropriate link:
https://www.nuget.org/packages/Microsoft.AspNet.Mvc/5.1.0
In order to extract the dll, I set up a new dummy project and used NuGet to pull down the dll via the package manager console.
Install-Package Microsoft.AspNet.Mvc -Version 5.1.0
Once you get the binary, copy it from package directory ( .\packages\Microsoft.AspNet.Mvc.5.1.0\lib\net45\System.Web.Mvc.dll ) to the website bin directory on the target machine.
At this point you are up and running. Use the web interface to create your application. It will create a subfolder under the "apps" directory with a tree that should be self explanatory. It will also have created two new websites for your application:
kudu_{your-app-name}
kudu_service_{your-app-name}
In a production situation, you should create an additional website running on appropriate port/host header that points to: .\apps\\site\wwwroot
Now you can add a git remote for your deployment. Go to your source location in a git console (ex: Git Bash) and add the remote as identified by Kudu. Note: you may need to change localhost in the url to be the appropriate server name.
git remote add deploy http://:52711/your-app-name.git
Push your code to the new "deploy" remote and see what happens. You should see all the normal push messages, plus the build output.
git push deploy master
My initial push failed to build and deploy due to "node" not being recognized. It was in the path, so a server reset convinced the path environment variable to be refreshed. You may find additional errors to work through. For instance, I had an issue with MSBuild being imported and causing a hiccup.
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\Visual Studio\v11.0\WebApplications\Microsoft.WebApplication.targets" was not found.
YMMV, but these are all solvable problems now. Good continuous deploying!
The project automatically sets up two websites on IIS for each application you add using the web front end. Kudu doesn't automatically map the bindings for them but it's relatively easy to open IIS and find the two sites named "kudu_appname" and "kudu_appname_service". The service website is the one that you point GIT too and the other one is the site itself. Just add public bindings to them by right-clicking and "edit bindings". You can then add public hostnames to them.
This is the easy part. The hard part that I'm still working on is getting authentication working so any random Joe isn't able to push to my kudu repository!

Resources