Hook

Self-hosted AI Gateway

One control plane for model routing, access policy, billing, and observability.

Hook gives teams a private gateway for provider routing, token policy, wallet billing, usage records, and operations monitoring across OpenAI-compatible, Claude, and Gemini APIs.

Overview

Users call Hook with Hook-issued tokens through /v1 or /v1beta. Hook routes requests by model, provider, group, wallet balance, and permission policy, then records usage, billing, and runtime status.

Backend

Axum, SeaORM, PostgreSQL, Redis, scheduling, billing, monitoring, and admin APIs.

Frontend

Next.js, React, MUI, and TypeScript for the user console and admin panel.

Use cases

Provider management, OpenAI-compatible proxying, quota control, request records, and operations monitoring.

Features

Unified AI proxy

OpenAI-style /v1 and Gemini-style /v1beta routes for chat, Responses, Claude Messages, images, embeddings, rerank, audio, moderations, and Realtime.

Provider and model management

Manage providers, endpoints, upstream API keys, model bindings, model costs, cooldown release, and model connectivity tests.

Tokens and permissions

Control user tokens, admin tokens, RBAC roles, menus, API permissions, navigation permissions, groups, and model access policy.

Billing and monitoring

Track wallets, balances, transactions, usage records, active requests, model status checks, scheduled tasks, and system health.

Installation

Docker Compose with the prebuilt GHCR image is the recommended deployment path for stable releases. It starts PostgreSQL, Redis, and ghcr.io/zzispp/hook:latest, runs migrations, and serves frontend plus API from http://127.0.0.1:5555.

Docker Compose Prebuilt Image
git clone https://github.com/zzispp/Hook.git
cd Hook
HOOK_COMPOSE_FILES=docker-compose.prebuilt.yml ./deploy.sh
First run

./deploy.sh creates .env, asks for admin username, admin email, and admin password, then generates PostgreSQL password, JWT secret, and provider key secret automatically.

Pin an image tag

Stable releases publish latest and version tags. Main branch builds publish edge and nightly.

HOOK_IMAGE_TAG=v1.0.1 HOOK_COMPOSE_FILES=docker-compose.prebuilt.yml ./deploy.sh

Docker Compose Source Build

Use source build when you want to build the image locally from this checkout.

git clone https://github.com/zzispp/Hook.git
cd Hook
./deploy.sh

Useful commands

docker compose --env-file .env -f docker-compose.prebuilt.yml logs -f hook
docker compose --env-file .env -f docker-compose.prebuilt.yml ps
docker compose --env-file .env -f docker-compose.prebuilt.yml down

docker compose down stops containers without deleting Docker named volumes. Use docker compose down -v only when deployment data should be removed.

Update

After prebuilt-image Docker Compose deployment, run the update script from the deployment directory.

One-command update
HOOK_COMPOSE_FILES=docker-compose.prebuilt.yml ./update.sh

update.sh pulls the newest ghcr.io/zzispp/hook:${HOOK_IMAGE_TAG:-latest} image, pulls PostgreSQL and Redis base images, and recreates containers. It does not delete Docker named volumes.

For source-build deployments, run ./update.sh. It runs git pull --ff-only, rebuilds the Hook image from the current source tree, and recreates containers.

GitHub Release Packages

Release assets include Linux and macOS binary packages, install.sh, and SHA256SUMS. Binary packages are intended for deployments where PostgreSQL and Redis are already managed outside Hook.

Latest release installer
curl -fsSL https://github.com/zzispp/Hook/releases/latest/download/install.sh | sudo bash

The installer verifies the downloaded package, installs it under /opt/hook/releases/<version>, updates /opt/hook/current, writes /etc/hook/config.example.yaml, and creates /etc/hook/config.yaml when it does not already exist. Edit /etc/hook/config.yaml before running Hook.

/opt/hook/current/bin/generate_password_hash "your-password"
/opt/hook/current/bin/hook_backend --config /etc/hook/config.yaml migration up
/opt/hook/current/bin/hook_backend --config /etc/hook/config.yaml

Local Development

Requirements: Rust edition 2024 toolchain, Node.js >=22.12.0, pnpm 10.33.4, PostgreSQL, and Redis.

Source workflow
pnpm install
cp config/config.yaml config.yaml
scripts/generate-password-hash.sh "your-password"
cargo run -p hook_backend -- migration up
NEXT_PUBLIC_SERVER_URL=http://127.0.0.1:5555 pnpm build:frontend:embedded
NEXT_PUBLIC_SERVER_URL=http://127.0.0.1:5555 pnpm dev
Backendhttp://127.0.0.1:5555
Frontendhttp://127.0.0.1:8082
Checkscargo check -p hook_backend, pnpm lint:frontend, pnpm build:frontend

API Entrypoints

GET /healthHealth check endpoint.
/api/*Console, admin, auth, wallet, billing, provider, model, and monitoring APIs.
/v1/*OpenAI, Claude, and Jina compatible proxy routes.
/v1beta/*Gemini compatible proxy routes.

Common proxy routes

  • /v1/models
  • /v1/chat/completions
  • /v1/responses
  • /v1/messages
  • /v1/images/generations
  • /v1/embeddings
  • /v1/rerank
  • /v1/realtime

Configuration and Data

.envCreated by ./deploy.sh on first Docker Compose deployment.
POSTGRES_*Database name, user, and generated password for the PostgreSQL container.
HOOK_ADMIN_*Initial administrator username, email, and base64-encoded password value.
HOOK_JWT_SECRETGenerated signing secret used by the backend token system.
HOOK_PROVIDER_KEY_SECRETGenerated secret used for provider key protection.
hook-postgres / hook-redisDocker named volumes that keep deployment data across container rebuilds.

Acknowledgments

Hook references and is inspired by these open-source projects.