Self-hosting
Fliq is open source and runs the whole stack — API, scheduler, and Postgres —
from one docker compose. No Clerk account, no Redis, no managed services. The
only prerequisite is Docker.
This guide mirrors the README in core-api and is verified against a clean clone.
1. Clone and start
git clone https://github.com/fliq-sh/core-api.git && cd core-api
# Build + start Postgres, run migrations, then bring up the server + scheduler.
docker compose --profile migrate --profile app up --build
The migrate profile runs the database migrations once and exits; the app
profile then starts the API server and the scheduler. When it settles, the API
is live on http://localhost:8080:
curl localhost:8080/health
# {"status":"ok","version":"dev","time":"..."}
2. Get a first credential — no Clerk
Self-hosted Fliq authenticates with HS256 JWTs signed by JWT_SECRET (set in
docker-compose.yml). Mint one for any user id; the first authenticated request
auto-provisions that user with free credits.
SECRET='dev-only-change-me-0123456789abcdef0123456789' # must match the server's JWT_SECRET
b64() { openssl base64 -A | tr '+/' '-_' | tr -d '='; }
h=$(printf '{"alg":"HS256","typ":"JWT"}' | b64)
p=$(printf '{"sub":"local-user","exp":%d}' "$(($(date +%s)+31536000))" | b64)
s=$(printf '%s.%s' "$h" "$p" | openssl dgst -sha256 -hmac "$SECRET" -binary | b64)
JWT="$h.$p.$s"
# Exchange the JWT for a long-lived API token (fliq_sk_*) you can use everywhere:
curl -s -X POST localhost:8080/tokens \
-H "Authorization: Bearer $JWT" -H 'Content-Type: application/json' \
-d '{"name":"self-host"}'
# → {"token":"fliq_sk_...", ...}
3. Schedule a job
Use the fliq_sk_* token the same way you would against the hosted API:
curl -X POST localhost:8080/jobs \
-H "Authorization: Bearer fliq_sk_..." -H 'Content-Type: application/json' \
-d '{"url":"https://httpbin.org/post","method":"POST","scheduled_at":"2030-01-01T00:00:00Z"}'
From here, everything in the Quickstart and API Reference applies unchanged — the self-hosted API is the same binary as the hosted one.
Configuration
Everything is env-driven; the compose file sets sane local defaults. The vars that matter when self-hosting:
| Var | Purpose |
|---|---|
DATABASE_URL | Postgres connection string |
JWT_SECRET | HS256 signing secret for local auth (min 32 chars) — change it |
CLERK_JWKS_URL | set only to use Clerk RS256 auth instead of the HS256 path |
WORKER_COUNT / POLL_INTERVAL_SEC | scheduler concurrency + poll cadence |
STRIPE_* | optional — only needed for paid top-ups |
Running the binaries directly
Prefer not to use Docker for the app processes? Bring up only Postgres, run the migrations, then run the two Go binaries — see the Local dev section of the core-api README.
View core-api on GitHub→