Laser Stack
Run Apache Iggy and laser-plane on your machine so every Laser SDK feature works locally
Laser Stack runs the LaserData Apache Iggy fork and laser-plane in Docker for local development, SDK examples, and CI. It waits until both services are healthy and prints a connection string.
Plain Apache Iggy runs messages, agents, and session recording. Queries and views, changes, key-value state, graph, forks, filters, session listings, and managed permissions also need laser-plane. Laser Stack gives you both.
Requirements
- A current Docker Engine or Docker Desktop.
- Docker Compose v2. The scripts stop if Docker is not installed, not running, or has no Compose v2.
- A 64-bit
amd64orarm64system. Docker picks the matching image, includingarm64on Apple Silicon.
Start the stack
git clone https://github.com/laserdata/laser-stack
cd laser-stack
./scripts/upThe first run creates .env from .env.example with mode 600, so only its owner can read it. The script pulls the latest published images and starts both services in the background. When both report healthy, it prints:
export LASER_CONNECTION_STRING='iggy:[email protected]:8090'Copy the printed value into your shell. The default credentials are iggy:laser.
If the registry is unreachable, the script uses cached images. If there are no published or cached images, it builds them from signed binaries.
Check the managed path
./scripts/smokeThe smoke test checks Iggy TCP health and plane readiness. It then installs the published TypeScript SDK in a Node.js container, connects, reads the capabilities, and runs a managed key-value write and read through Iggy and laser-plane.
What runs
| Service | Role | Local endpoint |
|---|---|---|
| LaserData Apache Iggy fork | Durable log, authentication, and forwarding of managed requests | TCP 127.0.0.1:8090, HTTP 127.0.0.1:3000 |
laser-plane | Views, queries, key-value state, graph, changes, the filter catalog, authorization, and run read models | Internal Unix socket shared with Iggy |
Applications use one SDK connection for both. Iggy data and plane data live in separate Docker volumes.
Connect
Export the value from ./scripts/up, then connect:
import { Laser } from "@laserdata/laser-sdk"
await using laser = await Laser.connectEnv()use laser_sdk::prelude::*;
let laser = Laser::connect_env().await?;import laser_sdk as ls
laser = await ls.Laser.connect_env()The environment helpers read LASER_CONNECTION_STRING and the optional LASER_STREAM. See Connect for every option.
Run the SDK examples
The laser-sdk examples run the same steps in each language. Rust needs the toolchain version pinned in rust-toolchain.toml. Python needs 3.10 or later and uses uv. TypeScript needs Node.js 22.14 or later.
git clone https://github.com/laserdata/laser-sdkFrom the directory that holds the clone, run an example. query uses both Iggy and laser-plane:
cd laser-sdk/examples/typescript
npm run setup
npm run example:querycd laser-sdk/examples/rust
cargo run --example queryPublished package:
cd laser-sdk/examples/python
uv venv
uv pip install laser-sdk
uv run python query.pyLocal source:
cd laser-sdk/examples/python
uv sync --project ../../foreign/python --locked --extra testing --extra examples
uv run --project ../../foreign/python python query.pyRun npm run setup once after cloning. It installs dependencies and builds the TypeScript SDK from the clone. Each npm run example:<name> compiles the examples first. Run npm run setup again after you change the SDK source.
Focused examples are log, query, watch, kv, cdc, graph, recall, context, and agent. Larger ones are native-streaming, event-analytics, fleet-tape, firehose, incident-desk, memory, interop, orchestra, governance, and sessions. Rust and TypeScript use hyphenated names. Python files use underscores, such as event_analytics.py.
Each example writes to its own stream, laser-<example>-<language>. A run deletes the previous run's stream first and keeps its own data for you to inspect. Set LASER_STREAM to use a stream of your own. The examples never delete that stream, so repeated runs share its state. Against plain Apache Iggy, a step that needs laser-plane prints the missing capability and exits.
Stack commands
| Command | Action |
|---|---|
./scripts/up | Start in the background and wait until healthy |
./scripts/up --foreground | Run attached until Ctrl-C |
./scripts/up --build | Build images from signed, pinned binaries |
./scripts/up --random-password | Generate a random password for a new data volume |
./scripts/smoke | Check health and readiness, then run a managed SDK key-value round trip |
./scripts/logs [service] | Follow all logs or one service (iggy or plane) |
./scripts/down | Stop services and keep data |
./scripts/down --volumes | Stop services and delete this stack's volumes |
./scripts/reset | Stop services and delete this stack's data after a prompt |
./scripts/reset --yes | Reset without a prompt |
Configuration
Edit .env before you start the stack.
| Variable | Default | Purpose |
|---|---|---|
LASER_BIND_ADDRESS | 127.0.0.1 | Host interface for the Iggy ports |
LASER_IGGY_PORT | 8090 | Iggy TCP host port |
LASER_IGGY_HTTP_PORT | 3000 | Iggy HTTP host port |
LASER_IGGY_USERNAME | iggy | Root username |
LASER_IGGY_PASSWORD | laser | Root password. Letters, digits, ., _, ~, and - only |
LASER_START_TIMEOUT | 120 | Seconds up waits for each service to become healthy |
LASER_IGGY_VERSION, LASER_PLANE_VERSION | Tested versions | Binaries that ./scripts/up --build downloads |
LASER_SDK_VERSION | Tested version | TypeScript SDK version that the smoke test installs |
LASER_SMOKE_TIMEOUT | 300 | Seconds before the smoke test gives up |
LASER_SMOKE_NODE_IMAGE | Pinned node:22-alpine | Node.js image for the smoke test |
Iggy stores the root account in its data volume on first start. Changing the password in .env later does not change an existing volume. To use a random password, reset first:
./scripts/reset --yes
./scripts/up --random-password--random-password refuses to run while the Iggy volume exists or while LASER_IGGY_PASSWORD is set in your shell.
The ports bind to 127.0.0.1 by default, so other machines cannot reach them. The stack has no TLS certificates. Set up Iggy TLS and a trusted CA before you change LASER_BIND_ADDRESS.
To smoke test another npm version or a local .tgz, set LASER_SMOKE_SDK_SPEC in your shell. This leaves .env unchanged:
LASER_SMOKE_SDK_SPEC=/path/to/laser-sdk.tgz ./scripts/smokeSee the Laser Stack README for image signatures and troubleshooting.
Choose a target
| Target | Messages, agents, and sessions | Managed features |
|---|---|---|
| Laser Stack | Yes | Yes, locally through laser-plane |
| LaserData Cloud | Yes | Yes, managed |
| Plain Apache Iggy | Yes | No. Managed calls fail with an unsupported error |
Change LASER_CONNECTION_STRING to switch targets. The code stays the same. Read laser.capabilities() before you use an optional managed feature.