Prerequisites
- An operator checkout of the Quivr revision you deploy, Python 3.12+ (
python3 --version), and SSH (ssh -V). - For the Azure example, Azure CLI (
az version), an authenticated subscription (az account show), permission to create the resources below and invoke VM Run Command to read its public SSH host key. Your region and zone must offer Premium SSD v2 and the selected VM size. - A private SSH identity file outside the repository, its public key, an admin username, and the public CIDRs your operator connections originate from. Before sending the API key, the script verifies the SSH host key through Azure’s authenticated control plane. It saves a private trust file beside your SSH identity, or at
--known-hosts FILE, and uses strict host-key checking thereafter. Keep that trust file for repeat runs. - A regular
0600API-key file containing 16–256 URL-safe characters. Generate and store it outside the repository. The same key becomesWEAVIATE_API_KEYin the engine’s API and every worker. - A running installation with API-key-capable Weaviate clients. For migration, preserve PostgreSQL, canonical content and stored vector artifacts. Your Quivr API key needs
corpora:read,projections:rebuild,operations:readandsearch:query.
large profile caps Weaviate at 64,000,000,000 bytes with GOMEMLIMIT=16GiB; a larger VM needs a corresponding container-memory override. The installer requires at least 2 GiB beyond the container limit for the host and proxy. Increase that margin for your workload.
Provision SSD IOPS and throughput for random reads, imports and compaction. The VM’s uncached disk limits can cap a faster disk. Leave room for the OS disk and maintenance. See cold-index sizing.
Steps
1. Inspect the portable definition
The files indeploy/vector-host/ reuse the pinned image and profile environment from deploy/infrastructure.json. They force API-key authentication on and anonymous access off. Caddy provides automatic certificates through TCP 443; raw Weaviate ports and HTTP port 80 remain closed. Firewall rules permit SSH only from your operator CIDRs.
This credential-free preview was run locally. The DNS name and device are placeholders; rendering never touches the device:
compose.json, Caddyfile, firewall.nft and the systemd units in the output directory. No API key appears in rendered files. --overrides FILE accepts the shared override format.
On another Ubuntu 24.04 x86_64 VM, install Docker with Compose v2, nftables and Python, copy this checkout, and run host.py apply as root with those host arguments and --api-key-file FILE. Use --initialize-empty-disk only for a new blank whole data disk. Existing ext4 filesystems are retained; root disks, partitioned disks, foreign mounts and other filesystem types are refused. The installation mounts by UUID and refuses to start on a missing or wrong disk, including when Docker restarts.
2. Provision the Azure host
Set the variables below from your private deployment configuration: resource group and VM names, region, zone, globally available DNS label, admin username, operator CIDR, and paths to your SSH identity/public key and API-key file. All names are configurable; omitted component names derive from the VM name. Example requiring your Azure account and private files; not run against a cloud provider:--operator-cidr for additional operator networks. Defaults are Standard_E8s_v5 (8 vCPU / 64 GiB), Ubuntu 24.04 x86_64, and a separate PremiumV2_LRS disk with 512 GiB, 12,000 IOPS and 250 MB/s. Host caching is None, required for Premium SSD v2. A new IPv4 virtual network and subnet are created. This example requires a zonal VM for Premium SSD v2; VM and disk use the same zone selected with --zone.
Use --vm-size, --image, --disk-size, --disk-iops, --disk-mbps, --vnet-cidr and --subnet-cidr to change defaults. Component names use --disk-name, --nsg-name, --public-ip-name, --vnet-name, --subnet-name and --nic-name. The script checks VM RAM and uncached disk limits and caps the resolved container CPU limit to its vCPU count. Preserve that CPU setting in overrides when comparing installation checks. See Azure disk requirements and VM sizing.
Azure creates a static public IP with your DNS label, a network security group allowing 443 from anywhere and 22 from operator CIDRs, and a retained data disk. Cloud-init installs the portable definition and mounts the disk by UUID. After verifying SSH trust and the expected bootstrap, the API key travels separately over SSH stdin into a root-owned 0600 file at /etc/quivr-vector-host/weaviate.env. It stays out of cloud-init, resource tags and command arguments.
The command returns weaviate_url and resolved_weaviate_limits. Service startup and certificate issuance continue on the host; check them before cutover. Repeating the same declaration creates no resources, reformats no disk and restarts no healthy service. Ownership or incompatible configuration drift is refused. A failed first run can leave owned resources; inspect privately and rerun the same command. Source/configuration changes require deliberate host updates rather than silently replacing the VM or disk.
3. Move the installation
Schedule downtime for search while the new index is built. Pause source collection and writes, stop workers that write to the old host, and preserve its disk for recovery. SetWEAVIATE_URL to the returned HTTPS URL and WEAVIATE_API_KEY to the matching key on the API and every worker. For native configuration, use weaviate_url and weaviate_api_key; keep TLS verification enabled. See runtime configuration.
Run the installation’s schema bootstrap (quivr migrate) against the new host, then start the API and rebuild workers with the new settings. Enumerate every organization’s document collections (Corpora) and request a rebuild for each through POST /v0/corpora/{corpus_id}/rebuilds (rebuildCorpusProjection). Supply a new idempotency_key in the action body; list Corpora with GET /v0/corpora. See the HTTP API. Follow the returned Operation until it completes. A projection is the searchable representation of stored content; rebuilding uses canonical text and retained vector artifacts, without re-importing sources. Compatible stored vectors can avoid new embedding calls. Rebuild failures leave search unavailable for the affected Corpus; inspect and retry through the supported Operation workflow.
Check counts, coverage and real lexical, semantic and hybrid searches before resuming source collection and normal writes. Keep all roles on the same index endpoint. If you return to the old host after accepting new writes, rebuild its projections from current durable content before reopening search.
4. Check the host and reset scope
Example requiring access to the provisioned host; not run against a cloud provider:match, drift or unknown. It never reports the allowed API key. Compose and Railway infrastructure CLIs accept --vector-host SSH_TARGET; --vector-host without a target explicitly reports unknown. Automatic endpoint detection prevents an unused local Weaviate from proving external settings. Use the same profile and overrides as the host, including its resolved CPU cap. SSH probes use your configured identity and known host key.
host.py apply preserves the data and certificate disk. The installation reset helper refuses an external or unverifiable vector endpoint before stopping writers or deleting volumes. It does not erase this host. Follow reset and reload only for a supported installation with its selected local index; migration never requires a reset.
Check it worked
Verify a protected endpoint such as/v1/schema: a request without a key is refused and the matching bearer key succeeds over HTTPS. Readiness alone does not prove authentication. Check that 443 is reachable, raw index ports/80 are closed, and 22 is reachable only from operator networks.
After a VM or Docker restart, the same data UUID mounts before the index starts. A missing disk prevents startup. Reapply the unchanged declaration and check that resources, data and service uptime are preserved. Test engine searches after idle time, restart and import completion; monitor memory refaults and disk latency. These live checks require the provisioned host and were not performed by the worker.
Troubleshooting
- If provisioning refuses capacity or drift, inspect the selected Azure resources privately. Check region/zone availability, VM limits and the original declaration; retain the disk.
- If initialization fails, inspect
cloud-init status, its logs and the host service journal privately, then rerun. Ensure your public IP is in an operator CIDR. - If certificates are unavailable, check the DNS label resolves to the static IP and TCP 443 reaches Caddy directly. TLS-ALPN validation needs that port.
- If checks report unknown, supply a reachable SSH target with sudo observation access, or inspect directly on the host. Unknown does not prove a match.
- If search slows after quiet time, revisit resident-memory and storage budgets; compare warm/cold searches and maintenance load.