Documentation menu

Docs / Get started

Quickstart

Run one node on your own machine, then three nodes on one bucket with TLS, and connect a client.

Available View Markdown
Works
One node on loopback with a local directory; three nodes on one qualified bucket with TLS; psql, psycopg 3, node-postgres, pgjdbc and HTTP clients.
Differs
The local fs: store is for development only. It says nothing about how a real bucket behaves.
Missing
A public download, a macOS or Windows server binary, a managed service.
Operational impact
Creating a database reserves an immutable ID. Dropping a database does not reclaim its data in pre-beta.
Evidence
Steps follow the project's beta guide. The beta acceptance run has not passed yet.

You need a build first. There is no public download yet. Pre-beta builds are a release directory (binary, checksums, build record, example config and systemd unit) handed to invited testers. Join the waitlist.

#What you need

  • The release directory, all files from the same release.
  • Linux x86_64 with glibc 2.34 or newer (Ubuntu 22.04, Debian 12, RHEL 9 or later). The binary does not run on macOS.
  • For part 2: three hosts that can reach each other on TCP 7101, and one bucket.

Check and install the binary:

Shell
sha256sum --check --ignore-missing SHA256SUMS
install -d -m 0755 "$HOME/.local/bin"
install -m 0755 gauntlet-*-linux-x86_64 "$HOME/.local/bin/gauntlet"
export PATH="$HOME/.local/bin:$PATH"
gauntlet --version        # must list "engines: turso"

#Part 1: one node on loopback

This runs one node against a directory on local disk. It needs no bucket and no certificates, because every listener is on 127.0.0.1.

Shell
mkdir -p "$HOME/gauntlet-dev" && cd "$HOME/gauntlet-dev"
export GAUNTLET_CLIENT_TOKEN=$(openssl rand -hex 32)
export GAUNTLET_PEER_TOKEN=$(openssl rand -hex 32)
export GAUNTLET_ADMIN_TOKEN=$(openssl rand -hex 32)

gauntlet --cache-dir "$PWD/cache" --cache-mib 512 serve \
  --store "fs:$PWD/bucket" --id n1 \
  --listen 127.0.0.1:7101 --pg-listen 127.0.0.1:7151 \
  --memory-mib 4096

--memory-mib 4096 is the smallest budget allowed. The node checks its store before it serves:

Shell
curl -s http://127.0.0.1:7101/health     # "ok": the process answers
curl -si http://127.0.0.1:7101/ready     # 200 when it can serve, 503 when it cannot

In a second terminal, with the same three tokens exported, create a database and get its token:

Shell
export GAUNTLET_URL=http://127.0.0.1:7101
gauntlet admin create-database app > app-create.json   # keep this file
gauntlet admin list
TOKEN=$(gauntlet admin token app)

Connect. The database token is the password, for any user name:

Shell
PGPASSWORD=$TOKEN psql "host=127.0.0.1 port=7151 dbname=app user=app" \
  -c "CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT NOT NULL)" \
  -c "INSERT INTO items VALUES (1, 'first')" \
  -c "SELECT * FROM items"

Stop the node with Ctrl-C. Start it again with the same command and the row is still there: everything it needs is under bucket/. The cache/ directory is disposable. A restart with the same --id takes 17–18 s to become ready, because it waits out the previous run's 15 s lease.

#Part 2: three nodes on one bucket

The examples use hosts n1.example.net, n2.example.net and n3.example.net, and an admin machine that is none of them.

#Choose a bucket

Gauntlet needs more than the S3 API. It needs atomic create-if-absent (If-None-Match: *), read-after-write consistency and a strongly consistent, ordered LIST. gauntlet qualify tests this for you, and every node start runs the same checks again. A bucket that fails is refused.

Provider Status
Tigris Run by the project. Recommended: one region, next to the hosts
Cloudflare R2 Run by the project. Conditional writes were slower in the project's runs, so commits are slower
AWS S3 Unverified. No run is recorded. Qualify it first
MinIO Unverified. No run is recorded. Qualify it first

Details, including the environment variables, are in deploy and qualify a bucket.

#Secrets, certificates and config

On the admin machine, write one secrets file that every node uses, test the bucket, and issue certificates from the deployment's private CA:

Shell
umask 077
cat > secrets.env <<ENV
GAUNTLET_S3_ENDPOINT=https://t3.storage.dev
GAUNTLET_S3_REGION=auto
GAUNTLET_S3_BUCKET=my-gauntlet-bucket
GAUNTLET_S3_ACCESS_KEY_ID=<access key id>
GAUNTLET_S3_SECRET_ACCESS_KEY=<secret access key>
GAUNTLET_CLIENT_TOKEN=$(openssl rand -hex 32)
GAUNTLET_PEER_TOKEN=$(openssl rand -hex 32)
GAUNTLET_ADMIN_TOKEN=$(openssl rand -hex 32)
ENV

(set -a; . ./secrets.env; gauntlet qualify --store 's3:#qualify-check')

gauntlet tls init --out ca
for n in 1 2 3; do
  gauntlet tls issue --ca ca --node n$n --dns n$n.example.net --dns localhost --out n$n
done

Write /etc/gauntlet/gauntlet.toml on each host. Only id and advertise differ between nodes:

TOML
store = "s3:#gauntlet/beta"          # GAUNTLET_S3_* plus this prefix; same on every node
id = "n1"                            # unique per node
listen = "0.0.0.0:7101"              # HTTP: clients, admin and peers
advertise = "n1.example.net:7101"    # a name in this node's certificate
pg-listen = "0.0.0.0:7151"           # PostgreSQL wire protocol
tls-cert = "/etc/gauntlet/tls/node.crt"
tls-key = "/etc/gauntlet/tls/node.key"
tls-peer-ca = "/etc/gauntlet/tls/ca.crt"
cache-dir = "/var/lib/gauntlet/cache"
cache-mib = 8192
memory-mib = 16384
log-format = "json"

Start all three with the packaged systemd unit. They find each other through leases in the bucket. A node answers neither /health nor /ready until its start-up bucket check passes.

#Create a database

Shell
export GAUNTLET_URL=https://n1.example.net:7101 GAUNTLET_TLS_CA=ca/ca.crt
set -a; . ./secrets.env; set +a
umask 077
gauntlet admin create-database app > app-create.json
TOKEN=$(gauntlet admin token app)

If create-database reports an unknown outcome, retry with gauntlet admin create-database --reservation app-create.json. Never retry by name: that reserves a second ID.

#Connect

Any node serves any database. Use the database name as dbname, any user name, and the database token as the password.

Shell
PGPASSWORD=$TOKEN psql "host=n1.example.net port=7151 dbname=app user=app \
  sslmode=verify-full sslrootcert=ca/ca.crt channel_binding=require" \
  -c "SELECT 1"

Driver examples are in PostgreSQL wire; the JSON API is in HTTP.

#Next

  • Read transactions: your client must handle 40001 and 40003.
  • Take a first backup and practise a restore.
  • Read the limits before you put data in.

Search runs in your browser over an index of these pages. No query leaves this site.