Skip to Content
DocsAdmin GuideDeployment

Deployment

Quazzar Cloud OS is designed for bare metal servers and VPS instances. It is distributed as a .deb package through the Quazzar APT repository.


APT Installation

Add the Quazzar APT repository and install the package:

# Import GPG key curl -fsSL https://apt.quazzar.cloud/apt/gpg-key.asc | sudo gpg --dearmor -o /usr/share/keyrings/quazzar.gpg # Add Quazzar repositories (stable + testing) sudo tee /etc/apt/sources.list.d/quazzar.list <<'EOF' deb [signed-by=/usr/share/keyrings/quazzar.gpg] https://apt.quazzar.cloud/apt stable main deb [signed-by=/usr/share/keyrings/quazzar.gpg] https://apt.quazzar.cloud/apt testing main EOF # Update and install sudo apt update sudo apt install quazzar

During installation, a terminal installer lets you choose which optional components to install (S3 storage, VPN, local AI, mail, WhatsApp, system tuning, network management). The package no longer installs Docker on its own: the installer keeps, replaces or installs it according to your choice. Without a terminal, defaults are used; to choose in a script, set QUAZZAR_COMPONENTS. See Components.

After installation, the setup output will show:

Quazzar service installed. To start: sudo systemctl start quazzar.service Edit configuration: sudo nano /etc/quazzar/quazzar.env

Start the Service

sudo systemctl start quazzar.service sudo systemctl enable quazzar.service

Docker

Alternatively, run Cloud OS as a Docker container. The image is hosted on the Quazzar private registry.

docker run -d \ --name quazzar \ --restart unless-stopped \ -p 8080:8080 \ -p 443:443 \ -p 80:80 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v quazzar-data:/var/lib/quazzar \ docker.quazzar.space/cloud-os:latest

Cloud OS needs access to the Docker socket to manage application containers. When running Cloud OS itself in Docker, mount the host’s Docker socket into the container.


Health Checks

Cloud OS exposes a health endpoint at GET /health for load balancers and monitoring tools. It returns 200 OK when the service is running and the database is accessible.


Upgrading

Upgrade via APT like any other system package:

sudo apt update sudo apt full-upgrade -y

The quazzar.service is automatically restarted after the upgrade.

Docker

docker pull docker.quazzar.space/cloud-os:latest docker compose up -d

Always back up the data directory before upgrading. Database migrations run automatically on startup.


Schema migrations (0.6.35)

0.6.35 ships with database migrations that run automatically on startup — no manual step is required. For reference, the release includes:

SideMigrationWhat it does
Node (quazzar.db)068Creates the notes table for the Memory MCP + Orbit Notes surface
Node (quazzar.db)069Adds the notes_embed_queue + cosine index for semantic search
Node (quazzar.db)070Adds widget_size_shape storage columns for the free-form dashboard grid
Control Panel (cc.db)058Extends billing_packages.features with Orbit Pro keys (orbit_collab, orbit_pivot, …)
Control Panel (cc.db)059Adds mcp_memory_snapshots for cross-node sync

Migrations are idempotent and run in order. If a migration fails, the service refuses to start and logs the migration index; restore from backup before retrying.

Back up /var/lib/quazzar/data/quazzar.db (node) and the Control Panel PostgreSQL database before upgrading to 0.6.35. The new tables hold durable state for Memory MCP and Orbit, and restoring a pre-0.6.35 backup after running migrations requires reapplying them manually.


Ownerless MSP clients and policies

MSP clients and fleet governance policies belong to a workspace (Control Center migrations 100 and 101). Rows created before those migrations had no owner and are hidden from every workspace until they get one. On every start, migration 104 assigns an owner wherever the data points at exactly one workspace:

  • an MSP client linked from the nodes of a single workspace (Fleet → node → Client), or named only in that workspace’s audit log;
  • a policy whose recorded violations are all on one workspace’s nodes, or named only in that workspace’s audit log;
  • on a single-workspace install (self-hosted with one tenant), every remaining ownerless client and policy goes to that workspace.

Anything else stays ownerless. To find and assign those rows, run against the Control Center PostgreSQL database:

-- What is still ownerless SELECT id, name, slug, contact_email, created_at FROM msp_clients WHERE tenant_id IS NULL; SELECT id, name, policy_type, created_at FROM fleet_policies WHERE tenant_id IS NULL; -- Find the workspace (tenant) to give them to SELECT id, name, email FROM tenants ORDER BY created_at; -- Assign UPDATE msp_clients SET tenant_id = '<tenant id>' WHERE id = '<client id>' AND tenant_id IS NULL; UPDATE fleet_policies SET tenant_id = '<tenant id>' WHERE id = '<policy id>' AND tenant_id IS NULL; -- Or remove what nobody needs any more DELETE FROM fleet_policies WHERE id = '<policy id>' AND tenant_id IS NULL;

A client assigned to an MSP workspace is also visible to its parent MSP (the MSP that created that client workspace). Policies take effect for the new owner on the next evaluation pass (every 10 minutes).


CI: GOTOOLCHAIN pin

Starting in 0.6.34, builds require GOTOOLCHAIN=go1.25.5 to sidestep a runner-vs-toolchain mismatch in the Go 1.24/1.25 rollout. If you build from source or run CI jobs against the repo, export the variable at the top of your pipeline:

variables: GOTOOLCHAIN: "go1.25.5"

The upstream Dockerfile and .gitlab-ci.yml already pin this. The requirement disappears once the standard runner image upgrades to Go 1.25+.