Skip to content

Deployment Guide

jinflow separates app (engine + Explorer) from data (tenant KLS files). On top of that split, there are five operating modes. Pick the one that matches your data sensitivity and collaboration needs.

The architectural background is in Operating Modes. This page is the practical how-to.


If you…PickWhy
Are the only user, sensitive dataLocalEverything on your laptop. Simplest. Most private.
Need multi-person access to sensitive dataProxy (P2P2P)KLS stays on your machine. Viewers browse through a tunnel. Ctrl+C vanishes the data.
Have non-sensitive data, want always-on collaborationCloud (R2)KLS uploaded, always available, standard cloud auth.
Need multi-person access but data can’t leave the siteSemi-CloudKLS stays local (via proxy), user activity (SIS) in the cloud.
Want builds to run automatically on pushMake-as-a-ServiceA cloud worker runs pre-make + make on git push or cron. No local build.

All five share the same Explorer, same APIs, same semantics. What varies is where each store lives and who runs the build.


Everything on one machine. The developer’s laptop.

Terminal window
# Install the desktop build
just release --now # or use a released bundle
# Build a tenant locally
jinflow make --tenant numetrix.szo_brig
# Explore locally
jinflow explore --tenant numetrix.szo_brig --port 4000

Auth: none (god mode). Git: optional; push AFS to GitHub when ready. Best for: development, author-only tenants, pre-flight dry runs.


KLS on the data owner’s machine. Explorer in the cloud. Your data. Your machine. Their browser.

This is the primary mode for sensitive data. The KLS never leaves the owner’s machine; the Explorer routes queries through a Cloudflare Tunnel. When you close the laptop, the data disappears from the internet instantly.

Terminal window
# 1. Build the KLS as usual
jinflow make --tenant numetrix.szo_brig
# 2. Start the proxy with a tunnel
jinflow-proxy store/numetrix_szo_brig_kls.duckdb --tunnel
# Output:
# KLS: numetrix_szo_brig_kls.duckdb (89 MB)
# Tunnel: https://amber-fox-23.trycloudflare.com
#
# Registered with proxy.jinflow.io
# Open: https://proxy.jinflow.io/s/k8m2np4qr7st9vwx
#
# Press Ctrl+C to stop

Share the URL with anyone who should have access. When the meeting ends, Ctrl+C unplugs the proxy — the data disappears from the cloud immediately.

Terminal window
# Stealth (default): anyone with the URL can view, no login
jinflow-proxy kls.duckdb --tunnel
# Identified: GitHub sign-in required (unlocks notebook, bookmarks, audit)
jinflow-proxy kls.duckdb --tunnel --require-auth

Read more: P2P2P concept page.

VariablePurpose
JINFLOW_PROXY_TOKENOverride the auto-generated session token
JINFLOW_PROXY_MAX_ROWSCap on rows returned per query (default: 10000)
JINFLOW_PROXY_EXPLORER_URLWhich Explorer to register with (default: https://proxy.jinflow.io)
JINFLOW_PROXY_HEARTBEAT_SECHeartbeat interval (default: 60)
CLOUDFLARED_BINPath to cloudflared binary (if not on PATH)

KLS uploaded to Cloudflare R2. Explorer + SIS in the cloud. Always on.

Use when the data is not sensitive and you want a shareable URL available 24/7.

Terminal window
# Configure R2 credentials
jinflow us --r2-account-id ... --r2-key ... --r2-secret ... --r2-bucket jinflow-demo
# Build locally and push to R2
jinflow make --tenant numetrix.demo
jinflow cloud sync --tenant numetrix.demo

Explorer discovers KLS files in R2, downloads to a local cache, and serves from disk. Background sync checks for updates every 5 minutes (ETag comparison).

Auth: GitHub OAuth for all cloud users.


KLS stays local. SIS in the cloud. No KLS upload.

Use when compliance forbids uploading the KLS but you still want multi-person collaboration (notes, bookmarks, audit). The proxy serves KLS queries; the SIS lives in the cloud.

Terminal window
# Build locally
jinflow make --tenant numetrix.szo_brig
# Start the proxy (KLS only)
jinflow-proxy store/numetrix_szo_brig_kls.duckdb --tunnel --sis-cloud

Auth: GitHub OAuth for cloud users (required for notebook writes). Best for: hospital tenants with compliance requirements on analytical data but not on user activity.


make runs in the cloud. No local machine needed.

The developer pushes AFS changes to GitHub. A cloud worker (GitHub Actions, Fly.io Machine, or Cloudflare Worker) runs pre-makemake → KLS upload. The Explorer serves the result.

Trigger: git push to AFS, scheduled cron, or manual (jinflow make --remote). Auth: GitHub for developers (push triggers build), OAuth for Explorer users. Git: the cloud worker has a deploy key and commits the pre-make step automatically.

This is the endgame: the developer never runs make locally. Everything is CI-driven.


The application package (CLI binary + Explorer) is built once per release and lives under the deploy root (default: ~/.jinflow/deploy/). The deploy root contains only the app — no data.

Terminal window
# Bump version, build, package
just release patch
# Build current version without bumping
just release --now
# Skip tests for faster iteration
just release --now --skip-tests

This produces:

  • jinflow-deploy/_cli/ — PyInstaller binary (Python + dbt + DuckDB)
  • jinflow-deploy/_explorer/ — SvelteKit build + node_modules
  • jinflow-deploy/jinflow — CLI launcher
Terminal window
# CLI (from repo)
jin make --tenant millesime.domaine_zufferey
# Explorer dev server
cd explorer && npm run dev # localhost:4000

Docker is for cloud deployment. Local Explorer runs as a Node.js web server.

Terminal window
# Build the Docker image
scripts/build-docker.sh
# Run with live root mount
docker run -v /path/to/live:/data/live:ro \
-p 4000:4000 \
jinflow-explorer

VariablePurpose
JINFLOW_LIVE_ROOTLive root for tenant discovery
JINFLOW_DB_PATHExplicit KLS path (single-tenant mode)
JINFLOW_AFS_ROOTAFS root for brand config
JINFLOW_SYSTEM_DB_PATHSystem DuckDB (optional)
JINFLOW_SIS_PATHExplicit SIS path (override)
ANTHROPIC_API_KEYClaude API key for AI explanations
JINFLOW_AI_MODELAI model override (default: claude-haiku-4-5-20251001)
KLS_SOURCEDiscovery mode: local, r2, or empty
KLS_LOCAL_DIRLocal directory for KLS discovery
VariablePurpose
JINFLOW_LIVELive root override
JINFLOW_PACKS_ROOTPack root override
JINFLOW_DLZ_ROOTDLZ root override
JINFLOW_TENANTDefault tenant
JINFLOW_DEPLOY_ROOTDeploy root override

See the Mode 2 environment variables above.


PlatformCLIExplorer
macOS (arm64)Native binaryNode.js or Bun
WindowsPyInstaller build (on Windows)Node.js
LinuxPyInstaller build (on Linux)Node.js

  1. Ensure tests pass: just test
  2. Commit all changes
  3. Release: just release patch (or minor, major)
  4. Test the deployed binary: jinflow-deploy/jinflow version
  5. Build tenants: jinflow make --all --sync
  6. Verify Explorer: jinflow explore

jazzisnow jinflow is a jazzisnow product
v0.45.1 · built 2026-04-17 08:14 UTC