Skip to content

Quickstart ​

Get the full Gatez gateway stack running locally and make your first authenticated request. Time estimate: 5 minutes.

Prerequisites ​

RequirementMinimumCheck command
Docker24.0+docker --version
Docker Composev2.20+docker compose version
RAM16 GB--
git2.xgit --version
curlanycurl --version
python33.8+python3 --version (used by setup scripts for JSON parsing)

WARNING

The full stack runs 15+ containers. With less than 16 GB of RAM, services like Zitadel and ClickHouse may fail to start or become unresponsive.

Step 1: Clone the Repository ​

bash
git clone https://github.com/your-org/gatez.git
cd gatez

Step 2: Create Your Environment File ​

bash
cp .env.example .env

Edit .env and configure your LLM provider API keys. At minimum, set one provider key or use the local Ollama fallback (no key needed):

bash
# .env
ZITADEL_ADMIN=admin
ZITADEL_ADMIN_PASSWORD=changeme
CLICKHOUSE_PASSWORD=changeme
LITELLM_MASTER_KEY=sk-local-dev-key
APISIX_ADMIN_KEY=edd1c9f034335f136f87ad84b625c8f1

# Set at least one LLM provider key (or leave empty to use Ollama only)
OPENAI_API_KEY=sk-your-openai-key-here
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key-here
GEMINI_API_KEY=your-gemini-key-here

DANGER

Never commit .env to version control. The pre-commit hook blocks it, but double-check your .gitignore.

Step 3: Start the Stack ​

bash
docker compose up -d

Expected output:

[+] Running 15/15
 ✔ Network gatez_gateway-net     Created
 ✔ Container etcd                Started
 ✔ Container gw-redis            Started
 ✔ Container clickhouse          Started
 ✔ Container qdrant              Started
 ✔ Container mock-backend        Started
 ✔ Container jaeger              Started
 ✔ Container otel-collector      Started
 ✔ Container prometheus          Started
 ✔ Container gw-grafana          Started
 ✔ Container gw-zitadel          Started
 ✔ Container apisix              Started
 ✔ Container ai-gateway          Started
 ✔ Container agent-gateway       Started
 ✔ Container control-plane-api   Started
 ✔ Container landing-page        Started

Step 4: Wait for Health Checks ​

Services need time to initialize, especially Zitadel (~30s) and ClickHouse (~10s). Monitor readiness:

bash
docker compose ps

Wait until all containers show healthy status. You can watch in real time:

bash
watch -n 5 'docker compose ps --format "table {{.Name}}\t{{.Status}}"'

Expected output when ready:

NAME                STATUS
apisix              Up 2 minutes (healthy)
ai-gateway          Up 2 minutes (healthy)
agent-gateway       Up 2 minutes (healthy)
clickhouse          Up 2 minutes (healthy)
control-plane-api   Up 2 minutes (healthy)
etcd                Up 2 minutes (healthy)
gw-grafana          Up 2 minutes (healthy)
gw-zitadel          Up 2 minutes (healthy)
gw-redis            Up 2 minutes (healthy)
mock-backend        Up 2 minutes (healthy)
otel-collector      Up 2 minutes
prometheus          Up 2 minutes
qdrant              Up 2 minutes (healthy)

:::note Zitadel can take up to 60 seconds on first start. If it shows starting, wait and recheck. :::

Step 5: Run the Smoke Test ​

bash
./scripts/smoke-test.sh

Expected output:

================================
  Gateway Platform Smoke Test
================================

[INFO] Step 1: Checking service health...
[PASS] APISIX admin API is up
[PASS] Mock backend is up
[PASS] AI Gateway is up
[PASS] ClickHouse is up
[PASS] Redis is up (via docker health)

[INFO] Step 2: Creating smoke-test route in APISIX...
[PASS] Route created successfully

[INFO] Step 3: Testing proxied request through APISIX...
[PASS] Request proxied successfully through APISIX to mock backend

[INFO] Step 4: Testing rate limiting...
[PASS] Rate limit plugin configured (limit-count: 100/60s)

[INFO] Step 5: Verifying ClickHouse schema...
[PASS] All ClickHouse tables created

[INFO] Step 6: Checking AI Gateway endpoints...
[PASS] AI Gateway model listing works

[INFO] Step 7: Checking observability stack...
[PASS] Prometheus is up
[PASS] Jaeger UI is up
[PASS] Grafana is up

================================
  SMOKE TEST PASSED
================================

Step 6: Set Up Authentication ​

Run the Zitadel setup script to create the gateway organization, the apisix-client OAuth client, and test users with tenant_id attributes:

bash
./scripts/zitadel-setup.sh

This creates:

UserPasswordTenant
testusertestpasstenant-alpha
user-betatestpasstenant-beta
admin-usertestpasstenant-alpha

Then configure the authenticated APISIX routes:

bash
./scripts/setup-routes.sh

This creates four routes:

PathAuthUpstream
/NoneHealth check (static response)
/smoke/*None (X-Tenant-ID header)Mock backend
/api/*JWT requiredMock backend
/v1/*JWT requiredAI Gateway

Step 7: Make Your First Authenticated Request ​

Get a JWT token from Zitadel:

bash
TOKEN=$(curl -s -X POST http://localhost:8085/oauth/v2/token \
  -d "client_id=apisix-client" \
  -d "client_secret=apisix-client-secret" \
  -d "username=testuser" \
  -d "password=testpass" \
  -d "grant_type=password" \
  -d "scope=openid tenant" \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

Make an authenticated API call through APISIX:

bash
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:9080/api/get | python3 -m json.tool

Expected output (proxied to mock backend via httpbin):

json
{
    "args": {},
    "headers": {
        "Accept": "*/*",
        "Host": "localhost",
        "X-Request-Id": "a1b2c3d4-...",
        "X-Forwarded-For": "172.18.0.1",
        "Authorization": "Bearer eyJhbG..."
    },
    "origin": "172.18.0.1",
    "url": "http://localhost/get"
}

Test the AI Gateway (requires at least one LLM provider key in .env):

bash
curl -s -X POST http://localhost:9080/v1/chat/completions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Hello"}]
  }' | python3 -m json.tool

Service Endpoints ​

After startup, the following services are accessible:

ServiceURLCredentials
APISIX Proxyhttp://localhost:9080Via JWT token
APISIX Admin APIhttp://localhost:9180X-API-KEY: edd1c9f034335f136f87ad84b625c8f1
AI Gatewayhttp://localhost:4000Direct access (bypasses L1)
Agent Gatewayhttp://localhost:5001Direct access (bypasses L1)
Control Plane APIhttp://localhost:4001Master key or JWT
Zitadel Adminhttp://localhost:8085admin / changeme
Grafanahttp://localhost:3002admin / admin
Prometheushttp://localhost:9090No auth
Jaegerhttp://localhost:16686No auth
ClickHouse HTTPhttp://localhost:8123No auth (local dev)

Troubleshooting ​

Zitadel fails to start or stays in "starting" state ​

Zitadel needs up to 60 seconds and at least 512 MB of free RAM. Check logs:

bash
docker logs gw-zitadel --tail 50

If services crash, increase Docker's memory allocation to at least 8 GB (Docker Desktop > Settings > Resources).

APISIX returns 502 Bad Gateway ​

The upstream service is not yet healthy. Check that mock-backend, ai-gateway, or whichever upstream is targeted is running:

bash
docker compose ps mock-backend ai-gateway

APISIX starts before upstream services may be ready. Wait for health checks to pass.

Port conflicts ​

Gatez uses non-default ports to avoid conflicts. If you still have conflicts:

bash
# Find what is using a port (example: 9080)
lsof -i :9080

Common conflicts: Redis on 6379 (Gatez maps to 6380), Zitadel on 8080 (Gatez maps to 8085), Grafana on 3000 (Gatez maps to 3002).

smoke-test.sh fails at "ClickHouse not reachable" ​

ClickHouse may still be initializing. Wait 10-15 seconds and retry:

bash
curl -s "http://localhost:8123/?query=SELECT%201"

If it returns 1, ClickHouse is ready. Re-run the smoke test.

Token fetch returns "invalid_grant" or "invalid_client" ​

Ensure you ran ./scripts/zitadel-setup.sh first. The gateway organization and apisix-client must exist before tokens can be issued.

AI Gateway returns 503 or "no models available" ​

No LLM provider API keys are configured. Either:

  • Add at least one key (OPENAI_API_KEY, ANTHROPIC_API_KEY, or GEMINI_API_KEY) to .env and restart: docker compose up -d ai-gateway
  • Or use the local Ollama model by running Ollama on your host machine (the local-llm model is always available)

Container builds fail (ai-gateway, agent-gateway, control-plane-api) ​

These services build from source (Rust). Ensure Docker has at least 4 GB of memory for compilation. First build takes 3-5 minutes.

bash
docker compose build ai-gateway agent-gateway control-plane-api

Resetting everything ​

To tear down and start fresh:

bash
docker compose down -v
docker compose up -d

WARNING

The -v flag deletes all volumes (ClickHouse data, Redis state, Grafana dashboards). Only use this for a full reset.

Next Steps ​

Enterprise API + AI + Agent Gateway