Bichon Docs

bichon-cli — Import & Export

bichon-cli is a fully interactive menu-driven client that talks to a running Bichon server over its REST API. It takes a single option:

./bichon-cli                # uses ./config.toml
./bichon-cli -c other.toml  # alternate config file

Configuration

On first run it prompts for the server Base URL and an API token, then offers to save them for future use. The config file is plain TOML:

base_url = "http://localhost:15630"
api_token = "…"

Create a long-lived API token in the WebUI (Settings → API Tokens) or via POST /api/v1/access-token. The token's user needs the permissions for whatever you drive from the CLI (see below).

Import

After choosing a target account, pick one of four methods:

MethodDescription
EML DirectoryRecursively scan a directory tree of .eml files; preserves folder structure
MBOXStream-import from a single .mbox archive (including Gmail's MBOX variant)
ThunderbirdImport directly from a local Thunderbird profile directory
PSTImport from Outlook Personal Storage .pst files

Requirements specific to import:

  • Only nosync-type accounts can be import targets — accounts that archive from a live IMAP server are excluded, so an import can never race the sync pipeline. Create a nosync account in the WebUI first if you have none. See Accounts.
  • Your token's user needs data:import:batch permission on that account (or be an administrator with system:root). Accounts you cannot import into are shown as [NO PERMISSION].

Export

Three modes:

ModeDescription
Export by saved search (recommended)Pick a format first: Mbox (whole messages, needs an email saved search) or Attachments (a deduplicated zip, needs an attachment saved search). Then pick the saved search, preview the scope, confirm — the export runs as a server-side job and the CLI polls it and downloads the artifact
Export entire account (legacy)Downloads every message in an account (100 per page) and writes the MBOX locally; shows account statistics first and checks free disk space with a 10% buffer
Verify an export job (compliance)Verify a previously run export job — confirms the exported MBOX messages, or the zip's attachment hashes, match what the server holds

Server-side jobs keep their artifact for one hour after finishing; download promptly. See Import & Export for the on-disk layout and limits.

All imports are processed server-side — the server handles MIME parsing, indexing, deduplication, and storage. The WebUI upload limits (1 GB MBOX / 2 GB PST) do not apply to the CLI path; for larger archives use bichon-cli.

bichon-admin — Administration

./bichon-admin

bichon-admin is a separate binary from the server — it is not built by the server build. The Community workspace produces it with cargo build --release -p bichon-admin; on the Pro/Enterprise tree the same command is cargo build --release -p bichon-pro --bin bichon-admin, which builds the extended variant described at the end of this section.

Interactive menu with five operations:

OperationDescription
Reset Admin PasswordReset the built-in admin password when locked out
Migrate v0.3.7 → v2.xNon-destructive migration from legacy Tantivy-based storage to v2.x — see the step-by-step guide
Migrate v1.x → v2.xBlob-only migration from Fjall to bichon-blob (indexes and metadata untouched) — see the step-by-step guide
Restore a Backup PointDisaster recovery — restore a backup point into an empty directory
Rebuild Search IndexesRebuild the Tantivy indexes after an index-format change — see Rebuild Search Indexes

Rebuild search indexes (reindex)

Releases that change the search index format require a one-time rebuild. It can be run non-interactively — pass --yes to skip the confirmation prompt, which is required when stdin is not a terminal (init containers, Kubernetes Jobs, CI):

./bichon-admin reindex --yes --bichon-root-dir /var/lib/bichon

Without a terminal and without --yes, the command refuses with exit code 2 instead of rebuilding (it no longer silently cancels with exit code 0). --yes only skips the confirmation — all pre-checks still run.

Use --bichon-index-dir / --bichon-data-dir (or BICHON_INDEX_DIR / BICHON_DATA_DIR) when the server was started with custom directories — they take the same parent paths. The command keeps the previous index as <index-parent>/bichon-indices.old-<timestamp> and never deletes it, so a failed or unsatisfactory rebuild can be rolled back. The full procedure, directory layout and rollback steps are on the Rebuild Search Indexes page.

Disaster-recovery restore (non-interactive)

The restore can also run without the menu, which is what you want on a fresh recovery box and in scripts:

./bichon-admin restore --config restore-config.json --into /path/to/empty-dir
FlagEnv equivalentDescription
--config (-c)—Required. JSON config file describing the backup target (S3-compatible store or local directory)
--intoBICHON_RESTORE_INTORequired. Empty target directory to restore into
--pointBICHON_RESTORE_POINTRestore point to use — a manifest id, the object name from the target listing (m-<id> / m-<id>.json.gz), or LATEST (default: LATEST)
--index-dirBICHON_RESTORE_INDEX_DIRTarget Tantivy index parent dir (default <into>/bichon-indices)
--data-dirBICHON_RESTORE_DATA_DIRTarget blob data parent dir (default <into>/bichon-storage)
--root-dirBICHON_ROOT_DIRLive data root of an existing install on the same box, if any — restore targets are refused if they touch it
--bichon-restore-verify-only—Verify every object of the restore point against its manifest and write nothing (Pro build only)

Omitting --point restores the latest committed backup point — there is no need to pass --point LATEST. To restore an older point, take the id of its manifest object from the backup target (<prefix>/v1/meta/m-<id>.json.gz) and pass it, e.g. --point 0192a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b.

--bichon-restore-verify-only is a flag, not a subcommand — it is still a restore, and it writes nothing, so --into is not required with it. That makes it the safe way to answer "is this backup actually restorable?" before committing to a recovery. It exists only in the Pro build.

The config file describes which target to read the restore point from. target_type defaults to "s3", so a file written before local targets existed keeps working unchanged.

S3-compatible store — only s3_endpoint and s3_bucket are mandatory. Read-only credentials are sufficient for a restore: it only issues GET requests against the bucket. Write access is needed for backups themselves (object uploads, retention pruning), not for restoring from them.

{
  "s3_endpoint": "https://s3.example.com",
  "s3_bucket": "bichon-backups",
  "prefix": "mail-archive",
  "s3_region": "eu-west-1",
  "s3_access_key": "…",
  "s3_secret_key": "…"
}

Local directory — the directory must exist and be mounted; a path whose volume is not attached is refused rather than silently read as an empty directory.

{
  "target_type": "local",
  "local_dir": "/mnt/backup",
  "prefix": "mail-archive"
}

prefix is the sub-location the restore points live under — the object-store prefix for an S3 target, the subdirectory of local_dir for a local one — and must match what the backups used. It defaults to bichon-backup.

Working out which directory is which

Both targets use the same layout, and it is worth knowing it, because a backup directory on disk does not tell you what to put in the config file by itself:

<local_dir>/          ← the "local_dir" you put in the config file
└── <prefix>/         ← the "prefix" (default: bichon-backup)
    └── v1/
        ├── meta/     ← LATEST pointer, plus one m-<id>.json.gz manifest per restore point
        └── obj/      ← immutable content-addressed objects

So a directory that looks like /mnt/backup/bichon-backup/v1/meta/LATEST means local_dir: "/mnt/backup" with the default prefix — the bichon-backup component is the prefix, not part of the path. On an S3 target the same three levels sit inside the bucket, below the prefix.

To list the restore points you have, look in <local_dir>/<prefix>/v1/meta/ (or the equivalent prefix in the bucket): LATEST names the newest one, and each m-<id>.json.gz is one restore point whose id you can pass to --point.

Safety rules: the target directory must be empty and must never overlap the live data root of an existing install — a restore is only ever into a fresh location, which you then point Bichon at via BICHON_ROOT_DIR.

Note (Pro): The Pro build ships its own bichon-admin with the same CLI and menus, extended with the audit replayer (audit deltas are replayed on restore) and the --bichon-restore-verify-only drill flag. See Backup & Disaster Recovery (Pro).

"Restore" in Bichon — two different things

  • Disaster-recovery restore (this subcommand): rebuild the entire archive — index, blobs, metadata — from a backup point into a fresh directory.
  • Message restore (WebUI / REST): push archived messages back to their source IMAP server, e.g. after accidental deletion on the mail server. It is not an undo of deletion — deletes in Bichon are permanent, with no trash or recycle bin. See Introduction (Message Lifecycle).

On this page