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.
Which Mode Should I Use?
Section titled “Which Mode Should I Use?”| If you… | Pick | Why |
|---|---|---|
| Are the only user, sensitive data | Local | Everything on your laptop. Simplest. Most private. |
| Need multi-person access to sensitive data | Proxy (P2P2P) | KLS stays on your machine. Viewers browse through a tunnel. Ctrl+C vanishes the data. |
| Have non-sensitive data, want always-on collaboration | Cloud (R2) | KLS uploaded, always available, standard cloud auth. |
| Need multi-person access but data can’t leave the site | Semi-Cloud | KLS stays local (via proxy), user activity (SIS) in the cloud. |
| Want builds to run automatically on push | Make-as-a-Service | A 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.
Mode 1 — Local
Section titled “Mode 1 — Local”Everything on one machine. The developer’s laptop.
# Install the desktop buildjust release --now # or use a released bundle
# Build a tenant locallyjinflow make --tenant numetrix.szo_brig
# Explore locallyjinflow explore --tenant numetrix.szo_brig --port 4000Auth: none (god mode). Git: optional; push AFS to GitHub when ready. Best for: development, author-only tenants, pre-flight dry runs.
Mode 2 — Proxy (P2P2P)
Section titled “Mode 2 — Proxy (P2P2P)”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.
# 1. Build the KLS as usualjinflow make --tenant numetrix.szo_brig
# 2. Start the proxy with a tunneljinflow-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 stopShare the URL with anyone who should have access. When the meeting ends, Ctrl+C unplugs the proxy — the data disappears from the cloud immediately.
Stealth vs Identified
Section titled “Stealth vs Identified”# Stealth (default): anyone with the URL can view, no loginjinflow-proxy kls.duckdb --tunnel
# Identified: GitHub sign-in required (unlocks notebook, bookmarks, audit)jinflow-proxy kls.duckdb --tunnel --require-authRead more: P2P2P concept page.
Proxy environment variables
Section titled “Proxy environment variables”| Variable | Purpose |
|---|---|
JINFLOW_PROXY_TOKEN | Override the auto-generated session token |
JINFLOW_PROXY_MAX_ROWS | Cap on rows returned per query (default: 10000) |
JINFLOW_PROXY_EXPLORER_URL | Which Explorer to register with (default: https://proxy.jinflow.io) |
JINFLOW_PROXY_HEARTBEAT_SEC | Heartbeat interval (default: 60) |
CLOUDFLARED_BIN | Path to cloudflared binary (if not on PATH) |
Mode 3 — Cloud (R2)
Section titled “Mode 3 — Cloud (R2)”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.
# Configure R2 credentialsjinflow us --r2-account-id ... --r2-key ... --r2-secret ... --r2-bucket jinflow-demo
# Build locally and push to R2jinflow make --tenant numetrix.demojinflow cloud sync --tenant numetrix.demoExplorer 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.
Mode 4 — Semi-Cloud
Section titled “Mode 4 — Semi-Cloud”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.
# Build locallyjinflow make --tenant numetrix.szo_brig
# Start the proxy (KLS only)jinflow-proxy store/numetrix_szo_brig_kls.duckdb --tunnel --sis-cloudAuth: GitHub OAuth for cloud users (required for notebook writes). Best for: hospital tenants with compliance requirements on analytical data but not on user activity.
Mode 5 — Make-as-a-Service
Section titled “Mode 5 — Make-as-a-Service”
makeruns 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-make → make → 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.
App Deployment
Section titled “App Deployment”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.
Desktop Release
Section titled “Desktop Release”# Bump version, build, packagejust release patch
# Build current version without bumpingjust release --now
# Skip tests for faster iterationjust release --now --skip-testsThis produces:
jinflow-deploy/_cli/— PyInstaller binary (Python + dbt + DuckDB)jinflow-deploy/_explorer/— SvelteKit build + node_modulesjinflow-deploy/jinflow— CLI launcher
Development
Section titled “Development”# CLI (from repo)jin make --tenant millesime.domaine_zufferey
# Explorer dev servercd explorer && npm run dev # localhost:4000Docker (Cloud Only)
Section titled “Docker (Cloud Only)”Docker is for cloud deployment. Local Explorer runs as a Node.js web server.
# Build the Docker imagescripts/build-docker.sh
# Run with live root mountdocker run -v /path/to/live:/data/live:ro \ -p 4000:4000 \ jinflow-explorerEnvironment Variables
Section titled “Environment Variables”Explorer
Section titled “Explorer”| Variable | Purpose |
|---|---|
JINFLOW_LIVE_ROOT | Live root for tenant discovery |
JINFLOW_DB_PATH | Explicit KLS path (single-tenant mode) |
JINFLOW_AFS_ROOT | AFS root for brand config |
JINFLOW_SYSTEM_DB_PATH | System DuckDB (optional) |
JINFLOW_SIS_PATH | Explicit SIS path (override) |
ANTHROPIC_API_KEY | Claude API key for AI explanations |
JINFLOW_AI_MODEL | AI model override (default: claude-haiku-4-5-20251001) |
KLS_SOURCE | Discovery mode: local, r2, or empty |
KLS_LOCAL_DIR | Local directory for KLS discovery |
| Variable | Purpose |
|---|---|
JINFLOW_LIVE | Live root override |
JINFLOW_PACKS_ROOT | Pack root override |
JINFLOW_DLZ_ROOT | DLZ root override |
JINFLOW_TENANT | Default tenant |
JINFLOW_DEPLOY_ROOT | Deploy root override |
Proxy / P2P2P
Section titled “Proxy / P2P2P”See the Mode 2 environment variables above.
Platform Requirements
Section titled “Platform Requirements”| Platform | CLI | Explorer |
|---|---|---|
| macOS (arm64) | Native binary | Node.js or Bun |
| Windows | PyInstaller build (on Windows) | Node.js |
| Linux | PyInstaller build (on Linux) | Node.js |
Release Checklist
Section titled “Release Checklist”- Ensure tests pass:
just test - Commit all changes
- Release:
just release patch(orminor,major) - Test the deployed binary:
jinflow-deploy/jinflow version - Build tenants:
jinflow make --all --sync - Verify Explorer:
jinflow explore
Related
Section titled “Related”- Operating Modes — the architectural background
- P2P2P — Data Sovereignty — deep dive on Mode 2
- Make Guide — day-to-day build usage