Sitecore automated deployments with TDS, Web Deploy and Sitecore.Ship

There are quite a few options when it comes to automatically deploying Sitecore to development, test and production environments. In this article I will discuss the pros and cons of a number of options and describe the steps that I have taken to successfully automate Sitecore deployments. These steps should be repeatable on any build or release server. Here's what we're going to do:
Sitecore deployment overview

For those who just want the command lines. Here you go:


  1. Output web deploy package

    MSBuild.exe WebProject\WebProject.csproj /T:Package /P:Configuration=Release;PackageLocation="..\WebDeployPackage\sitecore-files.zip"  
    


  2. Output Sitecore .update package

    MSBuild.exe MySolution.sln /P:Configuration=Release  
    


  3. Deploy Web Deploy package to destination server

    "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:package='sitecore-files.zip' -dest:auto,computerName="https://mysite.cloudapp.net:8172/msdeploy.axd?site=TODO_IIS_SITENAME_HERE",userName="TODO_WEBDEPLOY_USERNAME",password="TODO_WEBDEPLOY_PASSWORD",authtype="Basic",includeAcls="False" -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParam:name="IIS Web Application Name",value="TODO_IIS_SITENAME_HERE" -allowUntrusted -enableRule:DoNotDeleteRule
    


  4. Deploy Sitecore .update package to destination server using Sitecore.Ship

    curl.exe -i --insecure --show-error --silent --form "path=@MyProject.scitems.update" https://mysite.cloudapp.net/services/package/install/fileupload  
    

  5. Build / Packaging

    We need to build our project from source control and create packages which can be used for deploying Sitecore items/templates as well as website binaries and static files.

    TDS

    A prerequisite for having consistent Sitecore builds is to manage all your code, static files (images, css etc.) and Sitecore items/templates in source control. For managing Sitecore items and templates there is really only one industrialised option and that is Hedgehog's Team Development for Sitecore (TDS).

    TDS lets you configure a project in Visual Studio which lets you manage your Sitecore items and templates. It is then able to package these items and templates into a Sitecore .update file which can be created as part of build output and can be "installed" into a Sitecore instance via the Sitecore backend UI (/sitecore/admin/UpdateInstallationWizard.aspx).

    Sitecore Update Installation Wizard

    TDS also provides the ability to package code and static files which can be deployed to a Sitecore instance via this same mechanism. Unfortunately the deployment of code and static files via Sitecore .update files has one fatal flaw – it cannot update web.config. This is a limitation of Sitecore, not TDS. Sitecore is unable to update the web.config of its own process.

    Below is an example configuration of TDS which chooses to have separate update packages for files and templates. This is because we are going to discard the code/file package and instead do this part of the deployment with Microsoft Web Deploy.

    TDS Disable File Deployment and Sitecore Connector

    TDS Generate separate code and item packages

    The following is a standard MSBuild command line which would cause the creation of the above update files:

    MSBuild.exe MySolution.sln /P:Configuration=Release  
    

    Microsoft Web Deploy

    For the deployment of code and static files I have chosen to use Microsoft Web Deploy. Web Deploy is an incredibly flexible tool that, among other things, can be used to deploy websites to a remote IIS server. Web Deploy has both a command-line client (msdeploy.exe) as well as PowerShell extensions.

    Before we can deploy our code and static files we need to package it up so that it can be deployed consistently between environments. This can be done directly from an MSBuild command line.

    MSBuild.exe WebProject\WebProject.csproj /T:Package /P:Configuration=Release;PackageLocation="..\WebDeployPackage\sitecore-files.zip"  
    

    Deployment

    We now have two packages for installation to our target Environment:

    • Web Deploy Package (.zip) – Binaries and Static Files
    • Sitecore package (.update) – Sitecore Items and Templates

    Deploying the Web Deploy Package

    First you will need to install Web Deploy on the source server (potentially the build/release server) and the destination server (IIS server). This is a blog post in itself. There are many other references for this.

    Assuming you have correctly configured Web Deploy security permissions for the destination site you can then perform deployment with the following command line:

    "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:package='sitecore-files.zip' -dest:auto,computerName="https://mysite.cloudapp.net:8172/msdeploy.axd?site=TODO_IIS_SITENAME_HERE",userName="TODO_WEBDEPLOY_USERNAME",password="TODO_WEBDEPLOY_PASSWORD",authtype="Basic",includeAcls="False" -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParam:name="IIS Web Application Name",value="TODO_IIS_SITENAME_HERE" -allowUntrusted -enableRule:DoNotDeleteRule
    

    A key thing to note about this command line is the addition of the DoNotDelete rule. This is critical as otherwise Web Deploy will delete any file on the destination which isn't part of the Web Deploy package. This would include all of the Sitecore binaries and other files installed as part of the Sitecore installation!

    Deploying the Sitecore .update package

    As I mentioned earlier, these packages can be manually deployed using the Sitecore Update Installation Wizard page (/sitecore/admin/UpdateInstallationWizard.aspx). Unfortunately Sitecore do not provide an out of the box mechanism for doing this automatically from a remote server.

    Included with TDS is a command-line application which is able to install .update packages to a remote server. It does this by temporarily installing a "backdoor" upload page which it uses to upload the package. Unfortunately for it to be able to do this it requires write access to the web application's folder which is specified as a UNC path. This is difficult to secure and is not possible when the destination server is on a remote network or is cloud based.

    The community has developed a number of approaches here which usually all involve creating a special "upload" page or service on the server. I chose a great one called Sitecore.Ship which exposes a number of REST endpoints on the target server. These services let you perform a number of Sitecore operations including .update package installation. Sitecore.Ship is conveniently available as a NuGet package.

    Once you have Sitecore.Ship as part of your Visual Studio solution, and you have deployed it to the destination server, you are able to deploy the Sitecore .update package with simple web requests. I tried (and failed) to make this work with PowerShell so I instead reverted to using the curl command-line tool.

    Here is the command line to deploy a Sitecore .update package with curl:

    curl.exe -i --insecure --show-error --silent --form "path=@MyProject.scitems.update" https://mysite.cloudapp.net/services/package/install/fileupload  
    

    You will see that it takes the .update package file path and sends it to the Sitecore.Ship endpoint. Be sure to secure these endpoints.

    Conclusion

    Sitecore give you a lot of options but not really a lot of guidance when it comes to automated deployment. I believe the methods described in this post provide a lot of flexibility and should be suitable in many situations.

comments powered by Disqus