Installation¶
synthkit ships as a single self-contained binary. Build from source with Go, or pull the prebuilt container image from GitHub Container Registry.
Prerequisites¶
- Go 1.26.4 or later — synthkit's
go.modspecifiesgo 1.26.4. Earlier toolchain versions will be rejected. - Git (to clone the repo).
No CGO. The binary is fully static and cross-compiles cleanly.
- Docker (or any OCI-compatible runtime).
- No Go installation needed — the prebuilt image is a distroless static binary.
Build from source¶
This produces a synthkit binary in the current directory.
Full gate
Before shipping changes, run make gate — that runs build, vet, test (with the race detector), and the SPDX + hygiene checks. For a quick sanity check, go build ./... && go vet ./... && go test ./... is sufficient.
Run the prebuilt container image¶
The multi-arch image (linux/amd64 + linux/arm64) is published to GHCR on each release:
The image is distroless (based on gcr.io/distroless/static-debian12:nonroot) and runs as uid 65532 (nonroot). It has no shell, no package manager, and no writable filesystem except the /data volume.
# Dry run — prints the series inventory, pushes nothing
docker run --rm \
-e DRY_RUN=true \
ghcr.io/rknightion/synthkit:latest -once -dump
For a persistent run with credentials, use the docker-compose path below or mount a .env file.
docker-compose (recommended for standing deployments)¶
The repository ships a docker-compose.yml that reads all configuration from a .env file (gitignored — never commit secrets).
First-time setup:
# 1. Clone the repo
git clone https://github.com/rknightion/synthkit.git
cd synthkit
# 2. Create the .env file and fill in your credentials
cp .env.example .env
# edit .env — see Credentials for what to fill in
# 3. Create the state bind-mount directory and give it to the container user
# (uid 65532 = distroless nonroot; a single-file mount breaks atomic save)
mkdir -p control-state-data && sudo chown -R 65532:65532 control-state-data
# 4. Build and start
docker compose up -d --build
The container binds the control plane on port 8088 inside the container. Host exposure is controlled by SYNTHKIT_BIND in .env (defaults to 127.0.0.1 — loopback only, safe by default). The operator UI is available at:
Control plane is unauthenticated by default
POST routes (/control/scenarios, /control/scaling, /control/failures, /control/load) require no authentication unless CONTROL_TOKEN is set in .env. Keep the default SYNTHKIT_BIND=127.0.0.1 unless you are on a trusted network; use an SSH tunnel or tailscale serve to reach it remotely.
For the full production deployment guide — including the persistent volume setup, live credential rotation, and upgrade path — see Deployment.
Next steps¶
- Credentials — fill in
.envcorrectly - Quick Start — from binary to live data
- Deployment — standing production deploy on a host