Vekil Reverse Proxy Deploy
Deploy Vekil as the single reverse-proxy endpoint for Claude/Anthropic, Gemini, OpenAI-compatible, and Codex clients. Prefer the bundled Kubernetes script for repeatable cluster deployments; use Docker only for quick local runs.
Standard Kubernetes Workflow
- Confirm the target before changing anything:
kubectl config current-contextkubectl cluster-info- For remote/shared clusters, state the context and ask before exposing
LoadBalancerorNodePortservices.
- Deploy the default zero-config Copilot-backed proxy:
scripts/deploy_vekil_reverse_proxy.sh --context <kubectl-context>- Default namespace:
vekil-system; default service:ClusterIP; default image:ghcr.io/sozercan/vekil:latest; default port:1337.
- If explicit provider routing is required, write or locate a JSON/YAML providers file that uses secret env references, then pass it with existing Kubernetes secrets:
scripts/deploy_vekil_reverse_proxy.sh \ --context <kubectl-context> \ --providers-config /path/to/providers.yaml \ --env-secret AZURE_OPENAI_API_KEY=azure-openai:key - For non-interactive Copilot auth in Kubernetes, either wire an existing Secret or let the script create/update one from an explicitly exported
COPILOT_GITHUB_TOKEN. Prefer existing Secrets for production clusters that use a secret manager.# Existing Secret scripts/deploy_vekil_reverse_proxy.sh \ --env-secret COPILOT_GITHUB_TOKEN=copilot-github-token:token # Script-created Secret; the token is not printed or embedded in the rendered workload. export COPILOT_GITHUB_TOKEN=... scripts/deploy_vekil_reverse_proxy.sh \ --create-copilot-token-secret copilot-github-token:token - Wait for rollout, then verify through a port-forward:
kubectl -n vekil-system port-forward svc/vekil 1337:1337 curl http://127.0.0.1:1337/healthz curl http://127.0.0.1:1337/readyz curl http://127.0.0.1:1337/v1/models
Provider and Auth Notes
- Zero-config mode uses Vekil's built-in GitHub Copilot upstream. In Kubernetes, device-code login can work from pod logs; use
--skip-wait, watchkubectl -n <namespace> logs deploy/<name>, complete the login, then verify/readyz.COPILOT_GITHUB_TOKENvia--env-secretor--create-copilot-token-secretis better for non-interactive deployments;--create-copilot-token-secretrequires localCOPILOT_GITHUB_TOKENand does not fall back to GitHub CLI OAuth tokens. If the script-created Secret changes, the script restarts the Deployment so the Secret-backed env var is reloaded. - Explicit provider configs should use
api_key_env, not inlineapi_key, because the bundled script stores the config as a ConfigMap and refuses inline API keys by default. When the script creates or updates the providers ConfigMap, it restarts the Deployment so Vekil reloads provider routing read at startup. - OpenAI Codex providers need
auth.jsonfromcodex login. If needed, mount an existing secret with--codex-auth-secret <secret>[:auth.json]and verify whether the deployment needs a writable token source for refresh behavior. - Vekil token cache defaults to an
emptyDir; use--token-pvc <claim>if preserving Vekil-managed cached auth across pod restarts matters.
Common Commands
Render the manifest without applying:
scripts/deploy_vekil_reverse_proxy.sh --print
Create/update a Copilot token Secret from an explicit local environment token and deploy:
export COPILOT_GITHUB_TOKEN=...
scripts/deploy_vekil_reverse_proxy.sh \
--create-copilot-token-secret copilot-github-token:token
Deploy to a custom namespace and expose inside the cluster:
scripts/deploy_vekil_reverse_proxy.sh --namespace ai-proxy --name vekil
Expose for a local kind/minikube workflow with an explicit context:
scripts/deploy_vekil_reverse_proxy.sh --context kind-orka --namespace vekil-system
kubectl --context kind-orka -n vekil-system port-forward svc/vekil 1337:1337
Use the local Docker quick-start instead of Kubernetes when the user only needs a workstation proxy:
docker run -p 1337:1337 \
-v ~/.config/vekil:/home/nonroot/.config/vekil \
ghcr.io/sozercan/vekil:latest
Client Smoke Tests
Run these only after /readyz succeeds and the requested model appears in /v1/models.
env ANTHROPIC_BASE_URL=http://127.0.0.1:1337 \
ANTHROPIC_API_KEY=dummy \
claude --model claude-sonnet-4 --print --output-format text "Reply with exactly PROXY_OK"
env OPENAI_API_KEY=dummy \
OPENAI_BASE_URL=http://127.0.0.1:1337/v1 \
codex exec --skip-git-repo-check -m gpt-5.5 "Reply with exactly PROXY_OK"
env GEMINI_API_KEY=dummy \
GOOGLE_GEMINI_BASE_URL=http://127.0.0.1:1337 \
GOOGLE_GENAI_API_VERSION=v1beta \
GEMINI_CLI_NO_RELAUNCH=true \
gemini -m gemini-2.5-pro -p "Reply with exactly PROXY_OK" -o json
Troubleshooting
- If rollout fails:
kubectl -n <namespace> describe deploy/<name>andkubectl -n <namespace> logs deploy/<name>. - If an existing Secret used with
--env-secretchanges outside this script, restart the Deployment so env vars reload:kubectl -n <namespace> rollout restart deploy/<name>. - If
/healthzworks but/readyzfails, focus on provider auth, provider config model ownership, upstream reachability, or missing secret env vars. - If clients cannot connect, verify the base URL path: Anthropic/Gemini use
http://host:1337; OpenAI/Codex usehttp://host:1337/v1. - Do not paste secrets into prompts, commit provider files with inline credentials, or expose a public service without confirming the user's intended security boundary.
- When zero-config mode falls back to GitHub Copilot device-code login, surface the login code and URL to the user and wait for their confirmation before continuing. Never complete the login on their behalf.