تخطَّ إلى المحتوى
kazma.
EN نجمة 7 ابدأ الآن

Migration (cross-machine)

هذا المحتوى غير متوفر بلغتك بعد.

Move a full Kazma installation — config, secrets, memory, chat history, snapshots, scheduled jobs, assets — from one machine to another (WSL→Windows, Linux→Mac, server→laptop) without the silent breakage of a naive copy-paste.

A naive file copy breaks in three specific ways: the encrypted vault becomes undecryptable (wrong key), embedded file paths point at a dead /home/user/..., and Postgres-backed data (chat history, settings, checkpoints) is missed entirely. kazma migrate prevents all three.


On the source machine:

Terminal window
kazma migrate export --out my-kazma.zip

On the target machine (after copying my-kazma.zip over):

Terminal window
kazma migrate verify my-kazma.zip
kazma migrate import my-kazma.zip --workspace /path/to/kazma --dry-run # preview first
kazma migrate import my-kazma.zip --workspace /path/to/kazma # real import

That’s it for a SQLite-backed install. For Postgres sources, see § Postgres migration below.


A .zip archive with:

FileContents
manifest.jsonVersion, source OS/host, per-file sha256, vault-key fingerprint, table counts
meta.envKAZMA_VAULT_KEY + KAZMA_PUBLIC_URL (needed for vault decryption + OAuth)
config.yamlFull ConfigStore settings (secrets are vault:// refs, not plaintext)
data/vault.dbEncrypted secrets store (29+ secrets) — travels WITH the vault key
data/*.dbAll SQLite databases (snapshots, memory, cron, chat, checkpoints, etc.)
data/postgres.dumpPostgres dump (only when source is Postgres-backed)
data/workspaces.dbWorkspace table (root paths rewritten on import)
assets/Binary artifacts: attachments, documents, exports, images, fonts
pathmap.jsonSource workspace root + data dir (for path translation)

These are the silent-breakage modes kazma migrate prevents:

A. Vault pairing — vault.db + KAZMA_VAULT_KEY travel together

Section titled “A. Vault pairing — vault.db + KAZMA_VAULT_KEY travel together”

The vault’s encryption salt lives inside vault.db, so the DB is undecryptable without its matching key. The bundle carries both. On import:

  • Keys match → vault.db is installed, secrets decrypt. ✅
  • Target key is empty → the bundle’s key is written to the target .env. ✅
  • Keys differ → import aborts unless you pass --reset-vault-key (which backs up the target’s existing vault.db first, then writes the bundle’s key).
Terminal window
kazma migrate import my-kazma.zip --workspace /path --reset-vault-key

B. Path translation — embedded paths rewritten automatically

Section titled “B. Path translation — embedded paths rewritten automatically”

A source install at /home/user/kazma has that path baked into workspaces.root_path, snapshots.state_json (full SupervisorState blobs), chat messages, memory episodes, and cron prompts. The importer rewrites them all to the target path, across OS separator conventions.

\Users\me\kazma
# Linux source → Windows target
kazma migrate import my-kazma.zip --workspace "C:\Users\me\kazma"

The rewrite is byte-level substring (not a JSON parse) so it handles the 300+ MB snapshots.db efficiently. Path-prefix ordering prevents partial rewrites (/home/u/kazma won’t corrupt /home/u/kazma-repos/ShipX).

C. Atomic import — staging → backup → swap

Section titled “C. Atomic import — staging → backup → swap”

Import never touches live data mid-flight:

  1. Stage — extract the bundle to kazma-data/.migrate-staging-<ts>/
  2. Path-rewrite the staged copies
  3. Backup live DBs to kazma-data/.migrate-backup-<ts>/
  4. Swap staging → live (WAL-safe, one file at a time)

A failure before the swap leaves live data untouched. The staging dir is preserved on failure for inspection. To roll back: copy the .db files from the backup dir back over the live ones.


When the source is Postgres-backed, the bundle also includes a data/postgres.dump produced by pg_dump -Fc (custom format — handles bytea blobs natively, ~7× smaller than plain text).

The migration engine finds the binaries automatically:

  1. pg_dump / pg_restore on PATH
  2. docker exec ${KAZMA_DB_CONTAINER:-kazma-db} <bin> — the common Docker-deployment default
  3. Clear error with install hint if neither is available

Override the container name:

Terminal window
KAZMA_DB_CONTAINER=my-postgres kazma migrate export --out my-kazma.zip

The target must have KAZMA_DB_BACKEND=postgres + KAZMA_DATABASE_URL set:

Terminal window
export KAZMA_DB_BACKEND=postgres
export KAZMA_DATABASE_URL=postgresql://kazma:kazma_change_me@127.0.0.1:5433/kazma
export KAZMA_DB_CONTAINER=kazma-db-win
kazma migrate import my-kazma.zip --workspace /path/to/kazma --reset-vault-key

pg_restore --clean --if-exists recreates the schema (target DB can be empty), then loads data. The SQLite files (vault, memory, snapshots) are restored alongside.

When pg_dump / pg_restore run via docker exec, they execute inside the container, where Postgres listens on localhost:5432 — not the host’s forwarded port (e.g. 5433). The engine detects the Docker case and overrides automatically. Override the internal port if your container listens elsewhere:

Terminal window
KAZMA_DB_INTERNAL_PORT=5432 # default; change only if your container differs

Terminal window
kazma migrate export [--out PATH] [--no-assets]
FlagDefaultPurpose
--out PATHkazma-bundle-<timestamp>.zipOutput bundle path
--no-assets(assets included)Skip binary assets (smaller bundle for config+data only)
Terminal window
kazma migrate verify BUNDLE [--no-hash]

Checks bundle integrity: structure, manifest compatibility, per-file sha256, vault-key fingerprint, table row counts. --no-hash skips the (slow) hash re-hash for a quick structural check.

Terminal window
kazma migrate import BUNDLE [--workspace PATH] [--reset-vault-key] [--dry-run]
FlagDefaultPurpose
--workspace PATHcurrent directoryTarget workspace root (paths are rewritten to this)
--reset-vault-key(abort on mismatch)Overwrite target’s vault key with the bundle’s (backs up existing vault.db first)
--dry-run(real import)Verify + plan only; no writes

VariableDefaultPurpose
KAZMA_DB_CONTAINERkazma-dbDocker container name for pg_dump / pg_restore discovery
KAZMA_DB_INTERNAL_PORT5432Container-internal Postgres port (when running via docker exec)

See also: Environment variables · Portability · Disaster recovery


Every import creates a pre-import backup at kazma-data/.migrate-backup-<ts>/. To roll back:

Terminal window
# Stop Kazma, then copy the backup .db files back over the live ones
cp kazma-data/.migrate-backup-<ts>/*.db kazma-data/

For Postgres, pg_restore --clean --if-exists is idempotent — re-running the import restores from the bundle cleanly.