Windows Server Deployments
The MSI-and-service packaging, deployed the way a Windows shop deploys everything else: silent installation through Intune, Configuration Manager, or GPO scripting, the service-versus-desktop decision, where state lands under a service account, antivirus and firewall realities, and upgrading in place. For the administrator rolling out to a fleet or standing up a datacenter host.
1One MSI, two modes#
The Windows package ships as a signed, per-machine MSI (x64 and ARM64), installing into
C:\Program Files\LM-Kit One. One property decides what kind of installation it is:
| Mode | What it installs | Lifecycle |
|---|---|---|
desktop (default) |
Payload, Start Menu shortcut, and the tray application, launched at the end of an interactive install | Starts with the user's session; autostart is per user, registered by the tray itself |
service |
Payload plus the LMKitOne Windows service, start type automatic, running as LocalSystem |
Starts with the machine, no logged-in session required |
Desktop is the default because a local user cannot script their way past a wrong one, while a
fleet deployment passes the property anyway. The mode is recorded (under
HKLM\SOFTWARE\LM-Kit\One), and the installer also detects a present service directly, so a
machine that already runs the service keeps it through every upgrade, whatever the default says.
An upgrade never silently unregisters a production server. Hosts installed under the previous
product name are recognized through the same detection.
Both modes install the tray. In service mode nothing starts it, but running it finds the service already serving, reports it, and opens its pages, so an administrator gets a control surface without any extra deployment.
2Silent installation for fleets#
The MSI behaves as a standard silent MSI, which is the whole point: anything that can push an MSI can push this one.
msiexec /i LM-Kit-One-<version>-win-x64.msi INSTALLMODE=service /qn service host, silent
msiexec /i LM-Kit-One-<version>-win-x64.msi desktop (default)
msiexec /x LM-Kit-One-<version>-win-x64.msi /qn uninstall, silent
Fleet-tooling specifics worth knowing up front:
- Per-machine scope, no UI. The package installs machine-wide and carries no dialog beyond a
progress bar, so
/qnhides nothing a person needed to see. A silent install never launches the tray; only an interactive desktop install ends with it running. - Version detection has a fold. Windows Installer rejects a package major above 255, so the calendar version folds inside the MSI (2026.8.1 records as package version 26.8.1) while Programs and Features displays the real one. A detection rule keyed on MSI product version must expect the folded form; a rule keyed on the displayed version sees the calendar form.
- Uninstall is symmetric. Removal unregisters the service before deleting files, and the unregistration is idempotent, so the same command line uninstalls both modes.
Verify the rollout with exit codes, not eyeballs. lmkit doctor runs one pass over state
directory writability, model directory and free disk, visible compute devices, certificate
validity, service registration, and liveness, and exits 0 only when everything passes;
lmkit service status exits 2 when the service is not registered. Both compose directly into a
compliance script (The Command Line).
3The service, owned by the product#
The LMKitOne service is registered by the product, not by the package: the installer calls
lmkit service install with rollback, and the same verbs are yours at any time (elevated for
install and uninstall):
lmkit service install
lmkit service status
lmkit service uninstall
This is deliberate. It means the portable zip gains the same capability the MSI has, and a machine crosses between desktop and service mode with one command instead of a reinstall.
Installation registers the service but does not start the server, because a fresh instance is
unconfigured. Start it yourself (Start-Service LMKitOne) or let the next boot do it, then
finish the setup: on a host other machines will reach, create the operator account and mint API
keys before widening the network posture (Going Live).
4Where state and models land#
Everything the server writes resolves under one state directory, decided at startup and printed in the startup log (Where Data Lives). On Windows the resolution is mode-dependent:
| Mode | State directory |
|---|---|
| Service (LocalSystem) | Beside the executable: C:\Program Files\LM-Kit One, which is writable for the service |
| Desktop | %LOCALAPPDATA%\LM-Kit\One, because an ordinary user cannot (and should not) write into Program Files |
| Either | LMKIT_STATE_DIR pins it explicitly |
Models live separately, under the model directory shown in Models, with
LMKIT_MODELS_DIR overriding the default. Two fleet practices follow:
- Pin the paths machine-wide. The CLI verbs act on the state their own user resolves, so an
administrator's shell and the LocalSystem service can see different paths. Setting
LMKIT_STATE_DIRandLMKIT_MODELS_DIRas system environment variables makes the service, scheduled scripts, and every operator shell resolve the same installation;lmkit doctorprints the paths it acted on precisely so a mismatch is visible. - Provision models at image-build time.
lmkit modelslists the catalog with download state, andlmkit pull gemma4:12bdownloads by catalog id without starting the server. Pull on the build machine, ship the image, and first boot serves immediately; the same pair is the air-gapped recipe.
The state directory is the installation: it is the backup set, and it is what moves to a new host (Backup and Upgrades).
5Antivirus realities#
The shipped binaries and the MSI are code-signed, which removes the SmartScreen warning and the heuristic false positives that self-contained single-file executables otherwise attract. What signing does not change is scan-on-read economics: model files run to many gigabytes, and real-time protection scans what the process reads, so a first model load can pay a substantial scan cost in latency and disk load.
Excluding the model directory from real-time scanning is a measured option, not a default:
- Measure first. Time a cold model load with and without the exclusion on your own hardware. If the difference does not matter on your traffic, keep the scanner on everything.
- If you exclude, exclude narrowly. The model directory only. Pair it with restrictive write ACLs on that directory, because an exclusion is exactly as safe as the list of principals who can write into it.
- Never blanket-exclude the install directory or the state directory: settings, keys, and uploads deserve scanning, and the cost there is negligible.
6Firewall and network posture#
A service install creates one inbound Windows Firewall rule, scoped to the program rather than to a port, because the listening ports are administrator-configurable and a port-scoped rule silently stops matching the moment someone changes them. A desktop install creates no rule: it listens on loopback, which needs none, and if it is later opened to the network Windows prompts on the first bind.
The rule only permits reachability. Whether the server actually listens beyond loopback is the
network posture in the Network section, and the moment the posture is Network,
every API call requires a key (Going Live). A GPO-managed firewall that
strips locally created rules should recreate the same program-scoped rule with its own tooling,
pointed at lmkit.exe in the install directory.
7GPU on a Windows Server host#
The runtime probes the host at startup and selects a backend: CUDA on NVIDIA hardware, Vulkan for AMD and Intel, CPU otherwise. On a server host that means installing the vendor driver (NVIDIA's driver for CUDA, a Vulkan-capable driver otherwise) and verifying, in this order:
lmkit devicesprints the compute inventory (name, type, memory) the runtime will see, offline, before anything loads.- The Hardware section shows what the running server sees and uses, which is the answer that matters for a service running as LocalSystem without any session.
- A real request while watching utilization, because inference that works but runs on CPU is the classic silent failure.
Backend selection, driver specifics, and the slow-inference diagnosis path are GPUs and Backends; memory sizing is Hardware Sizing.
8Upgrading in place#
An upgrade is the new MSI over the old one; the package supersedes the previous version and
keeps the recorded install mode, so a service host stays a service host. The procedure is the
standard runbook (Backup and Upgrades): copy the state directory,
stop the service, install, start, verify. lmkit doctor calls out the one classic post-upgrade
state (binary and running server reporting different versions until the service restarts), and
/health reports the new version when it is done.
One legacy case needs a manual step: a host installed under the previous product name keeps its
server-written state in the old install directory (C:\Program Files\LM-Kit Server). The MSI
removes the old service and files, but not what the server wrote at runtime; copy
appsettings.json (and certificates\ if the instance issued any) into C:\Program Files\LM-Kit One
before starting LMKitOne, then delete the old folder.
Logs stay files throughout: server.log under the state directory, tailed by lmkit logs --follow or the Logs section, and exported to your monitoring through OTLP or
Prometheus when you turn that on (Observability). After an abnormal
exit, the dashboard's unexpected-restart report also consults Windows' own shutdown records, so
a host-level crash is attributed instead of guessed at.
9Stated plainly#
- A set of service boxes becomes a load-balanced farm with the shared stores, warm joins, and lossless drains of Scaling Out; the rollout below provisions the boxes either way.
- One signed, per-machine MSI;
INSTALLMODE=service /qnis the entire fleet recipe, and any MSI-pushing tool qualifies. - The install mode is recorded and re-detected, so upgrades keep a production service a service.
- The service is registered by the product's own verbs, which the portable archive shares.
- State lands beside the executable for the service and under the user profile for desktop mode;
pin
LMKIT_STATE_DIRmachine-wide on fleets. - Antivirus exclusions are a measured, narrow option for the model directory, never a blanket instruction.