Server: Running an Embedded Instance

Overview

RavenDB makes it very easy to be embedded within your application, with RavenDB Embedded package you can integrate your RavenDB server with few easy steps.

EmbeddedServer.Instance.StartServer();
using (var store = EmbeddedServer.Instance.GetDocumentStore("Embedded"))
{
    using (var session = store.OpenSession())
    {
        // Your code here
    }
}
EmbeddedServer.Instance.StartServer();
using (var store = await EmbeddedServer.Instance.GetDocumentStoreAsync("Embedded"))
{
    using (var session = store.OpenAsyncSession())
    {
        // Your code here
    }
}

Prerequisites

There is one prerequsite and one recommendation for the Embedded package:

Prerequsite:

Recommendation:

  • Projects targeting .NET Framework 4.6.1+ that use old packages.config for maintaining NuGet packages should be migrated to PackageReference package management (please refer to section below on how to achieve this)

.NET Core Runtime

RavenDB Embedded does not include .NET Core runtime required for it to run.

By default the ServerOptions.FrameworkVersion is set to the .NET Core version that we compiled the server with and ServerOptions.DotNetPath is set to dotnet meaning that it will require to have it declared in PATH.

We highly recommend using the .NET Core framework version defined in ServerOptions.FrameworkVersion for proper functioning of the Server. The .NET Core runtime can be downloaded from here.

Migrating from packages.config to PackageReference in old csproj projects

Due to the NuGet limitations, we recommend that the Embedded package should be installed via newer package management using PackageReference instead of old packages.config.

The transition between those two is easy due to built-in into Visual Studio 2017 migrator written by Microsoft. Please read following article written by Microsoft that will guide you through the process.

Please note that binding redirects in App.config are still required when 'PackageReference' is used in old csproj project. Not doing so might result in an assembly load exception e.g.

Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Getting Started

Installation

  • Create a new project (.NET Standard 2.0+, .NET Core 2.0+, .NET Framework 4.6.1+).
  • Grab the package from our NuGet
    Install-Package RavenDB.Embedded -Version 4.1.0

Starting the Server

RavenDB Embedded Server is available under EmbeddedServer.Instance. In order to start it call StartServer method.

// Start RavenDB Embedded Server with default options
EmbeddedServer.Instance.StartServer();

For more control on how to start the server just pass to StartServer method a ServerOptions object and that`s it.

ServerOptions

Name Type Description
FrameworkVersion string The .NET Core framework version to run the server with
DataDirectory string Indicates where your data should be stored
DotNetPath string The path to exec dotnet (if it is in PATH, leave it)
AcceptEula bool If set to false, will ask to accept our terms & conditions
ServerUrl string What address we want to start our server (default 127.0.0.1:0)
MaxServerStartupTimeDuration TimeSpan The timeout for the server to start
CommandLineArgs List<string> The command lines arguments to start the server with
ServerDirectory string The path to the server binary files*

EmbeddedServer.Instance.StartServer(new ServerOptions
{
    DataDirectory = "C:\\RavenData",
    ServerUrl = "http://127.0.0.1:8080"
});

Setting Server Directory

In case you're not interested in installing the .Net run-time environment on your system, you can -

  • Download a full RavenDB version.
    This version already includes a .Net run-time environment.
  • Extract the downloaded version to a local folder.
    E.g. C:\RavenDB.
  • Set the ServerDirectory server option to the RavenDB subfolder that contains -
    • Raven.Server.exe in Windows
    • Raven.Server in Posix

EmbeddedServer.Instance.StartServer(new ServerOptions
{
    ServerDirectory = @"C:\RavenDB\Server"
});

Note

Without the ServerOptions, RavenDB server will start with a default values on 127.0.0.1:{Random Port}

Security

RavenDB Embedded support running a secured server. Just run Secured method in ServerOptions object.

We have two overloads to Secured:

var serverOptions = new ServerOptions();
serverOptions.Secured(
    certificate: "PathToServerCertificate",
    certPassword: "CertificatePassword");

The first way to enable authentication is to set certificate with the path to your .pfx server certificate. You may supply the certificate password using certPassword.

var serverOptionsWithExec = new ServerOptions();
var certificate = new X509Certificate2();
serverOptionsWithExec.Secured(
    certExec: "powershell",
    certExecArgs: "C:\\secrets\\give_me_cert.ps1",
    serverCertThumbprint: certificate.Thumbprint,
    clientCert: certificate);

This option is useful when you want to protect your certificate (private key) with other solutions such as "Azure Key Vault", "HashiCorp Vault" or even Hardware-Based Protection. RavenDB will invoke a process you specify, so you can write your own scripts / mini programs and apply whatever logic you need. It creates a clean separation between RavenDB and the secret store in use. RavenDB expects to get the raw binary representation (byte array) of the .pfx certificate through the standard output. In this options you can control on your client certificate and to use in a different certificate for your client.

Document Store

After starting the server you can get the DocumentStore from the Embedded Server and start working with RavenDB. Getting the DocumentStore from The Embedded Server is pretty easy you only need to call GetDocumentStore or GetDocumentStoreAsync with the name of the database you like to work with.

EmbeddedServer.Instance.GetDocumentStore("Embedded");
await EmbeddedServer.Instance.GetDocumentStoreAsync("Embedded");

For more control on the process you can call the methods with DatabaseOptions object.

DatabaseOptions

Name Type Description
DatabaseRecord DatabaseRecord Instance of DatabaseRecord containing database configuration
SkipCreatingDatabase bool If set to true, will skip try creating the database

var databaseOptions = new DatabaseOptions(new DatabaseRecord
{
    DatabaseName = "Embedded"
});
EmbeddedServer.Instance.GetDocumentStore(databaseOptions);
var databaseOptions = new DatabaseOptions(new DatabaseRecord
{
    DatabaseName = "Embedded"
});
await EmbeddedServer.Instance.GetDocumentStoreAsync(databaseOptions);

Get Server URL

The GetServerUriAsync method can be used to retrieve the Embedded server URL. It must be called after server was started, because it waits for the server initialization to complete. The URL can be used for example for creating a custom document store, omitting the GetDocumentStore method entirely.

Uri url = await EmbeddedServer.Instance.GetServerUriAsync();

Remarks

  • You can have only one instance of EmbeddedServer
  • Method EmbeddedServer.Instance.OpenStudioInBrowser() can be used to open an browser instance with Studio