Skip to content

Installation

Testhooks is a single Go binary with the web UI embedded. It stores data in PostgreSQL 15 or newer, or in memory for local testing.

The quickest start: no Docker and, with in-memory storage, no database. Install once; it downloads the build for your OS and architecture and verifies its SHA-256 checksum:

curl -fsSL https://raw.githubusercontent.com/sarathsp06/testhooks/main/install.sh | sh

Then run it, now and every time after:

DATABASE_URL=memory testhooks

Installer options:

Variable Default
TESTHOOKS_VERSION latest Release tag to install, for example v1.1.0
TESTHOOKS_INSTALL_DIR /usr/local/bin if writable, else ~/.local/bin Where to put the binary

If it lands in ~/.local/bin and that isn’t on your PATH, run ~/.local/bin/testhooks (the installer prints a hint). Builds are published for Linux, macOS and Windows on amd64 and arm64. You can also download them directly from the releases page.

For local testing, keep everything in memory:

DATABASE_URL=memory testhooks

Data is lost when the process stops. To keep it across restarts, add a snapshot file. The store is written to it every 30 seconds when something changed, and on shutdown, then loaded on the next start:

DATABASE_URL=memory SNAPSHOT_PATH=./testhooks.snapshot testhooks

A clean shutdown loses nothing; a crash loses at most the last 30 seconds. If the snapshot file is unreadable, Testhooks refuses to start rather than overwrite it.

In-memory mode is meant for one person testing locally. For a shared or public instance, use PostgreSQL.

For a quick local database:

docker run -d --name testhooks-pg -p 127.0.0.1:5432:5432 -e POSTGRES_USER=testhooks -e POSTGRES_PASSWORD=testhooks -e POSTGRES_DB=testhooks postgres:17-alpine
DATABASE_URL='postgres://testhooks:testhooks@localhost:5432/testhooks?sslmode=disable' testhooks

Point it at another database with DATABASE_URL. See Configuration for every setting.

For local testing. One container, data kept in memory:

docker run -d --name testhooks -p 8080:8080 -e DATABASE_URL=memory ghcr.io/sarathsp06/testhooks

To keep the data across restarts, add a volume and a snapshot file:

docker run -d --name testhooks -p 8080:8080 -v testhooks-data:/data -e DATABASE_URL=memory -e SNAPSHOT_PATH=/data/testhooks.snapshot ghcr.io/sarathsp06/testhooks

Remove it with docker rm -f testhooks (and docker volume rm testhooks-data for the snapshot).

For shared or long-running instances. Runs Testhooks and PostgreSQL together from the published image; migrations run on startup and the server waits up to 60 seconds for the database:

curl -fsSL https://raw.githubusercontent.com/sarathsp06/testhooks/main/deploy/docker-compose.yml | docker compose -p testhooks -f - up -d

Set options as environment variables in front of the command:

Variable Default
TESTHOOKS_PORT 8080 Host port to publish
TESTHOOKS_VERSION latest Image tag, for example 1.1.0
AUTH_TOKEN Password for the UI and API. Set it on anything reachable from the internet; see Authentication
ALLOWED_ORIGINS * Allowed browser origins
TRUSTED_PROXIES CIDRs of reverse proxies allowed to set client-IP headers
TESTHOOKS_PORT=9000 AUTH_TOKEN=change-me \
curl -fsSL https://raw.githubusercontent.com/sarathsp06/testhooks/main/deploy/docker-compose.yml | docker compose -p testhooks -f - up -d

To keep a local copy you can edit, download it first:

curl -fsSLO https://raw.githubusercontent.com/sarathsp06/testhooks/main/deploy/docker-compose.yml
docker compose up -d

Multi-arch images (amd64, arm64) are published to the GitHub Container Registry:

docker run -d -p 8080:8080 -e DATABASE_URL='postgres://user:pass@db-host:5432/testhooks?sslmode=disable' ghcr.io/sarathsp06/testhooks

Use DATABASE_URL=memory instead to run without a database.

The image is built FROM scratch: it holds only the binary, CA certificates and time zone data.

Prerequisites: Go 1.26+ and Node 22+. PostgreSQL is optional: without DATABASE_URL, ./testhooks stores data in memory.

git clone https://github.com/sarathsp06/testhooks.git
cd testhooks
docker compose up --build # app + Postgres built from this checkout
# or
make build # builds the UI, then the binary with the UI embedded
./testhooks

make build-all cross-compiles for every supported OS and architecture into dist/.

make dev # Go on :8080 (API, WebSocket, proxy to Vite) and Vite on :5173 with hot reload
make test # Go tests
make lint # go vet and svelte-check