Docs/Get startedv0.0.1-preview

Install the components

Download, verify, install and connect every TulaDB 0.0.1-preview component — the server, tulactl, the SDKs, the dashboard, the Prometheus exporter, the Grafana dashboards, the Iceberg exporter and the Docker and Postman evaluation bundle.

On this page
  1. Verify any download
  2. Server
  3. tulactl
  4. Prometheus exporter
  5. SDKs
  6. Dashboard
  7. Iceberg exporter
  8. Grafana and Prometheus
  9. Upgrade and remove

TulaDB 0.0.1-preview is several programs. The server is one install; everything else connects to it as a client. This page covers each one: what it is, what to download, how to verify and install it, how to start it, and how it reaches the cluster. To run them all together, follow Integrated cluster; to try everything on one machine first, Quick eval with Docker and Postman starts the whole stack from the release’s container images.

Component Download Runs on Talks to the cluster over
Server (tuladbd) core: tuladb-installer each node itself (ports 7700, 7800, 8700, 9700)
tulactl installed with the server any node client port 7700, mTLS
Prometheus exporter installed with the server, or standalone: prometheus-exporter each node, beside tuladbd nothing: it reads the node’s metrics file
SDKs sdk your application client port 7700 (writes), query port 7800 (reads), mTLS
Dashboard dashboard an operations host ports 7700 and 7800, mTLS
Iceberg exporter exporter an operations host query port 7800, mTLS
Grafana dashboards grafana-dashboards your Grafana Prometheus, which scrapes the Prometheus exporters on port 9145
Developer quick setup eval: container images, Compose bundle, Postman collection one machine with Docker or Podman everything, in containers (or one node with --single)

Availability. Every component above is a published, signed 0.0.1-preview download on Downloads, which lists each file with its size, SHA-256 and link. The developer quick setup (eval) is the last to be released: if Downloads lists it without hashes and links, it has not been published yet.

Verify any download

Each download has its own directory on downloads.tuladb.com, signed by its own release workflow. Next to the files you take, download SHA256SUMS, SHA256SUMS.cosign.bundle and trusted_root.json from the same directory, then check the signature and the hashes with cosign:

# the sdk download; for another product, change the repository and workflow
# in the identity (table below)
cosign verify-blob --offline --trusted-root trusted_root.json \
  --bundle SHA256SUMS.cosign.bundle \
  --certificate-identity https://github.com/TulaDB/tuladb-sdk/.github/workflows/release-preview.yml@refs/tags/v0.0.1-preview \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS       # macOS: shasum -a 256 -c --ignore-missing SHA256SUMS
Product Directory Signer workflow (the identity above)
core https://downloads.tuladb.com/core/0.0.1-preview/ tuladb-core, release.yml
sdk https://downloads.tuladb.com/sdk/0.0.1-preview/ tuladb-sdk, release-preview.yml
dashboard https://downloads.tuladb.com/dashboard/0.0.1-preview/ tuladb-dashboard, release.yml
exporter https://downloads.tuladb.com/exporter/0.0.1-preview/ tuladb-iceberg-exporter, release.yml
prometheus-exporter https://downloads.tuladb.com/prometheus-exporter/0.0.1-preview/ tuladb-core, release-prometheus-exporter.yml, at tag prometheus-exporter-v0.0.1-preview
grafana-dashboards https://downloads.tuladb.com/grafana-dashboards/0.0.1-preview/ tuladb-core, release-grafana-dashboards.yml, at tag grafana-dashboards-v0.0.1-preview
eval https://downloads.tuladb.com/eval/0.0.1-preview/ tuladb-install, release.yml

Every identity ends in @refs/tags/v0.0.1-preview, except the Grafana dashboards’, which ends in @refs/tags/grafana-dashboards-v0.0.1-preview, and the standalone Prometheus exporter’s, which ends in @refs/tags/prometheus-exporter-v0.0.1-preview.

The identity is a path inside the signature, not a link: the repositories are private. Downloads prints the exact command for each product. Do not install a file if either check fails.

Server

tuladbd installs only through tuladb-installer: one static binary per platform (Linux x86_64 and arm64 for servers, macOS on Apple silicon for development) that carries the whole server release. There is no separate package to download.

chmod +x tuladb-installer-0.0.1-preview-linux-x86_64
sudo ./tuladb-installer-0.0.1-preview-linux-x86_64 install --single          # one node, started
sudo ./tuladb-installer-0.0.1-preview-linux-x86_64 install --cluster-node ... # prepared, not started
sudo ./tuladb-installer-0.0.1-preview-linux-x86_64 status

The installer puts tuladbd, tulactl, tuladb_backup, tuladb_upgrade, tuladb_verify_store and tuladb_prometheus_exporter in /opt/tuladb, and links the CLIs (not the exporter) into /usr/bin. Install TulaDB covers every step, the cluster, upgrade and uninstall --purge --yes-delete-financial-data.

tulactl

The command-line client. It comes with the server, so every node has it at /usr/bin/tulactl (on macOS, ~/.tuladb/tulactl). The release has no separate tulactl download.

On a cluster node every port requires a client certificate, so tulactl connects with TLS and a certificate signed by the cluster’s CA. Its global flags are --host, --port, --tls, --tls-ca-file, --tls-cert-file, --tls-key-file and --tls-server-name, and each has an environment fallback:

export TULADB_CLIENT_HOST=10.0.0.1 TULADB_CLIENT_PORT=7700
export TULADB_CLIENT_TLS_ENABLED=1
export TULADB_CLIENT_TLS_CA_FILE=$HOME/pki/ca.crt
export TULADB_CLIENT_TLS_CERT_FILE=$HOME/pki/tuladb-operator.crt
export TULADB_CLIENT_TLS_KEY_FILE=$HOME/pki/tuladb-operator.key
tulactl ready --json
tulactl --api-key "$KEY" ledger-create --ledger 10 --currency 840 --yes

The certificate proves who is connecting; its principal needs a role_grant on the nodes, or the connection gets the node’s default_role, denied. An --api-key then authenticates as the key’s principal: the installer’s admin key is tuladb-admin, granted cluster-admin. tulactl connects to one node per command; a follower forwards writes to the leader. tulactl lists every command.

Prometheus exporter

tuladb_prometheus_exporter turns one node’s metrics into Prometheus series. tuladbd writes its metrics to <data_dir>/runtime/metrics.json (/var/lib/tuladb/runtime/metrics.json on an installed node), and the exporter reads that file: it opens no connection to the node, needs no certificate and no role. Run one beside each node.

It installs with the server, at /opt/tuladb/tuladb_prometheus_exporter. The installer does not create a service for it, so add one on each node. The cluster name labels every series (cluster="..."); it comes from a small configuration file, and without one it is local:

sudo install -d -m 0755 /etc/tuladb
echo 'cluster_name = "ledger-eval"' | sudo tee /etc/tuladb/prometheus-exporter.toml
sudo tee /etc/systemd/system/tuladb-prometheus-exporter.service >/dev/null <<'EOF'
[Unit]
Description=TulaDB Prometheus exporter
After=tuladbd.service

[Service]
User=tuladb
Group=tuladb
ExecStart=/opt/tuladb/tuladb_prometheus_exporter --config /etc/tuladb/prometheus-exporter.toml --snapshot /var/lib/tuladb/runtime/metrics.json --listen 10.0.0.1:9145
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable --now tuladb-prometheus-exporter
curl -s http://10.0.0.1:9145/metrics | grep '^tuladb_up'

Use the node’s own address in --listen. The default is 127.0.0.1:9145. The endpoint serves /metrics and /healthz over plain HTTP with no authentication: the cluster’s mTLS covers the TulaDB ports, not this one. Let only your Prometheus host reach port 9145 (a firewall rule), or put an HTTPS proxy in front of it. A snapshot older than 30 seconds (--max-snapshot-age) turns tuladb_up to 0, so a stalled node shows up as down instead of as stale numbers. Observability describes the metrics.

Flag Default
--config PATH config/tpe.toml configuration file (bind, metrics_file, cluster_name, max_snapshot_age_seconds); a missing file is allowed
--listen HOST:PORT 127.0.0.1:9145 IPv4 bind address
--snapshot PATH reports/runtime/metrics.json the node’s metrics file; on an installed node /var/lib/tuladb/runtime/metrics.json
--max-snapshot-age S 30 older than this: tuladb_up 0 and HTTP 503
--once print one scrape to stdout and exit
--version print the version and exit (the standalone release)

Standalone exporter

The prometheus-exporter download is the same exporter on its own release line, signed by tuladb-core’s release-prometheus-exporter.yml at tag prometheus-exporter-v0.0.1-preview. Use it when you want an exporter release apart from the server’s, or a metrics agent managed separately; on a node installed with tuladb-installer the copy in /opt/tuladb is already there. Each archive, tuladb-prometheus-exporter-0.0.1-preview-<platform>.tar.gz (linux-x86_64, linux-arm64, darwin-arm64), holds:

File
tuladb_prometheus_exporter the exporter; it needs only the C library (Linux: glibc 2.34 or newer)
tpe.toml example configuration: bind 127.0.0.1:9145, metrics_file = "/var/lib/tuladb/runtime/metrics.json"
tuladb-prometheus-exporter.service a sandboxed systemd unit that runs as tuladb (Linux archives only)
README.md these steps

On a node (user tuladb, data in /var/lib/tuladb), after verifying the download:

tar -xzf tuladb-prometheus-exporter-0.0.1-preview-linux-x86_64.tar.gz
cd tuladb-prometheus-exporter-0.0.1-preview-linux-x86_64
sudo install -D -m 0755 tuladb_prometheus_exporter /opt/tuladb-prometheus-exporter/tuladb_prometheus_exporter
sudo install -D -m 0644 tpe.toml /etc/tuladb-prometheus-exporter/tpe.toml
sudo install -m 0644 tuladb-prometheus-exporter.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now tuladb-prometheus-exporter
curl -fsS http://127.0.0.1:9145/metrics | grep '^tuladb_up'

To let Prometheus on another host scrape it, set bind in /etc/tuladb-prometheus-exporter/tpe.toml to the node’s address (and cluster_name to your cluster’s), then sudo systemctl restart tuladb-prometheus-exporter; the firewall advice above applies. Run only one exporter per node on port 9145: if you already added the service above for the installer’s copy, use one or the other.

SDKs

The C, Go, Java, Python and Rust SDKs are versioned 0.0.1-preview together. None is published to a package registry in this release (PyPI, Maven Central, crates.io and the Go module proxy are not used): each is a file in the sdk download, which you install from disk. go get from GitHub does not work, because the repository is private.

Language File Install
Python 3.9+ tuladb_sdk-0.0.1.dev0-py3-none-any.whl pip install --no-index ./tuladb_sdk-0.0.1.dev0-py3-none-any.whl
Java 21+ tuladb-client-0.0.1-preview.jar (+ .pom, -sources.jar, -javadoc.jar) on the classpath, or into a Maven repository (below)
C tuladb-c-sdk-0.0.1-preview-linux-x86_64.tar.gz, or -src.tar.gz link the static library with OpenSSL (below)
Rust tuladb-0.0.1-preview.crate a path dependency (below)
Go 1.21+ tuladb-go-sdk-v0.0.1-preview.zip a file:// module proxy or a replace (below)

0.0.1.dev0 is the Python packaging form of 0.0.1-preview.

Java. The jar is the whole SDK, with no dependencies. For Maven, install it with its POM and depend on com.tuladb:tuladb-client:0.0.1-preview:

mvn install:install-file -Dfile=tuladb-client-0.0.1-preview.jar \
  -DpomFile=tuladb-client-0.0.1-preview.pom \
  -Dsources=tuladb-client-0.0.1-preview-sources.jar \
  -Djavadoc=tuladb-client-0.0.1-preview-javadoc.jar

C. The Linux x86_64 archive holds a static library built with OpenSSL TLS, the headers and a pkg-config file. Other platforms build from the source archive (make -C tuladb-c-sdk-0.0.1-preview-src/c ENABLE_OPENSSL_TLS=1).

tar -xzf tuladb-c-sdk-0.0.1-preview-linux-x86_64.tar.gz
SDK=$PWD/tuladb-c-sdk-0.0.1-preview-linux-x86_64
cc app.c -I"$SDK/include" "$SDK/lib/libledgerd_client.a" -lssl -lcrypto -lpthread

Rust. The crate has no dependencies by default. Unpack it and use it as a path dependency; the optional tls feature needs rustls, which is not in the download (vendor it with cargo vendor on a connected machine).

mkdir -p vendor && tar -xzf tuladb-0.0.1-preview.crate -C vendor
# Cargo.toml:  tuladb = { path = "vendor/tuladb-0.0.1-preview" }

Go. The zip is the module as a module proxy would serve it. The module path inside it is github.com/TulaDB/tuladb-sdk/go; that name goes in go.mod, but nothing is fetched from it. Unpack the zip and point a replace at it:

V=0.0.1-preview
unzip -q tuladb-go-sdk-v$V.zip -d third_party
go mod edit -require=github.com/TulaDB/tuladb-sdk/go@v$V \
  -replace=github.com/TulaDB/tuladb-sdk/go=./third_party/github.com/TulaDB/tuladb-sdk/go@v$V

Connecting to a cluster. Every SDK refuses plaintext to a non-loopback host. Python, Java, C and Rust take the CA, client certificate and key in code or from TULADB_CLIENT_TLS_CA_FILE, TULADB_CLIENT_TLS_CERT_FILE and TULADB_CLIENT_TLS_KEY_FILE (Rust only with its tls feature); Go takes a standard crypto/tls configuration. Python, Java and the C smart client accept a list of nodes and route writes to the leader; Go and Rust connect to one address. Each SDK’s page has the details: Python, Java, Go, Rust, C.

Dashboard

The operator console: accounts and balances, transfers, pending holds, rejected records, the audit log and, optionally, the Iceberg lake. A Python backend (tuladb-dashboard) serves the built web frontend from inside its wheel.

Download. The dashboard release is an offline bundle for Linux x86_64 and arm64: the dashboard and Python SDK wheels, hashed dependency locks, wheelhouse archives for your architecture, an optional set of DuckDB extensions for the lake screen (all as .tar.gz archives), and an installer script, tuladb-dashboard-0.0.1-preview-install.sh. It needs Python 3.12 with venv on the host. Take the whole directory for your architecture and verify it as above.

Install. The installer checks every file it uses against SHA256SUMS, then installs with pip --no-index --require-hashes into its own virtual environment. It needs no network:

bash ./tuladb-dashboard-0.0.1-preview-install.sh            # --prefix DIR; --no-lake leaves the lake screen out

The default prefix is ~/.local/share/tuladb-dashboard; the launchers are in its bin/: tuladb-dashboard and tuladb-dashboard-users (local user accounts).

Connect and start. The dashboard connects to the nodes’ client port for writes and query port for reads, with its own client certificate, and finds the leader itself. It sends no API key to the nodes, so its certificate principal needs a grant on every node: ledger-operator to move money from the dashboard, read-only to only look.

umask 077 && cat > dashboard.env <<EOF
LEDGER_DASHBOARD_ENV=prod
LEDGER_DASHBOARD_API_KEY=$(openssl rand -hex 32)
LEDGER_DASHBOARD_SESSION_SECRET=$(openssl rand -hex 32)
LEDGER_DASHBOARD_PASSWORD=<a password you choose>
TULADB_CLUSTER_NODES=10.0.0.1:7700,10.0.0.2:7700,10.0.0.3:7700
TULADB_QUERY_NODES=10.0.0.1:7800,10.0.0.2:7800,10.0.0.3:7800
TULADB_CLIENT_TLS_ENABLED=1
TULADB_CLIENT_TLS_CA_FILE=/etc/tuladb-pki/ca.crt
TULADB_CLIENT_TLS_CERT_FILE=/etc/tuladb-pki/tuladb-dashboard.crt
TULADB_CLIENT_TLS_KEY_FILE=/etc/tuladb-pki/tuladb-dashboard.key
EOF
set -a && . ./dashboard.env && set +a
~/.local/share/tuladb-dashboard/bin/tuladb-dashboard --host 127.0.0.1 --port 8080

With LEDGER_DASHBOARD_ENV=prod it refuses to start without LEDGER_DASHBOARD_API_KEY (the key its own HTTP API accepts from other services; it never reaches the browser) or while the sign-in password is still the default. Sign in as admin with the password you set; tuladb-dashboard-users add creates named users with the roles viewer, operator and admin, after which the environment password no longer signs in. The backend serves plain HTTP and, in production mode, marks its session cookie Secure: keep it on 127.0.0.1 and put your HTTPS reverse proxy in front, or for an evaluation reach it through an SSH tunnel (ssh -L 8080:127.0.0.1:8080 ops-host, then http://localhost:8080). Observability describes what it shows; Lake query turns on the lake screen.

Iceberg exporter

tuladb-iceberg-exporter streams committed ledger history into Apache Iceberg tables, exactly once into the table, off the write path. It reads the export stream from the nodes’ query port 7800.

Download. The exporter release has the wheel (pure Python, 3.11+), its source distribution, and offline wheelhouses: one per extra (base, iceberg, biglake, s3tables, all), CPython version (3.11, 3.12) and Linux architecture (x86_64, arm64; the file names say aarch64). Each wheelhouse holds every wheel that extra needs, the exporter’s own included. Take the one for your interpreter and platform, with iceberg for a local or REST catalog, s3tables for AWS S3 Tables or biglake for Google BigLake, and verify it as above.

Install, with no network:

W=tuladb-iceberg-exporter-0.0.1-preview-wheelhouse-iceberg-cp312-manylinux_x86_64
tar -xzf $W.tar.gz && cd $W
sudo python3.12 -m venv /opt/tuladb-iceberg-exporter
sudo /opt/tuladb-iceberg-exporter/bin/pip install --no-index --find-links wheelhouse 'tuladb-iceberg-exporter[iceberg]'
/opt/tuladb-iceberg-exporter/bin/tuladb-iceberg-exporter --version

requirements.txt in the same directory is the hashed lock the wheels came from; INSTALL.txt shows how to install exactly that set with --require-hashes.

Air-gapped hosts. A wheelhouse is the whole install: copy it (and, to check the signature, SHA256SUMS, SHA256SUMS.cosign.bundle, trusted_root.json and a cosign binary) across, verify with --offline, and install with --no-index as above. What it does not carry:

  • Python. The host needs CPython 3.11 or 3.12 with venv, matching the wheelhouse.
  • Other platforms. The wheelhouses are built for glibc Linux (manylinux): no macOS, no musl (Alpine).
  • A cloud lake. Inside an isolated network, write to a filesystem path or a self-hosted S3-compatible object store with the local SQL (SQLite) catalog (iceberg extra). The s3tables and biglake extras target AWS S3 Tables and Google BigLake, which are cloud services.

The release tests each wheelhouse this way before it is signed: unpacked on a clean host of its own architecture, installed with no index, then a real export into a local Parquet store and, for iceberg and all, a SQLite Iceberg catalog.

Connect. Give the exporter a client certificate and grant its principal the exporter role on every node: holding an export lease and sending durable acks need it, and a read-only principal is refused (ERR_PERMISSION, 35). Set export_lease_ttl_ms above 0 on the nodes, or the exporter’s lease holds no WAL. Its configuration lists every node’s query port and the client certificate:

[source]
hosts = ["10.0.0.1:7800", "10.0.0.2:7800", "10.0.0.3:7800"]
register_export_lease = true

[source.tls]
enabled = true
ca_file = "/etc/tuladb-pki/ca.crt"
cert_file = "/etc/tuladb-pki/tuladb-iceberg-exporter.crt"
key_file = "/etc/tuladb-pki/tuladb-iceberg-exporter.key"

[iceberg]
enabled = true
writer_epoch = 1          # required: iceberg.enabled refuses writer_epoch < 1

Start.

tuladb-iceberg-exporter doctor  --config exporter.toml   # validate the configuration; makes no network calls
tuladb-iceberg-exporter run     --config exporter.toml   # continuous
tuladb-iceberg-exporter metrics --config exporter.toml   # /metrics and /healthz on 127.0.0.1:9146

Integrated cluster has a complete configuration with a local catalog. Analytics export covers the catalogs (S3 Tables, BigLake, a local SQL catalog), the table layout, partitioned workers, exit codes and reconcile.

Grafana and Prometheus

Prometheus and Grafana are not TulaDB downloads: install them from their own projects. The TulaDB side is the grafana-dashboards download, tuladb-grafana-dashboards-0.0.1-preview.tar.gz: six dashboards, cross-linked through a “TulaDB dashboards” menu, with the Grafana provisioning files and a README.

File Dashboard uid
dashboards/tuladb-overview.json TulaDB · 0 Overview tuladb-overview
dashboards/01-cluster-consensus.json TulaDB · 1 Cluster & consensus tuladb-cluster
dashboards/02-durability-wal.json TulaDB · 2 Durability & WAL tuladb-wal
dashboards/03-engine-throughput.json TulaDB · 3 Engine & throughput tuladb-engine
dashboards/04-runtime-security.json TulaDB · 4 Runtime & security tuladb-runtime
dashboards/05-dedup-run-tier.json TulaDB · 5 Dedup run tier tuladb-dedup-run
provisioning/datasources/datasource.yml the Prometheus datasource, uid tuladb-prometheus
provisioning/dashboards/provider.yml loads every dashboard into a “TulaDB” folder

Every panel reads the ${datasource} variable, whose default is the datasource with uid tuladb-prometheus, and every metric a panel queries is checked against the Prometheus exporter before the release is signed. Grafana and Prometheus run on an operations host, not on the nodes.

Prometheus. Scrape every node’s exporter:

scrape_configs:
  - job_name: tuladb
    static_configs:
      - targets: ["10.0.0.1:9145", "10.0.0.2:9145", "10.0.0.3:9145"]

Grafana, provisioned. Unpack the archive and copy its files where Grafana reads them, then set url in datasource.yml to your Prometheus (the default, http://prometheus:9090, is a Compose service name). Keep uid: tuladb-prometheus:

tar -xzf tuladb-grafana-dashboards-0.0.1-preview.tar.gz && cd tuladb-grafana-dashboards-0.0.1-preview
sudo install -m 0644 provisioning/datasources/datasource.yml /etc/grafana/provisioning/datasources/tuladb.yml
sudo install -m 0644 provisioning/dashboards/provider.yml    /etc/grafana/provisioning/dashboards/tuladb.yml
sudo install -d /var/lib/grafana/dashboards && sudo install -m 0644 dashboards/*.json /var/lib/grafana/dashboards/
sudo systemctl restart grafana-server

Grafana, by hand. Dashboards → New → Import, upload each JSON file, then pick your Prometheus datasource in the “Data source” drop-down at the top of each dashboard.

No alert rules ship in this release. The rule set described in Observability is not in a published download; design partners receive it on request.

The eval release also carries the same six dashboards in tuladb-eval-observability-0.0.1-preview.tar.gz, with provisioning and a Prometheus scrape configuration written for its Compose stack’s host names. Integrated cluster has every file for a three-node cluster.

Upgrade and remove

Each component upgrades on its own: download the new release, verify it, then replace the old one as below. The engine and the SDKs must speak the same wire version; the release notes of each release say when that changes.

Component Upgrade Remove
Server, tulactl, the bundled Prometheus exporter the new installer’s upgrade, one node at a time (Upgrade); it checks the new build against this node first and rolls back if the switch fails uninstall keeps the data; uninstall --purge --yes-delete-financial-data deletes it (Uninstall)
SDKs install the new file the same way (a new wheel, jar, crate, Go zip or C archive) and rebuild your application uninstall it with your language’s tool, or delete the file
Dashboard run the new bundle’s installer with the same --prefix: it replaces the virtual environment and keeps <prefix>/data (users, audit log) stop it, then delete the prefix, ~/.local/share/tuladb-dashboard by default, which also deletes its users and audit log
Iceberg exporter stop it, then pip install --no-index --find-links wheelhouse from the new wheelhouse into the same virtual environment, and start it; its progress lives in the lake and its state directory, not the install stop it and delete the virtual environment; the lake’s tables stay where they are
Prometheus exporter, standalone replace /opt/tuladb-prometheus-exporter/tuladb_prometheus_exporter, then sudo systemctl restart tuladb-prometheus-exporter sudo systemctl disable --now tuladb-prometheus-exporter, then delete the unit, the binary and /etc/tuladb-prometheus-exporter
Grafana dashboards copy the new JSON files over the old ones; the uids stay the same, so links and bookmarks keep working delete the files and the two provisioning files, then restart Grafana
Developer quick setup unpack the new eval bundle and run ./eval.sh up: it sees a different release and installs it, keeping your certificates and credentials ./eval.sh down stops it and keeps the data; ./eval.sh purge deletes the data; deleting ~/.tuladb-cluster (or ~/.tuladb for --single) also deletes the certificates and credentials (Remove it)

Air-gapped hosts. Everything in this release installs without a network once the files are on the host: the server installer carries its whole release, the dashboard and Iceberg exporter bundles carry every dependency, and the signature checks run with --offline against the trusted_root.json in each directory. Bring cosign across yourself to check signatures there; the hashes need only sha256sum. The exceptions are a cloud lake for the Iceberg exporter (above), and the Prometheus and Grafana images of the developer quick setup, which come from Docker Hub.