Windows Deployment Plan¶
Overview¶
NornicDB on Windows supports multiple distribution methods: 1. MSI Installer + Windows Service - Enterprise/end-user, GUI installation 2. Chocolatey - Developer-focused, command-line installation 3. winget - Microsoft's official package manager 4. Portable ZIP - No installation required
All methods can optionally install NornicDB as a Windows Service that runs in the background.
Build Variants¶
NornicDB offers 5 Windows build variants to match different deployment needs:
| Variant | Binary | Size | Embeddings | GPU | Use Case |
|---|---|---|---|---|---|
cpu | nornicdb-cpu.exe | ~15MB | None | ❌ | Smallest, use external embedding service |
cpu-localllm | nornicdb-cpu-localllm.exe | ~25MB | BYOM | ❌ | Resource-constrained, bring own model |
cpu-bge | nornicdb-cpu-bge.exe | ~425MB | Built-in | ❌ | Resource-constrained, ready to run |
cuda | nornicdb-cuda.exe | ~30MB | BYOM | ✅ | GPU-accelerated, bring own model |
cuda-bge | nornicdb-cuda-bge.exe | ~430MB | Built-in | ✅ | GPU-accelerated, ready to run |
BYOM = Bring Your Own Model (place .gguf file in models/ directory)
Quick Build Guide¶
All builds use build.bat on Windows:
REM === FIRST TIME SETUP ===
REM Download pre-built llama.cpp libraries (for localllm/cuda variants)
build.bat download-libs
REM Download BGE model (for bge variants, ~400MB)
build.bat download-model
REM === BUILD VARIANTS ===
REM CPU-only (smallest, no embeddings)
build.bat cpu
REM CPU + local embeddings (bring your own model)
build.bat cpu-localllm
REM CPU + local embeddings + BGE model embedded
build.bat cpu-bge
REM CUDA + local embeddings (requires NVIDIA GPU)
build.bat cuda
REM CUDA + local embeddings + BGE model embedded
build.bat cuda-bge
REM Build headless variant (no web UI)
build.bat cuda headless
REM Build ALL variants
build.bat all
Prerequisites by Variant¶
| Variant | Go | llama.cpp libs | CUDA Toolkit | BGE Model |
|---|---|---|---|---|
cpu | ✅ | ❌ | ❌ | ❌ |
cpu-localllm | ✅ | ✅ | ❌ | ❌ |
cpu-bge | ✅ | ✅ | ❌ | ✅ |
cuda | ✅ | ✅ (CUDA) | ✅ | ❌ |
cuda-bge | ✅ | ✅ (CUDA) | ✅ | ✅ |
Pre-Built llama.cpp Libraries¶
For fast builds, use pre-built llama.cpp libraries instead of compiling from source (~15 min saved).
Option 1: Download Pre-Built (Recommended)¶
Option 2: Build Locally (requires VS2022 + CUDA)¶
# Build CUDA-enabled llama.cpp libraries
.\scripts\build-llama-cuda.ps1
# Output: lib\llama\libllama_windows_amd64.lib
Pre-Built Library Artifacts¶
Available from GitHub Releases: - URL: timothyswt/nornicdb/releases/download/libs-v1/ - Files: libllama_windows_amd64.lib, headers
Method 1: MSI Installer (Recommended)¶
User Experience¶
- Download
NornicDB-1.0.0.msifrom releases - Double-click to install
- Follow installation wizard
- Service starts automatically
- Access at
http://localhost:7474
Implementation¶
1. Directory Structure¶
packaging/windows/
├── wix/
│ ├── Product.wxs # Main WiX definition
│ ├── Service.wxs # Windows Service config
│ └── UI.wxs # Installer UI
├── service/
│ ├── nornicdb-service.xml # WinSW configuration
│ └── WinSW.exe # Service wrapper
├── scripts/
│ ├── install.ps1 # Post-install script
│ └── uninstall.ps1 # Pre-uninstall script
└── build-msi.ps1 # Build script
2. WiX Installer Definition (Product.wxs)¶
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="NornicDB"
Language="1033"
Version="1.0.0.0"
Manufacturer="NornicDB"
UpgradeCode="YOUR-GUID-HERE">
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version is already installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="ProductFeature" Title="NornicDB" Level="1">
<ComponentGroupRef Id="ProductComponents" />
<ComponentGroupRef Id="ServiceComponents" />
</Feature>
<!-- Properties -->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<Property Id="INSTALL_SERVICE" Value="1" />
<!-- Custom Actions -->
<CustomAction Id="InstallService"
Directory="INSTALLFOLDER"
ExeCommand="[INSTALLFOLDER]nornicdb-service.exe install"
Execute="deferred"
Impersonate="no"
Return="check" />
<CustomAction Id="StartService"
Directory="INSTALLFOLDER"
ExeCommand="[INSTALLFOLDER]nornicdb-service.exe start"
Execute="deferred"
Impersonate="no"
Return="ignore" />
<CustomAction Id="StopService"
Directory="INSTALLFOLDER"
ExeCommand="[INSTALLFOLDER]nornicdb-service.exe stop"
Execute="deferred"
Impersonate="no"
Return="ignore" />
<CustomAction Id="UninstallService"
Directory="INSTALLFOLDER"
ExeCommand="[INSTALLFOLDER]nornicdb-service.exe uninstall"
Execute="deferred"
Impersonate="no"
Return="ignore" />
<InstallExecuteSequence>
<Custom Action="StopService" Before="InstallFiles">
REMOVE="ALL"
</Custom>
<Custom Action="UninstallService" After="StopService">
REMOVE="ALL"
</Custom>
<Custom Action="InstallService" After="InstallFiles">
NOT REMOVE AND INSTALL_SERVICE
</Custom>
<Custom Action="StartService" After="InstallService">
NOT REMOVE AND INSTALL_SERVICE
</Custom>
</InstallExecuteSequence>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="NornicDB">
<Directory Id="DataFolder" Name="data" />
<Directory Id="LogFolder" Name="logs" />
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="NornicDB" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="MainExecutable" Guid="YOUR-GUID-1">
<File Id="NornicDBExe"
Source="$(var.BuildDir)\nornicdb.exe"
KeyPath="yes" />
<!-- Add to PATH -->
<Environment Id="PATH"
Name="PATH"
Value="[INSTALLFOLDER]"
Permanent="no"
Part="last"
Action="set"
System="yes" />
</Component>
<Component Id="ServiceWrapper" Guid="YOUR-GUID-2">
<File Id="ServiceExe"
Source="$(var.BuildDir)\nornicdb-service.exe" />
<File Id="ServiceConfig"
Source="$(var.BuildDir)\nornicdb-service.xml" />
</Component>
</ComponentGroup>
<ComponentGroup Id="ServiceComponents" Directory="INSTALLFOLDER">
<!-- Data directory -->
<Component Id="DataDir" Guid="YOUR-GUID-3">
<CreateFolder Directory="DataFolder">
<Permission User="SYSTEM" GenericAll="yes" />
<Permission User="Administrators" GenericAll="yes" />
</CreateFolder>
</Component>
<!-- Log directory -->
<Component Id="LogDir" Guid="YOUR-GUID-4">
<CreateFolder Directory="LogFolder">
<Permission User="SYSTEM" GenericAll="yes" />
<Permission User="Administrators" GenericAll="yes" />
</CreateFolder>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
3. WinSW Service Configuration (nornicdb-service.xml)¶
<service>
<id>NornicDB</id>
<name>NornicDB Graph Database</name>
<description>Lightweight graph database with vector search and AI memory</description>
<executable>%BASE%\nornicdb.exe</executable>
<arguments>serve --data-dir "%BASE%\data"</arguments>
<!-- Logging -->
<log mode="roll-by-size">
<sizeThreshold>10240</sizeThreshold>
<keepFiles>8</keepFiles>
</log>
<logpath>%BASE%\logs</logpath>
<!-- Service behavior -->
<startmode>Automatic</startmode>
<delayedAutoStart>true</delayedAutoStart>
<!-- Recovery -->
<onfailure action="restart" delay="10 sec"/>
<onfailure action="restart" delay="20 sec"/>
<onfailure action="restart" delay="30 sec"/>
<resetfailure>1 hour</resetfailure>
<!-- Environment -->
<env name="NORNICDB_LOG_LEVEL" value="info"/>
<!-- Run as LocalService for security -->
<serviceaccount>
<username>LocalService</username>
</serviceaccount>
<!-- Dependencies -->
<depend>Tcpip</depend>
</service>
4. Build Script (build-msi.ps1)¶
param(
[string]$Version = "1.0.0"
)
$ErrorActionPreference = "Stop"
Write-Host "Building NornicDB MSI v$Version" -ForegroundColor Cyan
# Paths
$BuildDir = "build\windows"
$DistDir = "dist"
$WixDir = "packaging\windows\wix"
# Create build directory
New-Item -ItemType Directory -Force -Path $BuildDir | Out-Null
New-Item -ItemType Directory -Force -Path $DistDir | Out-Null
# Build Windows binary (cross-compile from Mac/Linux or native)
Write-Host "Building nornicdb.exe..."
$env:GOOS = "windows"
$env:GOARCH = "amd64"
$env:CGO_ENABLED = "0"
go build -o "$BuildDir\nornicdb.exe" .\cmd\nornicdb
# Download WinSW
$WinSWUrl = "https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exe"
if (-not (Test-Path "$BuildDir\nornicdb-service.exe")) {
Write-Host "Downloading WinSW..."
Invoke-WebRequest -Uri $WinSWUrl -OutFile "$BuildDir\nornicdb-service.exe"
}
# Copy service config
Copy-Item "packaging\windows\service\nornicdb-service.xml" $BuildDir
# Build MSI with WiX
Write-Host "Building MSI installer..."
$WixBin = "C:\Program Files (x86)\WiX Toolset v3.11\bin"
& "$WixBin\candle.exe" `
-dBuildDir="$BuildDir" `
-dVersion="$Version" `
-out "$BuildDir\Product.wixobj" `
"$WixDir\Product.wxs"
& "$WixBin\light.exe" `
-ext WixUIExtension `
-cultures:en-us `
-out "$DistDir\NornicDB-$Version.msi" `
"$BuildDir\Product.wixobj"
Write-Host "✓ Built: $DistDir\NornicDB-$Version.msi" -ForegroundColor Green
Method 2: Chocolatey¶
User Experience¶
# Install
choco install nornicdb
# Start service
Start-Service NornicDB
# Check status
Get-Service NornicDB
# Uninstall
choco uninstall nornicdb
Implementation¶
Package Structure¶
chocolatey/
├── nornicdb.nuspec
├── tools/
│ ├── chocolateyinstall.ps1
│ ├── chocolateyuninstall.ps1
│ └── LICENSE.txt
└── legal/
└── VERIFICATION.txt
nornicdb.nuspec¶
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>nornicdb</id>
<version>1.0.0</version>
<title>NornicDB</title>
<authors>NornicDB Team</authors>
<owners>timothyswt</owners>
<licenseUrl>https://github.com/timothyswt/nornicdb/blob/main/LICENSE</licenseUrl>
<projectUrl>https://github.com/timothyswt/nornicdb</projectUrl>
<iconUrl>https://raw.githubusercontent.com/timothyswt/nornicdb/main/icon.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Lightweight graph database with vector search and AI memory</description>
<summary>A Neo4j-compatible graph database optimized for AI/LLM memory</summary>
<tags>database graph neo4j vector-search ai llm</tags>
<releaseNotes>Initial release</releaseNotes>
</metadata>
<files>
<file src="tools\**" target="tools" />
</files>
</package>
chocolateyinstall.ps1¶
$ErrorActionPreference = 'Stop'
$packageName = 'nornicdb'
$toolsDir = "$(Split-Path -Parent $MyInvocation.MyCommand.Definition)"
$url64 = 'https://github.com/timothyswt/nornicdb/releases/download/v1.0.0/nornicdb-windows-amd64.zip'
$checksum64 = 'PLACEHOLDER_SHA256'
# Install to Program Files
$installDir = Join-Path $env:ProgramFiles 'NornicDB'
Install-ChocolateyZipPackage `
-PackageName $packageName `
-Url64bit $url64 `
-Checksum64 $checksum64 `
-ChecksumType64 'sha256' `
-UnzipLocation $installDir
# Add to PATH
Install-ChocolateyPath -PathToInstall $installDir -PathType 'Machine'
# Install as Windows Service
$serviceName = 'NornicDB'
$serviceExe = Join-Path $installDir 'nornicdb.exe'
# Download and configure WinSW
# ... (similar to MSI approach)
Write-Host "NornicDB installed successfully!" -ForegroundColor Green
Write-Host "Start the service with: Start-Service NornicDB"
Method 3: winget¶
User Experience¶
Implementation¶
Submit a PR to microsoft/winget-pkgs:
# manifests/n/NornicDB/NornicDB/1.0.0/NornicDB.NornicDB.yaml
PackageIdentifier: NornicDB.NornicDB
PackageVersion: 1.0.0
PackageName: NornicDB
Publisher: NornicDB
License: MIT
ShortDescription: Lightweight graph database with vector search
Installers:
- Architecture: x64
InstallerType: msi
InstallerUrl: https://github.com/timothyswt/nornicdb/releases/download/v1.0.0/NornicDB-1.0.0.msi
InstallerSha256: PLACEHOLDER
ManifestType: singleton
ManifestVersion: 1.0.0
Service Management¶
After installation, users can manage the service:
# PowerShell commands
Start-Service NornicDB
Stop-Service NornicDB
Restart-Service NornicDB
Get-Service NornicDB
# Command Prompt
net start NornicDB
net stop NornicDB
# Service Control (sc)
sc query NornicDB
sc start NornicDB
sc stop NornicDB
Or use the Services GUI: services.msc
Data Locations¶
| Type | Path |
|---|---|
| Binary | C:\Program Files\NornicDB\nornicdb.exe |
| Data | C:\Program Files\NornicDB\data\ |
| Logs | C:\Program Files\NornicDB\logs\ |
| Config | C:\ProgramData\NornicDB\config.yaml (optional) |
| Service | Windows Service: "NornicDB" |
Firewall Configuration¶
The installer should add a firewall rule:
# Add during installation
New-NetFirewallRule `
-DisplayName "NornicDB" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 7474,7687 `
-Action Allow `
-Program "C:\Program Files\NornicDB\nornicdb.exe"
# Remove during uninstallation
Remove-NetFirewallRule -DisplayName "NornicDB"
Code Signing¶
For trusted installation without warnings:
- Obtain a code signing certificate (DigiCert, Sectigo, etc.)
- Sign the executable and MSI:
# Sign executable
signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 `
/f certificate.pfx /p PASSWORD nornicdb.exe
# Sign MSI
signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 `
/f certificate.pfx /p PASSWORD NornicDB.msi
Implementation Checklist¶
- Create WiX installer project
- Configure WinSW service wrapper
- Build MSI installer
- Test installation/uninstallation
- Create Chocolatey package
- Submit to Chocolatey community repository
- Create winget manifest
- Submit to winget-pkgs
- Set up code signing
- Add to GitHub Actions release workflow
- Test on Windows 10
- Test on Windows 11
- Test on Windows Server 2019/2022
- Document manual service installation