Tag: Devops

Moving the Media Cache folder in Sitecore

One of the cache’s that Sitecore has is the Media Cache. Whenever you use an image from Sitecore’s media library, Sitecore will retrieve the image from the database, scale it to the size you requested and then store it to disk in the media cache folder. On any subsequent request the image will now be retrieved from the media cache rather than the database.

By default each content management and content delivery server will locate the media cache in /App_Data/MediaCache

This is a relatively logical place to store a cache for images that wont cause you many issues. However, if you have automated deployments setup then you are likely wiping the whole of your website folder each time you do a deploy to ensure that your deploy remains the same on all environments. As the App_Data folder is in the website, your Media Cache will be deleted too.

Depending on your site then deleting the media cache potentially isn’t much of an issue. After all it’s a cache so all that will happen is the images will get cached the next time they are requested. But depending how many images get retrieved at the same time this could slow down performance, particularly if your content editors decided to put every image they ever uploaded into the same folder. Opening the that folder in the admin will create a nice amount of load on your server, particularly if you also have some extra image optimization logic installed.

Like most things in Sitecore though, you can change the location through a config setting.

In Sitecore.config you will find a property called Media.CacheFolder. Change this to somewhere outside of your website folder and Sitecore will now start storing the Media Cache in this location and it will be safe your all your deploys.

<!--  MEDIA - CACHE FOLDER
          The folder under which media files are cached by the system.
          Default value: /App_Data/MediaCache
    -->
  <setting name="Media.CacheFolder" value="/App_Data/MediaCache"/>

Azure devops and custom NuGet feeds

If your setting up a CI pipleline on Azure Devops for a site which uses a NuGet feed from a source that isn't on nuget.org you may see the error:

"The nuget command failed with exit code(1) and error(Errors in packages.config projects Unable to find version..."

On your local dev machine you will have added extra an extra NuGet feed source through visual studio which will update a global file on you machine. However as Azure Pipelines is a serverless solution you don't have the same global file to update to include the sources.

Instead of this you need to add a NuGet.config file to the root of your repository.

Here is an example of one set to include Sitecores NuGet package feed.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
  <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  <add key="Sitecore NuGet v2 Feed" value="https://sitecore.myget.org/F/sc-packages/" />    
</packageSources>
</configuration>

Next you will need to update your pipeline to tell the NuGet step to use this config file

- task: NuGetCommand@2
inputs:
  restoreSolution: &#39;$(solution)&#39;
  feedsToUse: &#39;config&#39;
  nugetConfigPath: &#39;NuGet.config&#39;

And that's it. As long as all the sources are correct the NuGet command should now find your packages.

Bundling with Gulp in TeamCity

Like most, our front end developers write CSS in LESS or SASS and then use Gulp to compile the result. This is great but up until recently both the compiled and source style files would end up in our source control repository.

While this isn't a major issue it was more of an annoyance factor when doing a merge that the compiled file would need to be merged as well as the source files. Any conflicts in bundled/minified files also can become problematic to solve. As well as this it also just seems wrong to have both files in a repo, effectively duplicating the file. After all we wouldn't put compiled dll's into a repo with their source.

Our solution was to get the build server to start running the gulp tasks to produce the bundled files.

Step 1 - Install Node on the build server

To start we need NodeJS installed on the build server. This allows extensions to be installed via NPM (Node Package Manager), it's a similar thing to NuGet,

Step 2 - Install the TeamCity plugin for NodeJS

To add built steps for Node and Gulp we need to install a plugin to make them available. Lucking there is one that does such a thing here https://github.com/jonnyzzz/TeamCity.Node

The actual build of the plugin you can download from Jetbrains team city here https://teamcity.jetbrains.com/viewType.html?buildTypeId=bt434. Just login as guest and then download the latest zip from the artifacts of the last build.

To install the plug you need to copy the zip to Team City's plugin folder. For me this was C:\ProgramData\JetBrains\TeamCity\plugins, if your having trouble finding your's just go to Administration > Global Settings in Team City and it will tell you the data directory. The plugin folder will be in there.

Restart the TeamCity server and the plugin should now show under Administration > Plugins List

Step 3 - Add a NPM Setup build step

The NPM step with a command of install will pick up dependencies and get the files.

Step 4 - Add a Gulp build step

 

In your gulp step add the path to the gulp file and the tasks in your gulp file that need to be run. I'm using a gulp file that our front end devs had already created for the solution that contained as task for bundling css and another for bundling js.

Step 5 - Including bundled files in a MSBuild

As the bundled files are no longer included in our Visual Studio solution it also means that they arn't included in the set of files which will be included in a publish when MSBuild runs.

To overcome this update the .csproj file with a Target with BeforeTargets set to BeforeBuild and list your bundled files as content. In my example I'm included the whole Content\bundles folder

<Target Name="BundlesBeforeBuild" BeforeTargets="BeforeBuild"> 
<ItemGroup> 
<Content Include="Content\bundles\**" /> 
</ItemGroup> 
</Target&gt;