Local Development Setup
This guide walks you through setting up a local development environment for lana-bank.
Prerequisites
- Nix with flakes enabled
- Git
- Optional: direnv to load the worktree's Nix environment automatically
The local dependency stack uses Nix and process-compose; Docker and Docker Compose are not required for this workflow.
Quick Start
1. Enter the Development Shell
From the repository root:
make nix-develop
This provides the Rust stable toolchain, Node.js 24, pnpm 11, Python 3.13, PostgreSQL client tools, and sqlx-cli, with database connections and URLs for this worktree. nix develop also loads the development environment; make nix-develop additionally honors Make command-line overrides such as PORTLESS_NAME.
2. Start the Application
make up-app bootstrap tui
This starts dependencies, runs database migrations, starts the Rust backend and Vite frontends in the background, seeds the sandbox chart and module configurations, and attaches the process-compose TUI. make bootstrap uses the El Salvador preset from deploy/components/bootstrap/config-maps.yaml.
For a foreground stack instead, run make run-app; Ctrl+C stops the stack. Run make bootstrap from another development shell if you need the seeded chart and module configurations.
The managed backend defaults to simulated time, frozen at the simulation epoch until advanced. If you need a wall-clock development environment instead, export LANA_DEV_TIME_MODE=normal before starting a fresh stack.
3. Or Run the Backend Separately
For backend-only iteration:
make up-deps
make run-server
make up-deps already runs migrations. Use make setup-db to rerun them after changing a migration; the migrations live in lana/app/migrations/.
A dependency-only stack cannot be expanded in place with make up-app. Use make restart-app to replace it with the full application stack while preserving data.
Development URLs
Portless is the default: each checkout gets a deterministic port range and browser-facing hostnames based on its normalized directory name. For a checkout named lana-bank:
| Service | URL |
|---|---|
| Admin Panel | http://admin.lana-bank.localhost:1355 |
| Admin GraphQL API | http://admin.lana-bank.localhost:1355/graphql |
| Customer GraphQL API | http://app.lana-bank.localhost:1355/graphql |
| Partner Portal | http://partner.lana-bank.localhost:1355 |
| Partner GraphQL API | http://partner.lana-bank.localhost:1355/graphql |
| Keycloak Admin Console | http://keycloak.lana-bank.localhost:1355 |
Replace lana-bank with your checkout's name. make status shows the registered routes. To override the name, pass the same override to stack and shell commands, for example make up-app PORTLESS_NAME=my-branch and make nix-develop PORTLESS_NAME=my-branch.
GraphQL APIs validate Keycloak JWTs in the Rust servers. The Vite dev servers proxy /graphql to their respective APIs for same-origin browser requests. The dependency-only profile registers Keycloak and Jaeger routes; the full app profile also registers the frontend and API routes.
Fixed-Port Mode
Use fixed ports only when parallel worktrees are not needed:
LANA_DEV_PORT_MODE=fixed make up-app
LANA_DEV_PORT_MODE=fixed make nix-develop
In this mode the admin panel uses http://admin.localhost:3001, customer GraphQL uses http://app.localhost:5254/graphql, Keycloak uses http://localhost:8081, and runtime PostgreSQL uses port 5433. These are not the default Portless addresses.
Common Commands
| Command | Purpose |
|---|---|
make up-deps | Start dependencies and run migrations in the background |
make up-app | Start dependencies, backend, and frontends in the background |
make run-app | Run the full stack in the foreground; Ctrl+C tears it down |
make bootstrap | Seed chart and module configurations against a running backend |
make down-deps | Stop this worktree's stack, preserving data |
make restart-app | Restart with the full application graph, preserving data |
make recreate-deps | Wipe .nix-deps/ and restart dependencies |
make recreate-app | Wipe .nix-deps/ and restart the full application |
make status | Show this worktree's routes and processes |
make check-code-rust | Verify Rust code compiles and passes Rust checks |
make check-code-apps | Lint, type-check, and build frontends |
SQLX_OFFLINE=true cargo nextest run | Run all Rust tests |
SQLX_OFFLINE=true cargo nextest run -p core-credit | Run tests for one crate |
make e2e | Run BATS end-to-end tests |
make sdl | Regenerate GraphQL schemas |
make sqlx-prepare | Update SQLx offline query cache |
clean-* and recreate-* delete local state, including the DuckDB warehouse. Use down-* or restart-* when you want to preserve data.
Database Access
Use the environment exported by direnv or make nix-develop, not a hard-coded port or connection string:
psql "$LANA__RUNTIME_DB__PG_CON"
Inspect the DuckDB data warehouse's published serving copy:
duckdb "$LANA__DW_DB__PATH/serve/lana_dw.duckdb" -readonly
The reporting warehouse is not a separate database service. Its root contains the Parquet landing zone, dbt build database, and serving copy; the serving file becomes available after a successful warehouse build. See Data Pipelines.
Environment Variables
The development shell exports worktree-specific values:
| Variable | Purpose |
|---|---|
DATABASE_URL, LANA__RUNTIME_DB__PG_CON | Runtime PostgreSQL connection |
CORE_PG_PORT | Runtime PostgreSQL port |
LANA__DW_DB__PATH | Absolute path to this worktree's .nix-deps/dw warehouse root |
LANA_ADMIN_BASE_URL, LANA_ADMIN_GRAPHQL_URL | Public admin panel and GraphQL URLs |
LANA_APP_BASE_URL, LANA_PARTNER_BASE_URL | Public customer API and partner portal base URLs |
LANA_KEYCLOAK_URL | Direct, local Keycloak URL |
LANA_KEYCLOAK_PUBLIC_URL | Browser-facing Keycloak URL used as the token issuer |
ADMIN_SERVER_PORT, ADMIN_PANEL_PORT | Backend and Vite ports for admin development |
For local realm names and login instructions, see Authentication (Local Dev).