Skip to main content

Installation

Quack on Demand ships as a single uber-jar. Three installation paths are supported: download from Maven Central (the recommended default), build from source, and Docker.

Prerequisites

  • JDK 21 or later. The assembly jar embeds an Add-Opens manifest attribute (JEP 261) so no extra --add-opens flags are required when running java -jar.

  • Postgres 16 or later. The control plane stores all state in a dedicated database (default name qod) on localhost:5432. The run-jar.sh startup script probes Postgres before the JVM boots and refuses to proceed against a server older than PG 16.

    If you do not have a local Postgres instance, the quickest path is:

    docker run -d --name qod-pg \
    -e POSTGRES_PASSWORD=azizam \
    -p 5432:5432 \
    postgres:16-alpine

Run from Maven Central

scripts/run-jar.sh handles everything: it resolves the latest release from Maven Central (ai.starlake:quack-on-demand_3:<version>), caches the jar under ~/.cache/quack-on-demand/, probes Postgres, creates the control-plane database if it does not exist, and starts the JVM with the Arrow allocator pinned.

# Latest release (default)
./scripts/run-jar.sh

# Pinned release
QOD_VERSION=0.3.2 ./scripts/run-jar.sh

# Latest snapshot from Central snapshots
QOD_VERSION=latest-snapshot ./scripts/run-jar.sh

On first run against a freshly-provisioned Postgres, the script creates the qod database and Liquibase applies the control-plane schema. The admin UI is at http://localhost:20900/ui/; log in as admin with password admin (change this before any exposure beyond localhost -- see Configuration model below).

The FlightSQL edge listens on localhost:31338 with TLS on by default (self-signed cert auto-generated under certs/).

To stop the manager:

./scripts/stop-jar.sh

Seeding TPC-H for a quick smoke test

Pass LOAD_TPCH=1 to seed TPC-H at scale factor 1 (approximately 6 million lineitem rows) into the bootstrap tenant-db before the JVM starts. Requires the duckdb CLI on PATH.

LOAD_TPCH=1 ./scripts/run-jar.sh

For a completely fresh start (drops the control-plane DB and wipes local state directories before booting):

NUKE=1 LOAD_TPCH=1 ./scripts/run-jar.sh

Build from source

BUILD=1 tells run-jar.sh to call sbt assembly first instead of downloading:

BUILD=1 ./scripts/run-jar.sh

To build the jar separately and run it manually:

sbt assembly
java -jar distrib/quack-on-demand-assembly-*.jar

The assembly output lands in distrib/quack-on-demand-assembly-<version>.jar. The jar carries the Add-Opens manifest attribute covering java.base/java.nio and java.base/sun.nio.ch, which Arrow Flight's unsafe allocator needs on Java 17+. No extra --add-opens flags are needed on the command line.

Note: sbt compile and sbt assembly also run npm ci and npm run build inside the ui/ directory as a resource generator, so the React admin UI is bundled automatically. There is no separate UI build step.

Docker

The published image is starlakeai/quack-on-demand. Use scripts/run-docker.sh to pull and run it against an external Postgres:

PG_HOST=db.internal PG_PASSWORD=*** ./scripts/run-docker.sh

The script requires PG_HOST and PG_PASSWORD. Key options:

VariableDefaultDescription
QOD_VERSIONlatestImage tag to pull
PG_PORT5432Postgres port
PG_USERpostgresPostgres user
MANAGER_PORT20900Host port for REST + admin UI
EDGE_PORT31338Host port for FlightSQL edge
TLSfalseEnable FlightSQL TLS inside the container
ADMIN_PASSWORDadminAdmin login password (rotate before production)
API_KEYunsetREST X-API-Key static key
BUILD0Set to 1 to build the image from the local Dockerfile instead of pulling

To pin a version or use the latest snapshot:

QOD_VERSION=0.3.2 PG_HOST=... PG_PASSWORD=*** ./scripts/run-docker.sh
QOD_VERSION=latest-snapshot PG_HOST=... PG_PASSWORD=*** ./scripts/run-docker.sh

Note: do not mix Docker and native-jar runs against the same catalog DB. DuckLake records the absolute data path in Postgres metadata. Inside the container that path is /app/ducklake/<db>; natively it is <host-cwd>/ducklake/<db>. Use a different PG_DBNAME (or QOD_PG_DBNAME) per mode, or wipe the data directory between switches.

Configuration model

Every scalar in application.conf accepts a matching QOD_* environment variable override (FlightSQL edge keys use the PROXY_* prefix). The bundled application.conf is baked into the jar at build time, so you should use environment variables rather than editing it directly.

Defaults you must change before production:

SettingEnv varInsecure default
Admin passwordQOD_ADMIN_PASSWORDadmin
Postgres passwordQOD_PG_PASSWORDazizam
REST API keyQOD_API_KEYunset (open API)

Setting QOD_API_KEY to a secret string requires that value in the X-API-Key header on every REST call. Leaving it unset means the REST API is accessible without authentication (acceptable only on localhost or behind a trusted network boundary).

Other commonly used variables:

SettingEnv varDefault
Manager REST portQOD_ON_DEMAND_PORT20900
FlightSQL edge portPROXY_PORT31338
FlightSQL TLS on/offPROXY_TLS_ENABLEDtrue
State backendQOD_STATE_STORAGEpostgres
Postgres hostQOD_PG_HOSTlocalhost
Postgres userQOD_PG_USERpostgres
Control-plane databaseQOD_PG_DBNAMEqod
Admin usernamesQOD_ADMIN_USERNAMEadmin@localhost.local,admin
Enable per-statement RBACQOD_ACL_ENABLEDfalse

For the full list of configuration keys, see the Configuration reference.