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.

On this page
  1. What you need
  2. What runs
  3. 1. Download and verify
  4. 2. Check the machine
  5. 3. Start it
  6. 4. Check it
  7. 5. Walk the API in Postman
  8. 6. See it in the dashboard and Grafana
  9. Day-to-day commands
  10. Troubleshooting
  11. Remove it
  12. What has been tested
  13. Limits of the evaluation stack

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 eval download, 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, openssl and tar. 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, and cosign if you have it);
  • the engine, whether it is running, and its compose;
  • the engine’s architecture, which must be x86_64 or arm64, 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.

  1. 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’s SHA256SUMS.
  2. It loads the images and creates a local certificate authority with a certificate for each node and client.
  3. It generates the credentials (openssl rand, files with mode 0600). They are never printed.
  4. It starts the stack.
  5. 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:

  1. Import postman/tuladb-eval.postman_collection.json from the unpacked bundle, and the environment file eval.sh just wrote.
  2. Select the TulaDB eval environment.
  3. 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 → 1001 shows 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.