Docs/Get startedv0.0.1-preview
Developer quick setup (Docker or Podman)
Run a three-node TulaDB cluster with the dashboard, the REST API, Prometheus and Grafana on your machine with Docker or Podman, from the release's container images, then walk the API with the Postman collection.
The fastest way to see every TulaDB component working together on a developer machine. The eval download starts a three-node cluster with the operator dashboard, the REST API (the Python SDK server), Prometheus and Grafana, from container images that ship in the release itself. No registry login is needed. A Postman collection then walks the API: setup, transfers, an idempotent retry, a decline, a batch, reserve and commit, an explicit reject, queries and metrics. Requests that get a retryable 503 are retried automatically.
It runs on Docker or Podman. On a small laptop, --single runs one node instead of three.
This is for evaluating on one machine. For separate machines with your own certificates, follow Integrated cluster.
Where it comes from. Everything here is the
evaldownload,downloads.tuladb.com/eval/0.0.1-preview/, signed by its release workflow like every other TulaDB download. If Downloads still lists it without hashes and links, its release has not been published yet; [email protected] can tell you when it will be.
What you need
| Docker | Podman | |
|---|---|---|
| Linux (x86_64, arm64) | Docker Engine with the Compose v2 plugin | Podman with podman-compose; rootless is fine |
| macOS (Apple silicon) | Docker Desktop | Podman machine (podman machine init, then podman machine start) |
| Windows | Docker Desktop with WSL 2, run from the WSL shell | Podman machine, run from the WSL shell |
Also:
curl,opensslandtar. They are already on macOS and on most Linux distributions.- About 2.5 GB of free disk, for the images, the downloads and the data.
- Memory for containers: 3 GB for the three-node cluster, 2 GB for
--single. Docker Desktop and Podman machine set this in their own settings. Podman machine starts at 2 GB, so either raise it (podman machine stop && podman machine set --memory 6144 && podman machine start) or use--single. - Postman, for the API walkthrough.
eval.sh uses whichever engine is running; Docker wins if both are. Set EVAL_ENGINE=podman or EVAL_ENGINE=docker to choose.
What runs
| Container | Image | On your machine |
|---|---|---|
| three TulaDB nodes, mutual TLS between them | tuladb-core, built from the published tuladb-installer |
inside the Compose network |
| SDK REST API | tuladb-sdk-server-python |
http://localhost:8080 |
| Dashboard | tuladb-dashboard-backend, tuladb-dashboard-frontend |
http://localhost:3000 |
| Prometheus | pulled from Docker Hub by digest | http://localhost:9090 |
| Grafana, with the six TulaDB dashboards | pulled from Docker Hub by digest | http://localhost:3001 |
--single runs one node, the SDK REST API and the dashboard, without Prometheus and Grafana. The REST API and the dashboard keep ports 8080 and 3000.
The TulaDB images are in the release as <name>-<arch>.tar.gz files, one set for x86_64 and one for arm64. eval.sh takes the set for your engine’s architecture and loads it with docker load or podman load. Every host port is bound to 127.0.0.1 only.
1. Download and verify
V=0.0.1-preview
curl -fsSLO https://downloads.tuladb.com/eval/$V/tuladb-eval-compose-$V.tar.gz
curl -fsSLO https://downloads.tuladb.com/eval/$V/SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS # macOS: shasum -a 256 -c --ignore-missing SHA256SUMS
tar -xzf tuladb-eval-compose-$V.tar.gz && cd tuladb-eval-$V
To check the signature as well, take SHA256SUMS.cosign.bundle and trusted_root.json from the same directory and run the cosign verify-blob command Downloads prints for the eval release.
2. Check the machine
./eval.sh doctor # add --single for the one-node profile
doctor changes nothing. It reports, line by line:
- the tools (
curl,openssl,tar, a SHA-256 tool, andcosignif you have it); - the engine, whether it is running, and its compose;
- the engine’s architecture, which must be
x86_64orarm64, and its memory; - free disk where the stack installs;
- whether the ports are free;
- on Linux, whether SELinux is enforcing;
- with Podman, whether healthchecks can run (see Troubleshooting).
Fix every FAIL line before going on. WARN lines are worth reading, but the stack can start with them.
3. Start it
./eval.sh up # three nodes, dashboard, REST API, Prometheus, Grafana
./eval.sh up --single # or: one node, dashboard, REST API
On first use, up installs into ~/.tuladb-cluster, or ~/.tuladb with --single. Set TULADB_HOME to install somewhere else.
- It downloads the container images for your architecture, and every other file it needs, from
downloads.tuladb.com/eval/0.0.1-preview/, and checks each one against the release’sSHA256SUMS. - It loads the images and creates a local certificate authority with a certificate for each node and client.
- It generates the credentials (
openssl rand, files with mode0600). They are never printed. - It starts the stack.
- It waits until the engines report healthy and the REST API and dashboard answer.
On later runs up just starts the stack. If the first install failed partway, or you unpacked a newer release over it, up runs the installer again. That keeps your certificates and credentials.
Run it next to a full copy of the release directory, with SHA256SUMS beside eval.sh, and it works with no network at all, except for the Prometheus and Grafana images, which come from Docker Hub.
4. Check it
./eval.sh status
It lists the containers and probes every endpoint: the SDK API’s health and routes, the dashboard and its cluster view, and, for the cluster, Prometheus and Grafana. Each should answer 200.
| Address | Sign in | |
|---|---|---|
| Dashboard | http://localhost:3000 |
user admin, password LEDGER_DASHBOARD_PASSWORD in ~/.tuladb-cluster/dashboard.env |
| SDK REST API | http://localhost:8080 |
header X-API-Key: TULADB_SDK_SERVER_API_KEY in ~/.tuladb-cluster/sdk-server.env |
| Grafana | http://localhost:3001 |
user admin, password in ~/.tuladb-cluster/grafana-admin.env |
| Prometheus | http://localhost:9090 |
none |
With --single, the files are in ~/.tuladb, and there is no Grafana or Prometheus. The dashboard’s own API takes LEDGER_DASHBOARD_API_KEY from dashboard.env as its X-API-Key. To call the REST API from a shell without printing the key:
set -a && . ~/.tuladb-cluster/sdk-server.env && set +a
curl -s -H "X-API-Key: $TULADB_SDK_SERVER_API_KEY" http://localhost:8080/v1/version
5. Walk the API in Postman
./eval.sh postman # add --single for the one-node profile
This writes tuladb-eval.local.postman_environment.json, mode 0600, into the install directory. It is the Postman environment for this stack, with its two API keys (gatewayApiKey, dashboardApiKey) filled in. In Postman:
- Import
postman/tuladb-eval.postman_collection.jsonfrom the unpacked bundle, and the environment fileeval.shjust wrote. - Select the TulaDB eval environment.
- Run the collection folder by folder, top to bottom.
| Folder | What it does |
|---|---|
| 1. Health | SDK server health, versions and routes; the cluster as the dashboard sees it |
| 2. Setup | ledger 1 in USD, source EVAL, control account 1000, accounts 1001 to 1003 (1003 with limit_low 0), and funds 1001 with 1,000.00 |
| 3. Transfers | 25.00 from 1001 to 1002; the same request again, which is refused as a duplicate (409) instead of posting twice; a transfer with amount_decimal; a decline (1003 has no funds); a batch of three |
| 4. Two-phase | reserve 7.00 from 1001, list pending reservations, commit |
| 5. Rejects | record an explicit reject, then list rejected transfers |
| 6. Queries | balance, account, history, a transaction by id and by reference (source_id + txn_id), the accounts in ledger 1, every currency balance of 1001 |
| 7. Metrics | from Prometheus: scrape targets up, accepted transfers per node, node roles (skip it with --single) |
Every run uses new txn_ids, so you can run the collection again on the same stack. The collection and its environment template are also published loose on Downloads, and in tuladb-eval-postman-0.0.1-preview.zip, if you only want the Postman files.
6. See it in the dashboard and Grafana
- Dashboard (
http://localhost:3000): Transfers lists what the collection posted; Accounts →1001shows its balance; Rejected shows the explicit reject. - Grafana (
http://localhost:3001, cluster only): folder TulaDB → TulaDB · 0 Overview. The per-node transfers graph shows the collection’s writes, and Fleet health shows the three nodes. The other five dashboards (cluster and consensus, durability and WAL, engine throughput, runtime and security, dedup run tier) are in the same folder; see Grafana and Prometheus.
Day-to-day commands
| Command | What it does |
|---|---|
./eval.sh logs |
follow every service’s logs; ./eval.sh logs node1 sdk-server follows just those |
./eval.sh down |
stop the stack; data and credentials are kept |
./eval.sh up |
start it again |
./eval.sh reset |
delete the data and start again, empty; certificates and credentials are kept |
./eval.sh purge |
stop the stack and delete its data (every volume) |
Every command takes --single. Without it, a command other than up uses whichever profile is installed.
Troubleshooting
A port is already in use. doctor names it. The cluster uses 3000, 3001, 8080, 9090, 7701–7703 and 7801–7803; --single uses 3000, 8080, 7700 and 7800. The two profiles share ports, so run one at a time (./eval.sh down --single before ./eval.sh up, or the other way round).
Rootless Podman. Supported. The nodes run as uid 65532 and the dashboard backend as uid 10001. A one-shot tls-init container copies each one’s certificate and key into a volume that user owns, so no file on your machine needs to change owner.
up waits forever on Podman. Podman runs container healthchecks from systemd timers. Without a systemd user session they never run, and the stack waits on them. That happens over SSH with no lingering, in some containers, and in WSL without systemd. doctor warns about it. Over SSH, loginctl enable-linger $USER and a new login fix it.
podman compose is missing. Install podman-compose: dnf install podman-compose on Fedora and RHEL, apt install podman-compose on Debian and Ubuntu, brew install podman-compose on macOS. eval.sh calls it directly when it is installed.
Permission denied reading a certificate or config (Fedora, RHEL, CentOS Stream). SELinux is enforcing. The installers detect it and add ,z to every host bind mount, which relabels the stack’s own files so containers can read them. The value is TULADB_BIND_LABEL in the install directory’s .env. If you installed while SELinux was permissive and later enabled it, run TULADB_SELINUX_RELABEL=1 ./eval.sh up once. TULADB_SELINUX_RELABEL=0 turns the relabel off.
short-name resolution enforced (Podman). Podman refuses an image name without a registry. The compose files name every image with its registry (Prometheus and Grafana as docker.io/…). If you see this, a hand-edited compose file has a short name.
Apple silicon. The arm64 images run natively on Docker Desktop and Podman machine. If doctor reports x86_64 on an Apple-silicon Mac, the engine is an emulated x86 virtual machine (for example a Colima or Podman machine created for x86_64): the x86_64 images then run under emulation, slowly. Use a native arm64 engine instead.
Not enough memory. doctor reports the memory the engine sees. Docker Desktop: Settings → Resources. Podman machine: podman machine set --memory. Or use --single.
Something else. ./eval.sh logs node1 (or tuladb with --single) shows the engine’s own log. ./eval.sh status shows which endpoint is not answering.
Remove it
./eval.sh purge # stop and delete the data (add --single for that profile)
rm -rf ~/.tuladb-cluster # also delete the certificates and credentials (~/.tuladb for --single)
The loaded images are tagged <registry>/tuladb/<name>:0.0.1-preview, the name the compose files use. docker image ls | grep tuladb or podman image ls | grep tuladb lists them, and docker image rm or podman image rm removes them. They come from the release’s tarballs, not from a registry.
What has been tested
| Setup | Status |
|---|---|
| Docker Desktop on macOS, Apple silicon | full stack, --single, all Postman folders |
| Rootless Podman 5.2 with podman-compose 1.4.1, Fedora 41, SELinux enforcing | full stack, --single, all Postman folders |
| Docker Engine on Linux x86_64 | the x86_64 images are built by the release job; the stack has not yet been run there |
Podman machine on macOS or Windows; Docker Desktop on Windows (WSL 2); podman compose with docker-compose as its provider; rootless Docker |
not yet tested |
Limits of the evaluation stack
- One machine. All three nodes share one disk and one host, so the cluster survives a container being killed, not the machine failing. Performance numbers from it say little about a real deployment.
- Local certificates and generated credentials. Fine for an evaluation; for anything else use your own PKI, as in Integrated cluster.
- No Iceberg exporter. The lake export runs from its own download.
- Evaluation licence. Running TulaDB is covered by the evaluation grant of the TulaDB Source-Available License: internal, non-production evaluation. See Licensing.