Deployment & Orchestration Guide
Business M supports a highly flexible deployment model, allowing you to run all domain capabilities inside a unified monolith topology or as decoupled, distributed macroservices. This guide outlines all available orchestration layers and deployment tracks.
1. Overview of Deployment Tracks
Section titled “1. Overview of Deployment Tracks”| Track | Target Environment | Purpose | Core Technologies |
|---|---|---|---|
| Track 1: Dev Services | Local Machine | Launching databases & sidecars in background for local process running (m dev) |
Docker Compose (dev/) |
| Track 2: Local Containers | Local Machine | Full containerized building & integration testing of all services locally | Docker Compose (dev/*.local.yml) |
| Track 3: Prod VM Compose | Single-VM / Staging | Production-grade deployment with SSL and host-isolated databases | Docker Compose (deploy/compose) |
| Track 4: Prod Kubernetes | Kubernetes / Enterprise | Auto-scaling, highly resilient enterprise deployments | Helm Chart (deploy/helm) |
| Track 5: Desktop & LAN App | Windows / macOS / Linux | Desktop native installation for single users or offline LAN server setups | Tauri & Binary Sidecars (apps/business-local) |
2. Track 1: Local Development Services
Section titled “2. Track 1: Local Development Services”When developing Business M locally on your machine, you normally run the application code directly on your host using the m dev command. To support this, you only need to run the underlying database and sidecar engines in the background.
All development compose files have been organized into the deploy/compose/dev/ folder to keep the workspace root clean.
2.1 Monolith Dev Infrastructure
Section titled “2.1 Monolith Dev Infrastructure”The monolithic Indie track uses PostgreSQL for relational storage, Valkey (Redis) for state caching, and NATS for event messaging. To spin these up:
docker compose -f deploy/compose/dev/dev.compose.yml up -d- Postgres Port:
5432(with database schema auto-configured) - Valkey Port:
6379 - NATS Port:
4222
2.2 Macroservices Dev Infrastructure (Integrated KurrentDB)
Section titled “2.2 Macroservices Dev Infrastructure (Integrated KurrentDB)”Monolith local development uses standard PostgreSQL for event streams. However, distributed macroservices use specialized engines—TigerBeetle for financial ledger entries and KurrentDB (EventStoreDB) for event sourcing.
To launch the macroservice dev sidecars locally:
# Spins up PostgreSQL, Valkey, NATS, TigerBeetle, and KurrentDBdocker compose -f deploy/compose/dev/dev.compose.yml \ -f deploy/compose/dev/macroservices.compose.yml \ up -d- TigerBeetle Port:
3000(attached to a bridge network) - KurrentDB Port:
2113(backed by persistentkurrent_datavolume)
3. Track 2: Local Container Testing
Section titled “3. Track 2: Local Container Testing”If you want to compile the container images and run the entire stack inside Docker locally (for integration tests or pre-deployment validation), you can leverage the local compose override configurations (*.local.yml).
Because the compose files reside in a subdirectory, they are pre-configured with a build context of ../../../ to correctly find and package the codebase from the repository root.
3.1 Run Monolith Locally in Containers
Section titled “3.1 Run Monolith Locally in Containers”Build and run the full Monolith backend and sidecar services in containers:
docker compose -f deploy/compose/dev/dev.compose.yml \ -f deploy/compose/dev/compose.yml \ -f deploy/compose/dev/compose.local.yml \ up --build -d- App Portal: http://localhost:8000
3.2 Run Macroservices Locally in Containers
Section titled “3.2 Run Macroservices Locally in Containers”Build and execute the distributed services in containers, coordinated behind a local Traefik proxy:
docker compose -f deploy/compose/dev/dev.compose.yml \ -f deploy/compose/dev/macroservices.compose.yml \ -f deploy/compose/dev/macroservices.local.yml \ up --build -d- Traefik Entrypoint Portal: http://localhost:8080 (automatically stripping paths and routing traffic between
shell,finance, andwmsaccording to gateway routing maps).
4. Track 3: Production Single-VM Docker Compose
Section titled “4. Track 3: Production Single-VM Docker Compose”For production deployments on a single virtual machine (VM) or VPS, use the production compose suite located under deploy/compose/.
4.1 Production Design Principles
Section titled “4.1 Production Design Principles”- Host Network Isolation: Keeps your backend databases (PostgreSQL, Redis, NATS, TigerBeetle, KurrentDB) strictly internal. No database ports are bound to the public host interface, preventing external scanning.
- Scalability Enabled: Application containers do not have static
container_namefields. You can scale workers or API gateway pods natively via--scale(e.g.--scale app=3). - Automated SSL/TLS: Traefik v3 proxy handles Let’s Encrypt certificate acquisition automatically via ACME HTTP-01 challenges and routes secure HTTPS (
port 443) traffic. - Database Schema Auto-Migrations: Unified Postgres and keeper migration jobs run automatically on startup to keep database schemas updated.
4.2 Preparation
Section titled “4.2 Preparation”- Navigate to the production compose directory:
Terminal window cd deploy/compose - Copy the production environment example and fill in secure values:
Terminal window cp prod.env.example .env# Open .env and customize DOMAIN, ACME_EMAIL, and POSTGRES_PASSWORD
4.2.1 Security & Tenancy Configuration
Section titled “4.2.1 Security & Tenancy Configuration”Business M’s multi-layer security model is configured entirely through environment variables set in your .env file.
Tenant Mode (M_TENANT_MODE)
Section titled “Tenant Mode (M_TENANT_MODE)”| Value | Adapter | When to Use |
|---|---|---|
implicit (default) |
ImplicitTenantAdapter |
All self-hosted single or multi-company deployments |
header |
HeaderTenantAdapter |
Behind a trusted internal gateway (not for public SaaS) |
registry |
RegistryTenantAdapter |
Full SaaS multi-tenant with cryptographic fact verification |
For a standard production single-tenant deployment, no M_TENANT_MODE configuration is needed. The default implicit mode uses the local CompanyMember DocType to manage which companies each user can access.
Database Routing (M_DB_TIER)
Section titled “Database Routing (M_DB_TIER)”| Value | When to Use |
|---|---|
local (default) |
Single-DB deployments (all deployment tracks unless SaaS) |
shared |
Shared-cluster multi-tenant; framework injects tenant_id column |
dedicated |
Per-tenant dedicated DB, URL fetched from control plane |
Tenant Registry (SaaS mode only)
Section titled “Tenant Registry (SaaS mode only)”If using M_TENANT_MODE=registry, add one of the following to your .env:
# Option 1: Provide the Ed25519 public key directly (air-gapped / pinned key)TENANT_REGISTRY_PUBLIC_KEY=base64encodedpublickey==
# Option 2: Point at the Tenant Registry — key is fetched on startupTENANT_REGISTRY_URL=https://registry.yourdomain.com4.3 Monolith Deployment
Section titled “4.3 Monolith Deployment”Deploy the secure Monolith stack with automated SSL proxying:
docker compose -f docker-compose.base.yml -f docker-compose.monolith.yml -f docker-compose.traefik.yml up -d4.4 Macroservices Deployment (Enterprise)
Section titled “4.4 Macroservices Deployment (Enterprise)”Deploy the distributed microservices stack:
docker compose -f docker-compose.base.yml -f docker-compose.macroservices.yml -f docker-compose.traefik.yml up -d4.5 Optional: Add Event Sourcing (KurrentDB)
Section titled “4.5 Optional: Add Event Sourcing (KurrentDB)”If you configure EVENT_STORE_TYPE=kurrent in your .env file, append the specialized KurrentDB compose file to spin up the secure event store:
docker compose -f docker-compose.base.yml \ -f docker-compose.macroservices.yml \ -f docker-compose.kurrentdb.yml \ -f docker-compose.traefik.yml \ up -d5. Track 4: Production Kubernetes via Helm
Section titled “5. Track 4: Production Kubernetes via Helm”For highly-available, cloud-scale deployments, Business M provides a production-grade Helm chart under deploy/helm/business-m.
5.1 Deployment Modes
Section titled “5.1 Deployment Modes”The primary switch in the Helm chart is the .Values.mode setting, which dictates which topology to build inside your cluster:
mode: monolith: Deploys a single application pod, monolith workers, and Postgres/Valkey/NATS services.mode: macroservices: Deploys separate pods forshell,finance,wms,m-india, WMS workers, and keeper services, managed behind a unified Ingress.
5.2 Basic Monolith Installation
Section titled “5.2 Basic Monolith Installation”Install the chart in monolith mode:
helm install business-m deploy/helm/business-m --set mode=monolith5.3 Basic Macroservices Installation
Section titled “5.3 Basic Macroservices Installation”Install the chart in macroservices mode:
helm install business-m deploy/helm/business-m --set mode=macroservices5.4 Key Configuration Values (in values.yaml)
Section titled “5.4 Key Configuration Values (in values.yaml)”You can fully customize databases and sidecar modes inside values.yaml:
# Mode Select: 'monolith' or 'macroservices'mode: monolith
# Subchart Dependencies (bundled inside the chart)postgres: enabled: true user: "admin" database: "business_m" persistence: size: 8Gi
valkey: enabled: true auth: password: "securepassword"
nats: enabled: true jetstream: enabled: true
# Keeper Backends (double-entry engine type: 'postgres' or 'tigerbeetle')keepers: ledgerType: "postgres"
# Optional External SidecarsexternalConfig: database: url: "postgresql+asyncpg://user:pass@host:5432/dbname" tigerbeetle: addresses: "tb-cluster-ip:3000"5.5 Ingress Strip-prefix Rules
Section titled “5.5 Ingress Strip-prefix Rules”When running in macroservices mode, the Helm chart automatically configures advanced PathPrefix rules. Ingress strip-prefix controllers redirect API calls (e.g. /api/finance/... and /api/wms/...) directly to their respective pods, serving decoupled endpoints under a single domain seamless to the web client.
6. Track 5: Desktop & LAN Native App (Tauri)
Section titled “6. Track 5: Desktop & LAN Native App (Tauri)”For single-desktop offline usage or localized office LAN deployments, Business M provides the business-local native application wrapper, supporting Windows, macOS, and Linux.
6.1 Native Binary Sidecar Architecture
Section titled “6.1 Native Binary Sidecar Architecture”The Tauri app (apps/business-local/) compiles into a native installer, wrapping the web frontend alongside pre-compiled backend binary sidecars (PostgreSQL, Redka, NATS, Traefik, and the monolith backend).
When the user launches the application, Tauri automatically orchestrates the execution of eight background service processes:
- PostgreSQL (relational database engine)
- Redka (high-performance SQLite-backed, Redis-compatible caching engine)
- NATS (event messaging broker)
- Traefik (local routing and SSL gateway proxy)
- Monolith (the core web server backend)
- Worker (background queues queue consumer running
m worker) - Book Keeper (double-entry bookkeeping ledger service)
- Stock Keeper (inventory tracking and valuation service)
All engines bind purely to localhost, creating a fast, zero-configuration local single-desktop environment. On exit, Tauri clean-terminates all sidecar processes.
6.2 Building the App
Section titled “6.2 Building the App”To package the native desktop installers:
- Navigate to the tauri application folder:
Terminal window cd apps/business-local - Install frontend dependencies:
Terminal window pnpm install - Compile the target package (requires Rust and the Tauri CLI tools installed on the host):
This outputs native installers (
Terminal window pnpm tauri build.deb/.rpmon Linux,.msion Windows, or.dmg/.appon macOS) undersrc-tauri/target/release/bundle/.
6.3 Secure LAN Server Mode
Section titled “6.3 Secure LAN Server Mode”business-local can easily be toggled into LAN Server Mode, allowing other machines in the same office or local network to securely connect:
- Custom SSL Certificate Integration: You can load your secure LAN SSL certificates (
lan.crtandlan.key) directly through the desktop application’s user interface. For CLI-only or headless environments, you can simply place yourlan.crtandlan.keyfiles in the dedicated configuration directory. - Automated Traefik Service: Once the certificate files are loaded or placed, the bundled Traefik sidecar automatically picks them up, configures the routes, and serves the encrypted HTTPS endpoints, ensuring a completely zero-config secure proxy setup.
6.4 Debian Registry Distribution (APT)
Section titled “6.4 Debian Registry Distribution (APT)”In addition to direct downloads from GitLab Releases, Linux desktop packages are automatically published to the project’s native GitLab Debian Package Registry (apt repository) during CI/CD release pipelines.
This allows Debian/Ubuntu users to configure the repository in their package manager for automated updates.
6.4.1 Adding the Repository to sources.list
Section titled “6.4.1 Adding the Repository to sources.list”To configure the APT source, download the registry’s public GPG signing key and add the repository entry (no token required since the repository is public):
PROJECT_ID="79588051"
# Import GPG signing keycurl -sL "https://gitlab.com/api/v4/projects/${PROJECT_ID}/packages/debian/repository.key" | gpg --dearmor | sudo tee /usr/share/keyrings/business-m-archive-keyring.gpg > /dev/null
# Add repository list entryecho "deb [signed-by=/usr/share/keyrings/business-m-archive-keyring.gpg] https://gitlab.com/api/v4/projects/${PROJECT_ID}/packages/debian stable main" | sudo tee /etc/apt/sources.list.d/business-m.list6.4.2 Installing and Updating the App
Section titled “6.4.2 Installing and Updating the App”# Update local package indexsudo apt-get update
# Install the applicationsudo apt-get install business-local7. Automated Releases & Container Versioning
Section titled “7. Automated Releases & Container Versioning”To ensure absolute clarity, reliability, and security in production deployments, Business M utilizes a centralized GitLab CI/CD release workflow.
7.1 Authoritative Meta-Version
Section titled “7.1 Authoritative Meta-Version”The meta-version of the entire platform is authoritatively governed by the business-m-shell package (apps/business-m/pyproject.toml). Any commit that affects global code automatically bumps the shell version (e.g., from 0.1.0 to 1.0.0).
When a release prepare runs:
m release preparesynchronizes the bumped meta-version intorelease-config.jsonsync targets:- Helm Chart (
Chart.yaml): Automatically updates theappVersion(injecting the current platform meta-version to pull matched container images). The chartversionitself is kept completely independent and is bumped manually by developers for template-only adjustments. - Production Compose (
prod.env.example): Automatically updates the defaultIMAGE_TAGto point to the new release tag instead oflatest.
- Helm Chart (
7.2 Helm Version Integrity Guard
Section titled “7.2 Helm Version Integrity Guard”To prevent human error during independent versioning, the GitLab CI pipeline implements an automated Version Guard (lint-helm-version job in the lint stage):
- Change Detection: It automatically scans the commit diff to see if any Helm files (templates, helper templates, or
values.yaml) have been modified compared to themainbranch. - Enforced Bump: If chart configurations were modified but the
versionfield insideChart.yamlremains identical tomain, the build is failed with a clear validation error. - Duplicate Push Protection: The GitLab registry enforces strict unique constraints and rejects duplicate pushes, ensuring that once validated, a published Helm package version is immutable.
7.3 Triple-Tagging Container Scheme
Section titled “7.3 Triple-Tagging Container Scheme”To balance unified global deployments with independent package agility, all microservice container images compiled in CI are dual/triple-tagged:
- Release-Library Tag (
<business-m-version>-<lib-version>): e.g.,finance:1.16.0-0.8.2The definitive production tag. It explicitly maps the core gateway shell version (1.16.0) with the specific service library version (0.8.2). - Global Meta-Version Tag (
<business-m-version>): e.g.,finance:1.16.0Allows Helm charts or standard compose files to pull all microservice images under a single synchronized release version. - Library-Specific Tag (
<lib-version>): e.g.,finance:0.8.2Used for granular dependency tracking of individual service updates. - Latest Tag (
latest): Assigned automatically on default branch (main) builds.
7.3 Multi-Artifact Release Packages
Section titled “7.3 Multi-Artifact Release Packages”Every git-tagged release of the platform automatically compiles and distributes three public channels in GitLab:
- Public Helm Chart Registry (Recommended): Published directly to the GitLab Helm Package Registry, enabling anonymous public discovery and standard installation without any 401 basic authentication blocks:
(For private operator teams or OCI-specific workflows, the packaged chart is also mirrored to the OCI registry at
Terminal window helm repo add business-m https://gitlab.com/api/v4/projects/79588051/packages/helm/stablehelm repo updatehelm install business-m business-m/business-m --version <version>oci://registry.gitlab.com/castlecraft/business-m/charts/business-mwhich requires standard container registry credentials). - VM Compose Release Tarball: Bundles all files under
deploy/compose/(excluding localdevconfigurations) into a zipped packagebusiness-m-compose.tar.gzand pushes it to the GitLab Generic Packages Registry:This allows VM operators to download, extract, and start the production stack with a single command without cloning the entire monorepo.Terminal window curl -L -O https://registry.gitlab.com/castlecraft/business-m/packages/generic/business-m-compose/<version>/business-m-compose.tar.gz - Desktop & LAN Native Installers (Tauri): Automatically compiles the native Linux GUI application alongside its five pre-compiled binary sidecars (orchestrating eight background service processes) into optimized, offline-ready desktop installers:
AppImage: A portable, zero-installation single file that functions exactly like a click-and-run binary..debpackage: A standard installer for Debian/Ubuntu environments that handles menus, icons, and system layout automatically.- These artifacts are compiled via the automated
build-desktop-linuxjob in.gitlab/ci/desktop.ymlon release tags, or manually onmainbranch builds.