Canonical docs hub: docs/README.md
Next.js 16.1.6 + React 19.2.4 + TypeScript 5.9 + Tailwind CSS 4 + Prisma 7 + PostgreSQL 16
flowchart TD
internet["Internet"]
nginx["Nginx reverse proxy"]
dashboard["Next.js dashboard<br/>127.0.0.1:3000"]
proxy["CLIProxyAPI<br/>127.0.0.1:8317"]
postgres["PostgreSQL<br/>internal Docker network"]
dockerproxy["docker-socket-proxy<br/>internal Docker network"]
authvol["auth volume"]
logsvol["logs volume"]
collector["Embedded usage collector worker<br/>resident in dashboard container"]
internet --> nginx
nginx -->|"dashboard host"| dashboard
nginx -->|"API host"| proxy
dashboard -->|"Prisma"| postgres
dashboard -->|"Docker CLI via DOCKER_HOST"| dockerproxy
dashboard -->|"/api/management/[...path]<br/>CLIPROXYAPI_MANAGEMENT_URL"| proxy
proxy --> authvol
proxy --> logsvol
collector --> postgres
- The dashboard UI and its authenticated
/api/*routes live behind the dashboard hostname and terminate in the Next.js service. - OpenAI-compatible inference traffic lives behind the API hostname and terminates directly in CLIProxyAPI.
- The dashboard does not sit on the hot path for
/v1/*inference traffic in the current architecture. - The repo ships
../infrastructure/nginx/cliproxyapi-dashboard.http.conf.templatefor this split-host ingress pattern.
- Dashboard (
apps/dashboard/)- Next.js UI and API routes
- JWT session auth
- Prisma access to PostgreSQL
- provider ownership and custom-provider orchestration
- update and container-operation control plane
- Runtime stack (
infrastructure/)- bundled Docker Compose deployment
- loopback-bound dashboard and proxy API
- internal PostgreSQL network
manage.shfor runtime control plus backup and restore operations- webhook helpers
apps/dashboard/src/
├── app/ App Router pages and API handlers
│ ├── api/ authenticated/admin/runtime route handlers
│ └── dashboard/ authenticated dashboard surfaces
├── components/ shared UI building blocks
├── features/ feature-scoped UI and domain modules
├── lib/ shared utilities, clients, and React hooks
└── server/ server-only auth, db, jobs, and usage services
├── auth/ session and origin-validation helpers
├── db/ Prisma client and generated output
│ └── generated/ generated Prisma client under db ownership
└── jobs/ resident usage collector runtime
/
├── /login
├── /setup
└── /dashboard
├── /
├── /providers
│ └── /oauth
│ ├── /connect
│ └── /model-alias
├── /api-keys
├── /usage
├── /quota
├── /config
├── /settings
├── /monitoring
├── /logs
├── /containers
├── /setup
└── /admin
├── /users
└── /logs
DashboardOverviewPage: overall health, usage summary, model catalog, quick linksProvidersPage: provider API keys, OAuth accounts, custom providers, provider admin settingsApiKeysPage: dashboard-issued client credentialsUsagePage: persistent usage analytics based onGET /api/usage/historyQuotaPage: provider quota aggregation and capacity windowsConfigPage: managed CLIProxyAPI runtime settings and YAML previewSettingsPage: password changes, session revoke, proxy update, dashboard update, deploy flowDashboardSetupPage: authenticated onboarding checklist after loginMonitoringPage: proxy health, usage polling, live logs, restart actionsLogsPage: log-focused monitoring entryContainersPage: allowlisted container inspection and actionsAdminUsersPage: user and role managementAdminLogsPage: audit log reviewOAuthConnectPageandOAuthModelAliasPage: provider connect/model-alias workflows
The 48 route handlers fall into these groups.
/api/auth/*for login, logout, password change, and current-session lookups/api/setupfor first-admin bootstrap/api/setup-statusfor post-login onboarding state
/api/admin/users/api/admin/settings/api/admin/logs/api/admin/deploy/api/admin/revoke-sessions/api/admin/migrate-api-keys
/api/user/api-keys/api/providers/keys/api/providers/oauth/*/api/custom-providers/*/api/provider-groups/*/api/model-preferences/api/management/oauth-callback
/api/management/[...path]as the management API passthrough layer/api/proxy/status/api/proxy/oauth-settings/api/restart/api/containers/*/api/update/api/update/check/api/update/dashboard/check/api/health
/api/quota/api/usage/collectas an authenticated fast wake/trigger seam for the resident worker/api/usage/history/api/usageas a deprecated compatibility route
User
├── UserApiKey
├── ProviderKeyOwnership
├── ProviderOAuthOwnership
├── CustomProvider
├── ProviderGroup
├── ModelPreference
├── AuditLog
└── UsageRecord
CustomProvider
├── CustomProviderModel
└── CustomProviderExcludedModel
SystemSetting
CollectorState
User: dashboard identity, admin role, session invalidation viasessionVersionUserApiKey: dashboard-issued client API keysProviderKeyOwnership: direct provider-key ownership mappingProviderOAuthOwnership: OAuth account ownership mappingModelPreference: per-user excluded model preferencesCustomProvider: user-managed OpenAI-compatible upstream definitionProviderGroup: grouping, ordering, and activation state for custom providersSystemSetting: global dashboard settings such as provider-key limitsAuditLog: admin and security trailUsageRecord: persistent usage facts collected from CLIProxyAPICollectorState: runtime metadata for collector leadership, trigger overlap, and progress visibility
- CLIProxyAPI (
eceasy/cli-proxy-api:latest, upstreamrouter-for-me/CLIProxyAPI) for proxy runtime and management API - PostgreSQL 16 (
postgres:16-alpine) for persistent storage - Docker socket proxy (
tecnativa/docker-socket-proxy:latest) for restricted Docker API access - GHCR dashboard image (
ghcr.io/<repo>/dashboard) for published dashboard builds
lib/api-endpoints.ts: shared route constantslib/errors.ts: canonical API response helperslib/env.ts: env schema and validationlib/proxy-runtime.ts: proxy container and compose-path resolutionlib/providers/management-api.ts: management API wrapper and process-local mutexlib/usage/history.ts: persistent usage snapshot and aggregation logicfeatures/containers/containers.ts: allowlist for container managementserver/auth/lib/origin.ts: effective-origin validation for state-changing authenticated requests
- The production dashboard image runs
../apps/dashboard/scripts/runtime/entrypoint.sh, which applies the baseline Prisma migration chain withprisma migrate deploybefore starting the server. - Source development uses the same baseline migration chain with
prisma migrate deploy. - The Docker stack itself does not include a public ingress service. The repo ships an optional Nginx template, and
install.shcan install Nginx as an HTTP reverse proxy starter outside the Compose stack. - The bundled deployment assumes a single dashboard instance.
providerMutexin../apps/dashboard/src/lib/providers/management-api.tsis process-local only.../apps/dashboard/prisma/schema.prismais the active source of truth for the data model.
setup/login
-> hash password with bcrypt
-> sign JWT with jose
-> store session cookie
-> verify JWT on server
-> invalidate globally via users.sessionVersion