Views: 6519
Number of votes: 5
Average rating:

Setup EPiServer Search in a future safe and stable way

In almost every project I have done where I have the solution in a load balanced way I have had problem with EPiServer Search. Now I have figured out a way to set it up so the problems are nearly gone. This is also the way you must set it up if you would like to move your solution to Microsoft Azure.

Develop environment

I start out this example by creating a new Alloy project with the extension inside Visual Studio. That gives me a MVC project with EPiServer Search that are setup and will work if I press F5. I have now a solution that looks like this:

Image basic.png

Inside web.config EPiServer Search are configured like this:

  <episerver.search active="true">
    <namedIndexingServices defaultService="serviceName">
      <services>
        <add name="serviceName" baseUri="http://localhost:27565/IndexingService/IndexingService.svc" accessKey="local" />
      </services>
    </namedIndexingServices>
    <searchResultFilter defaultInclude="true">
      <providers />
    </searchResultFilter>
  </episerver.search>
 <episerver.search.indexingservice>
    <clients>
      <add name="local" description="local" allowLocal="true" readonly="false" />
    </clients>
    <namedIndexes defaultIndex="default">
      <indexes>
        <add name="default" directoryPath="[appDataPath]\Index" readonly="false" />
      </indexes>
    </namedIndexes>
  </episerver.search.indexingservice>

This is the basic way of configure EPiServer Search and it will work for small projects that are not in a load balanced environment or on Microsoft Azure. The problem with having this configuration in production in a load balanced environment is that if you put the index files on a common drive and let all the websites index then the index files will be corrupt. You can solve this by setting only one of the sites to do the index and that usually works, but I have had times when it fails because of for example problems with routing and so on.

The solution is to create another project inside your solution and when you create it be careful to not get to much example code in it. It should look something like this:

Image Setup1.png

Image setup2.png

As you can see in the images, I create a empty site with no folders and core reference to anything. I do not create a test project to it and does not host it in the cloud (even if that would be possible)

After doing that I add the EPiServer Search nuget package to the new site and remove that package from the regular web site. I also add a App_data folder to the new site, so I have somewhere to save the indexing files. The solution then looks like this:

Image Setup3.png

Now to get it to work we need to do a couple of things. We start by locating these lines in the regular web site and remove them (the nuget package are great at adding stuff but not removing them).

<section name="episerver.search.indexingservice" type="EPiServer.Search.IndexingService.Configuration.IndexingServiceSection, EPiServer.Search.IndexingService" />

      <dependentAssembly>
        <assemblyIdentity name="EPiServer.Search.IndexingService" publicKeyToken="8fe83dea738b45b7" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-7.7.1.0" newVersion="7.7.1.0" />
      </dependentAssembly>

<episerver.search.indexingservice>
    <clients>
      <add name="local" description="local" allowLocal="true" readonly="false" />
    </clients>
    <namedIndexes defaultIndex="default">
      <indexes>
        <add name="default" directoryPath="[appDataPath]\Index" readonly="false" />
      </indexes>
    </namedIndexes>
  </episerver.search.indexingservice>
  <location path="IndexingService/IndexingService.svc">
    <system.web>
      <httpRuntime maxQueryStringLength="65536" />
    </system.web>
    <system.webServer>
      <security>
        <requestFiltering>
          <requestLimits maxQueryString="65536" />
        </requestFiltering>
      </security>
    </system.webServer>
  </location>

Then open up Web.Config inside the new project that contains EPiServer Search and change this line:
<add name="default" directoryPath="[appDataPath]\Index" readonly="false" /> to
<add name="default" directoryPath="App_Data\Index" readonly="false" />

Then find this part

    <clients>
      <add name="local" description="local" allowLocal="true" readonly="false" />
    </clients>

And change to this:

    <clients>
      <add name="C7184E3ED7134895B3E95AB3AB4F4AE5" description="local" allowLocal="false" ipAddress="0.0.0.0/0" ip6Address="::/0" readonly="false" />
    </clients>

As you can see the name is a pretty much unique string and I changed allowLocal to false and added settings for ipv4 och ipv6 that basicly says allow all. You can read more here on why to add this settings: http://world.episerver.com/documentation/Items/Developers-Guide/EPiServer-CMS/8/Search/Installing-and-deploying-Search-Service/.

Now you need to go back to the web.config for the regular web project and find the line that points out the endpoint to the indexing asmx, should look something like this:

<add name="serviceName" baseUri="http://localhost:27565/IndexingService/IndexingService.svc" accessKey="local" />

First change the accessKey to match the pretty much unique name you selected before and then change the baseUri so it match the uri you have to your search project. For me it become like this:

<add name="serviceName" baseUri="http://localhost:28217/IndexingService/IndexingService.svc" accessKey="C7184E3ED7134895B3E95AB3AB4F4AE5" />

Now you should be pretty much up and running for the developer part. Start debug or make shore that you start up both web projects and then go into this url:

http://localhost:27565/EPiServer/CMS/Admin/IndexContent.aspx

Make shore you check Delete old data and then press Start Indexing.

This will reindex all your site the new index.

Important: If you do this in Visual Studio 2015 and you get an error like this when browsing to http://localhost:28217/IndexingService/IndexingService.svc:
Could not find a part of the path 'C:\.....\EPiServerSite.EPiServerSearch\bin\roslyn\csc.exe'. just do like they say here:
https://support.appharbor.com/discussions/problems/78633-cant-build-aspnet-mvc-project-generated-from-vstudio-2015-enterprise#comment_37577678
It is a bug in VS2015

Live environment

When you deploy this to production you need to prepare by creating a new website on one of your servers and then either go by port or by a hostname to reach it from all the other servers.

In my example I create one with a host name since I only have port 80 and 443 open in the firewall so I can not reach the iis from outside the server on any other port. So for example create a site like this:

Image site.png

Then I will add a transformation for my web.config in my regular site like this:

<?xml version="1.0" encoding="utf-8"?>

<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <episerver.search active="true">
    <namedIndexingServices defaultService="serviceName">
      <services>
        <add name="serviceName" baseUri="http://EPiServerSite.EPiServerSearch/IndexingService/IndexingService.svc" accessKey="C7184E3ED7134895B3E95AB3AB4F4AE5" xdt:Transform="Replace" />
      </services>
    </namedIndexingServices>
  </episerver.search>
</configuration>

This will not work out of the box since the servers does not know how to translate the "url" EPiServerSite.EPiServerSearch to an ip-adress so we need to tell them that. To do this, open up a notepad as a administrator on the servers and navigate to this file:

C:\Windows\System32\drivers\etc\hosts
It has not file suffix so you need to change in notepad to show all files to see the file hosts. In it on the server that contains the search site add a line like this:

127.0.0.1 EPiServerSite.EPiServerSearch 

And on the other servers add a similar line but change 127.0.0.1 (that means localhost) to the ipaddress of the server containing the search site.

This works great for me and I have saved myself a lot of problems by doing like this.

Aug 31, 2015

per.nergard
(By per.nergard, 9/1/2015 11:19:04 AM)

Nice. What kind of problems did you experience before coming up with this setup?

Henrik Fransas
(By Henrik Fransas, 9/1/2015 11:44:44 AM)

Mostly this:

  • Index files got corrupt when multiple sites indexed at the same time
  • 404 when trying to connect to the indexing asmx (I think this was because of routing problem)
  • some other 500 errors and problems with that the site could not reach the node that was doing the indexing.

Plus that I needed this approach when deploying to Azure

Arild Henrichsen
(By Arild Henrichsen, 9/2/2015 12:45:25 AM)

Yeah the 404 and 500 issues are some of the most common problems. To make things worse, some of the error messages are your only clue that your search config is CORRECT :-/

Svein Aandahl has a nice overview here http://sveinaandahl.blogspot.no/2013/06/how-to-install-episerver-search-for.html so combined these posts should FINALLY let people setup search without losing hair or sleep. Nice writeup!

Henrik Fransas
(By Henrik Fransas, 9/2/2015 10:17:23 AM)

Thanks Arild. Yes Svein's post has helped me a lot through my search for the best setup.

Øyvind Jonassen
(By Øyvind Jonassen, 12/16/2015 3:09:37 PM)

Hi

Do not understand why it helps with 127.0.0.1 EPiServerSite.EPiServerSearch. why not just write localhost?

  
    
      
    
    
      
        
      
    
  

What about also setting readonly="true" on front end serveres? Just to make sure font end servers can not write to the files

nitinanand
(By nitinanand, 4/1/2019 3:52:22 PM)

doesnt work. slight confusion with localhost:27565 and localhost:28217. which localhost to add in main project and which to add in new project.

Please login to comment.