LaserData Cloud
Laser SDK

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 amd64 or arm64 system. Docker picks the matching image, including arm64 on Apple Silicon.

Start the stack

git clone https://github.com/laserdata/laser-stack
cd laser-stack
./scripts/up

The 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/smoke

The 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

ServiceRoleLocal endpoint
LaserData Apache Iggy forkDurable log, authentication, and forwarding of managed requestsTCP 127.0.0.1:8090, HTTP 127.0.0.1:3000
laser-planeViews, queries, key-value state, graph, changes, the filter catalog, authorization, and run read modelsInternal 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-sdk

From 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:query
cd laser-sdk/examples/rust
cargo run --example query

Published package:

cd laser-sdk/examples/python
uv venv
uv pip install laser-sdk
uv run python query.py

Local source:

cd laser-sdk/examples/python
uv sync --project ../../foreign/python --locked --extra testing --extra examples
uv run --project ../../foreign/python python query.py

Run 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

CommandAction
./scripts/upStart in the background and wait until healthy
./scripts/up --foregroundRun attached until Ctrl-C
./scripts/up --buildBuild images from signed, pinned binaries
./scripts/up --random-passwordGenerate a random password for a new data volume
./scripts/smokeCheck 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/downStop services and keep data
./scripts/down --volumesStop services and delete this stack's volumes
./scripts/resetStop services and delete this stack's data after a prompt
./scripts/reset --yesReset without a prompt

Configuration

Edit .env before you start the stack.

VariableDefaultPurpose
LASER_BIND_ADDRESS127.0.0.1Host interface for the Iggy ports
LASER_IGGY_PORT8090Iggy TCP host port
LASER_IGGY_HTTP_PORT3000Iggy HTTP host port
LASER_IGGY_USERNAMEiggyRoot username
LASER_IGGY_PASSWORDlaserRoot password. Letters, digits, ., _, ~, and - only
LASER_START_TIMEOUT120Seconds up waits for each service to become healthy
LASER_IGGY_VERSION, LASER_PLANE_VERSIONTested versionsBinaries that ./scripts/up --build downloads
LASER_SDK_VERSIONTested versionTypeScript SDK version that the smoke test installs
LASER_SMOKE_TIMEOUT300Seconds before the smoke test gives up
LASER_SMOKE_NODE_IMAGEPinned node:22-alpineNode.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/smoke

See the Laser Stack README for image signatures and troubleshooting.

Choose a target

TargetMessages, agents, and sessionsManaged features
Laser StackYesYes, locally through laser-plane
LaserData CloudYesYes, managed
Plain Apache IggyYesNo. 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.

On this page