When thinking about Continuous Integration and Continuous Delivery for Sitefinity CMS, we should think of those processes as the standard ones that are applied to ASP.NET applications.
First we choose the environment—single server, multiple servers with load balancer, Azure or Amazon. In order to automate the delivery process and eliminate manual work for Sitefinity CMS, we need to know the specifics of the product and how to manage projects between environments.
Here are the main aspects of Sitefinity applications that we should focus our attention on when it comes to the continuous delivery process:
- Custom code implementations—widgets, templates and etc.
- Back-end structures—dynamic modules, custom fields for built in modules, taxonomies, sites and web services
- Environment and application configurations
For all of the above, we apply individual approaches when we sync between different environments. Let’s take a closer look at each of them and the main flows that we should follow during continuous delivery.
The foundation of each continuous delivery procedure is based on a specific flow.
If we simplify the above it looks like this:
It is important to note that only the code implementations and configurations are going from dev to live. The only thing that comes from production is the Database.
Continuous Delivery Flow Across Multiple Environments
Before we deploy something on our live servers we need to go through many testing environments to make sure that everything is working well and all our tests are passed. Here is a flow chart from a real world scenario from the telerik.com web site.
In some cases we have only one test environment but it always depends.
For small websites, a single server is enough to handle the load. For the rest of the scenarios where we need to handle large amounts of traffic, scalability is necessary.
Private Services/Virtual Machines
To handle traffic and load, we need to distribute it to many machines and use a load balancer.
One of the most popular, simplest and widely used techniques for distribution is round-robin. Progress adopted this approach for the telerik.com web site. In order to avoid complex updating between nodes, we need our configurations to be split between DB and config files. With Sitefinity 9.2, its auto mode of storage configuration property automatically solves this.
When it comes to the cloud, we always think about scalability and availability. The good news is that Sitefinity fully supports deployment in the cloud without any issues. Before we decide which platform to use we need to be very well informed about our case. We can find a good comparison table between Azure and Amazon that can help us to make the better informed choice here.
With Azure we have two options—a virtual machine and app services. Some guides on the web conclude that App Services are the preferred option in many cases. You can find our internal guide how to deploy your Sitefinity application to Azure here.
With Amazon we need to create a virtual server and host our application on it. You can find our internal guide how to deploy your Sitefinity application to Amazon here.
Continuous Delivery with Sitefinity CMS
All of the code implementations and configurations should come from the Dev environment to Production with the help of the source control and builds. The only thing that is opposite to that workflow is getting the Database from Production/Test and adding it to Dev. If we follow those two major rules there shouldn’t be any caveats or issues.
The flow here is pretty straightforward. When we check-in to the source control, a build is triggered and all of our tests are executed against the new code base. If all of the tests pass, we can promote the new version to the UAT and Production servers. Here is an example of what the delivery pipeline could look like.
For back-end structures we should consider dynamic modules, custom fields for built-in modules, taxonomies, sites and web services. With version 9.2, Sitefinity delivers functionality that helps us to export all of those types and import them easily. Keep in mind that only the structures are exported, not the content.
To import them we need to add the folder into our application and check it into the source control. When the website is started in the new environment, it automatically imports everything.
One of the most common use cases that this feature solves is when we add a dynamic field to an existing type and we want to have it in our production environment. Until now, the process included a lot of manual work and potential for failure because we would create it in the Dev environment as well as the other environments in our pipeline.
Here is an example of how the above procedure should be executed:
- Go to “Export for deployment” and click the “Export” button. A folder with all of the exported structures is created in your project. If you are curious check the path from the screenshot.
- Add that folder to your source control and check-in everything.
- The next step is to import those structures into the project that are in production. Since we checked-in everything to the source control, all of the new structures will be automatically created by Sitefinity when we deploy our new package. This happens when the site starts for the first time.
- To see and access all of the new dynamic content modules in the back-end for multi-site scenarios, we use the modules configuration of the website and associate those modules to our application. All of this is done manually.
If we want all of the synchronization to be automatically applied to our particular website without any manual work, we should enable “Configure by default”. The system will then apply everything in our project and all of the dynamic content types will be visible when the site starts for the first time after a new version is deployed.
To have the same content through different environments, we need to use SiteSync. With this feature we can instantly sync content or schedule it for a particular date. In terms of continuous delivery, we are covered with the option to schedule our syncs (e.g. every day at 5:00 am).
Environment and Application Configurations
Before we discuss how to sync environment and application configurations, we need to define them.
For the environment configurations we need to have different values throughout different development environments. Also we don’t want to change them in the back-end. The best way is to have different config files between the environments and change their values with the help of transformations. Those settings should be kept in the config files of the system.
The application configurations are settings that are changed during runtime and should be kept in the database. That separation is needed in order to avoid cases where the config files are updated with the latest version and all of the configurations made during runtime are wiped out.
In addition, this keeps the continuous delivery process more straightforward and, in load balancing scenarios, we avoid any complications by having the same environment configuration across all nodes—only the application settings are shared in the DB. This way the update of every single node is easy and the downtime is minimized.
It’s really easy to achieve this since the system will take care of which settings should be in the DB or in the file system if you simply set the configuration storage mode to Auto.
In order to be certain that no one is can change the configuration settings in the back-end system, we should set the configuration mode to “read-only.” This is the recommended option for each Test/Live environment so that we can be sure that environment modifications will be done only by developers in specific config files.
With the latest release of Sitefinity, all of the necessary functionality to fully cover the continuous delivery process are now available. The first step is to identify your scenario and how many environments you need. Then you can follow the complete guidelines from the documentation and avoid all of the manual work.