Skip to content
bitzorcas
中EN

Guide

Local Aspire Orchestration

Use BitzOrcas.AppHost to orchestrate SQL Server, RabbitMQ, Redis, MinIO, schema initializers, LicenseSigner, API, JobHost, and the Vite frontend.

Last updated

BitzOrcas.AppHost is a local-development entry point and is not shipped as a production artifact. It exposes containers, schema initialization, and running Hosts as separate resources so missing business or Quartz tables fail before API/JobHost race ahead.

Actual resource graph

VITE_PROXY_TARGET

AppHost

sqlserver / bitzorcas

rabbitmq

redis

minio

license-signer

frontend / Vite

schema-initializer

quartz-schema-initializer

api

jobhost

Startup sequence:

  1. Run a ten-second docker ps preflight and terminate a timed-out probe.
  2. Start SQL Server, RabbitMQ, Redis, and MinIO.
  3. Run API --init-schema --no-seed in schema-initializer by default. BITZORCAS_ASPIRE_SEED_DEMO=true switches it to --seed-demo. BITZORCAS_ASPIRE_RESET_SCHEMA=true switches it to --reset-schema --force (optionally with seed). Do not pass -- --reset-schema to AppHost; those arguments never reach the initializer.
  4. Run JobHost --init-quartz-schema in quartz-schema-initializer.
  5. API waits for business schema; JobHost waits for Quartz schema.
  6. LicenseSigner starts independently and stays fail-closed without KMS configuration.
  7. The Vite frontend starts in parallel with backend initialization and receives the API port allocated for this AppHost run. Brief proxy failures before API readiness are expected.

Required local parameters

Store development values under AppHost user secrets or equivalent Parameters__<ParameterName> environment variables:

Terminal window
# Store AppHost-managed infrastructure parameters outside the repository.
dotnet user-secrets set "Parameters:sqlserver-password" "<strong-password>" \
--project src/Hosts/BitzOrcas.AppHost
dotnet user-secrets set "Parameters:rabbitmq-user" "bitzorcas" \
--project src/Hosts/BitzOrcas.AppHost
dotnet user-secrets set "Parameters:rabbitmq-password" "<strong-password>" \
--project src/Hosts/BitzOrcas.AppHost
dotnet user-secrets set "Parameters:redis-password" "<strong-password>" \
--project src/Hosts/BitzOrcas.AppHost
dotnet user-secrets set "Parameters:minio-access-key" "bitzorcas-dev" \
--project src/Hosts/BitzOrcas.AppHost
dotnet user-secrets set "Parameters:minio-secret-key" "<strong-password>" \
--project src/Hosts/BitzOrcas.AppHost
# Keep the PII search-hash key stable across restarts.
dotnet user-secrets set "Parameters:pii-search-hash-key" "<stable-random-key>" \
--project src/Hosts/BitzOrcas.AppHost

API still owns Host configuration such as Jwt:*. AppHost injects only declared parameters and resource references; it does not copy arbitrary business secrets.

When Parameters:demo-user-password is missing, scripts/local/bootstrap.sh aspire creates a 10-character policy password (same default as GenerateSecurePassword) and never rotates it automatically. It is stable per workstation rather than a shared plaintext default, and is recorded in ignored mode-0600 .bitzorcas/demo-credentials. Restarting AppHost does not change the secret or rewrite the hint. Existing 44-character Bitz!…Aa1 values are not overwritten. To adopt the current generator, remove that secret and re-run bootstrap; a persist / fast database also needs the ten demo accounts aligned to the new value. See Demo data and seed reference.

Start

Run these from the repository root. Fill missing AppHost / API user-secrets first, then pick one launch command:

Terminal window
# ① Fill missing values only. Existing secrets are kept. No license is issued.
scripts/local/bootstrap.sh aspire
scripts/local/doctor.sh aspire
# ② Prove the Docker daemon is up. AppHost repeats a similar preflight.
docker ps
# ③ Default: create business and Quartz tables, do not seed demo accounts
dotnet run --project src/Hosts/BitzOrcas.AppHost
# ④ First run that needs local admin / host-admin demo accounts
BITZORCAS_ASPIRE_SEED_DEMO=true \
dotnet run --project src/Hosts/BitzOrcas.AppHost
# ⑤ Daily work: persist SQL Server and MinIO; RabbitMQ / Redis stay session-scoped
BITZORCAS_ASPIRE_SEED_DEMO=true \
dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fast
# ⑥ After the database is warm, omit the seed switch
dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fast

The fast launch profile sets ASPIRE_PERSIST_SQLSERVER=true and ASPIRE_PERSIST_MINIO=true. Do not start AppHost with --no-launch-profile unless you also export DOTNET_ENVIRONMENT=Development; otherwise user-secrets are not loaded. If you still bind the Dashboard to HTTP 6888 without a profile, also export ASPIRE_ALLOW_UNSECURED_TRANSPORT=true.

The Dashboard is http://localhost:6888; the repo launch profiles already allow that unsecured URL. Do not remove ASPIRE_ALLOW_UNSECURED_TRANSPORT. AppHost SQL prefers localhost,14333: the fast / persist path pins that port, and a default session uses it when free, falling back to a dynamic DCP port only when another AppHost or leftover container already holds it. The orchestrated frontend uses 5860 when free. Do not commit a fallback random port. First image pull and initial schema creation are slower than a normal Host restart; inspect per-resource timing instead of attributing the whole duration to API startup. Demo passwords are written to the ignored .bitzorcas/demo-credentials file (mode 0600). Do not commit it or copy it to a shared environment.

Defaults and opt-ins

SwitchDefaultWhen true
ASPIRE_PERSIST_VOLUMESOffSQL, RabbitMQ, Redis, and MinIO use persistent volumes
ASPIRE_PERSIST_SQLSERVEROffOnly SQL Server uses a persistent volume
ASPIRE_PERSIST_RABBITMQOffOnly RabbitMQ uses a persistent volume
ASPIRE_PERSIST_REDISOffOnly Redis uses a persistent volume
ASPIRE_PERSIST_MINIOOffOnly MinIO uses a persistent volume
BITZORCAS_ASPIRE_SEED_DEMOOffInitialize schema and seed local demo identities/data
BITZORCAS_ASPIRE_USE_REMOTE_AGILECONFIGOffHosts/initializers read their configured remote nodes
BITZORCAS_AGILECONFIG_CONTAINEROffStart local AgileConfig and enable clients
LicenseManagement:Development:SigningWorkerEnabledOffAPI processes issue/revoke operations

Remote AgileConfig is disabled by default to isolate stale workstation Nodes/Secret and network failures. This is a development default, not a production recommendation.

Demo seeding is also opt-in. A normal startup creates schema without silently creating accounts. When BITZORCAS_ASPIRE_SEED_DEMO is enabled, demo-user-password is exposed only to the one-shot initializer; the long-running API, JobHost, and persisted database do not retain the plaintext.

Persistent volumes

Session lifetime is the default reproducible development path. For daily work, use the fast profile so SQL file metadata and MinIO objects persist together while RabbitMQ and Redis stay clean:

Terminal window
dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fast

The fast profile persists SQL Server and MinIO only. Use ASPIRE_PERSIST_VOLUMES=true when all infrastructure state must persist, or choose individual resources with the four resource-specific switches. Keep credentials stable for every persisted resource. Disabling a switch does not delete an old volume; removal is a separate destructive action.

Resolve targets first:

Terminal window
docker ps -a --filter "label=aspire-resource-name"
docker volume ls

Do not use broad docker system prune --volumes as project cleanup.

AgileConfig

Ordinary database debugging does not need AgileConfig. To use team-managed nodes:

Terminal window
BITZORCAS_ASPIRE_USE_REMOTE_AGILECONFIG=true \
dotnet run --project src/Hosts/BitzOrcas.AppHost

Start the local container only for a self-contained demo:

Terminal window
BITZORCAS_AGILECONFIG_CONTAINER=true \
dotnet run --project src/Hosts/BitzOrcas.AppHost

The current image is linux/amd64 and can fail under QEMU on Apple Silicon. Diagnose it separately from SQL Server, RabbitMQ, and Redis.

LicenseSigner

AppHost always shows license-signer and generates/persists the service bearer shared by API and signer. It does not generate a KMS private key, a verification public key, or an enabled worker.

Both states are legitimate:

  • ordinary business/database debugging: signer readiness is independent;
  • license issuance: configure a versioned Azure key URI, matching public key, and worker.

Follow Online License Issuance and Distribution.

Define successful startup

Resource/endpointExpected
schema-initializerCompletes successfully and exits
quartz-schema-initializerCompletes successfully and exits
SQL/RabbitMQ/Redis/MinIOHealthy
API /health/live200
API /health/readySelected capabilities ready; missing License may fail closed explicitly
JobHost /health/live200
LicenseSigner /health/live200; issuance also requires control-plane readiness

Running is not the same as ready. License readiness failure is not process-start failure.

Common failures

SymptomCheck first
AppHost exits immediatelyDocker Desktop, docker ps, parameter secrets
Schema initialization failsFirst initializer exception, connection, database resource
API does not startWhether schema-initializer completed
JobHost does not startWhether quartz-schema-initializer completed
Authentication fails after restartPersistent volume reused with changed passwords
Remote AgileConfig errorsAccidental opt-in and Host-specific Nodes/Secret
LicenseSigner returns 503Whether issuance is needed; then KMS, receipt directory, public key
Direct upload URL failsMinIO health and browser reachability of the presigned URL
cap.Published does not existUpdate to a build that initializes CAP before seeding, then rerun demo seed
Dirty persist library needs a wipeStop AppHost, start once with BITZORCAS_ASPIRE_RESET_SCHEMA=true (add BITZORCAS_ASPIRE_SEED_DEMO=true if you need demo accounts), then turn RESET_SCHEMA off. Do not pass -- --reset-schema to AppHost

Explicit persist reset

BITZORCAS_ASPIRE_RESET_SCHEMA=true is the only AppHost entry for a destructive rebuild. It makes schema-initializer run --reset-schema --force, dropping business, audit-bucket, and CAP tables before recreating them. Quartz tables are not dropped. It cannot be combined with BITZORCAS_ASPIRE_RESET_DEMO_PASSWORDS. Production / Staging refuse it. Launch profiles leave it off.

Terminal window
BITZORCAS_ASPIRE_RESET_SCHEMA=true \
BITZORCAS_ASPIRE_SEED_DEMO=true \
dotnet run --project src/Hosts/BitzOrcas.AppHost --launch-profile fast

Full semantics are in database initialization.

API and JobHost create the bitzorcas-files bucket idempotently at startup. MinIO enables the existing Files attachment flow used by chat, tickets, and AI. Knowledge-base PDF/Word upload is still not delivered and should not be diagnosed as a MinIO outage.

Differences from production

Local AppHostProduction supplies
Local Docker networkPrivate network, DNS, TLS, firewall
User secrets/parametersSecret store, workload identity, rotation audit
Session resources/local volumesManaged storage, backup, RPO/RTO
Aspire DashboardControlled OTel backend and access
One machineReplicas, failure domains, capacity, rollback
Development schema initializersApproved migrations, backup, rollback plan

AppHost success proves a development topology. It does not replace production IaC, Commercial GA, recovery exercises, or load testing.

See also

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%