Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions zeude/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,28 @@ RUN VERSION=$(cat /tmp/version) && \

# Copy install and uninstall scripts
COPY scripts/install.sh /releases/install.sh
COPY scripts/install-server.sh /releases/install-server.sh
COPY scripts/uninstall.sh /releases/uninstall.sh

# Node build stage
FROM node:20-alpine AS builder
FROM node:20-bookworm-slim AS builder

WORKDIR /app

# Copy dashboard source
COPY dashboard/package*.json ./
RUN npm ci

ENV NODE_ENV=production
ENV DATABASE_PROVIDER=sqlite
ENV DATABASE_PATH=/tmp/zeude-build.db
ENV SESSION_SECRET=build-session-secret
ENV NEXT_PUBLIC_APP_URL=http://localhost:3000
ENV CLICKHOUSE_URL=http://localhost:8123
ENV CLICKHOUSE_USER=default
ENV CLICKHOUSE_PASSWORD=build
ENV CLICKHOUSE_DATABASE=default

COPY dashboard .

# Copy pre-built Go binaries
Expand All @@ -53,15 +64,17 @@ COPY --from=go-builder /releases ./public/releases
RUN npm run build

# Production stage
FROM node:20-alpine AS runner
FROM node:20-bookworm-slim AS runner

WORKDIR /app

ENV NODE_ENV=production

# Create non-root user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN groupadd --system --gid 1001 nodejs && \
useradd --system --uid 1001 --gid 1001 nextjs && \
mkdir -p /var/lib/zeude && \
chown -R nextjs:nodejs /var/lib/zeude

# Copy built assets
COPY --from=builder /app/public ./public
Expand All @@ -74,5 +87,7 @@ EXPOSE 3000

ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENV DATABASE_PROVIDER=sqlite
ENV DATABASE_PATH=/var/lib/zeude/zeude.db

CMD ["node", "server.js"]
58 changes: 54 additions & 4 deletions zeude/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Zeude gives engineering teams visibility into how Claude Code and OpenAI Codex a
- **Understand usage** — See who's using what, how much it costs, and which prompts work best
- **Distribute knowledge** — Push skills, MCP servers, hooks, and agent profiles to your whole team
- **Support multiple tools** — Monitor both Claude Code and OpenAI Codex from one place
- **Own your data** — Self-hosted with Supabase + ClickHouse, no data leaves your infrastructure
- **Own your data** — Self-hosted with SQLite + ClickHouse, no data leaves your infrastructure

## Features

Expand All @@ -32,7 +32,7 @@ Developer Machine Self-Hosted Infrastructure
┌──────────────────────┐ ┌────────────────────────────┐
│ │ │ │
│ claude/codex (shim) │──── on startup ──▶│ Zeude Dashboard (Next.js) │
│ ~/.zeude/bin/ │ sync config │ ├── Supabase (users, config)
│ ~/.zeude/bin/ │ sync config │ ├── SQLite (users, config)
│ │ │ │ └── ClickHouse (telemetry)│
│ ▼ │ │ │
│ real claude/codex │ │ OTel Collector │
Expand All @@ -57,13 +57,31 @@ When you run `claude` (or `codex`), the Zeude shim:

### 1. Deploy the dashboard

Zeude now supports SQLite as the only operational runtime database. Supabase is migration-only and is no longer supported as a live runtime backend.

```bash
cd dashboard
cp .env.example .env.local # configure Supabase + ClickHouse URLs
cp .env.example .env.local
npm install
npm run migrate:sqlite
npm run dev
```

For a single-host production deploy:

```bash
cd dashboard
cp .env.example .env
docker compose up -d --build
```

Or install from the repo root with the server installer:

```bash
cd zeude
bash scripts/install-server.sh
```

### 2. Install the CLI shim

```bash
Expand Down Expand Up @@ -95,7 +113,7 @@ zeude/
├── dashboard/
│ ├── src/app/ # Next.js App Router pages & API routes
│ ├── clickhouse/ # ClickHouse schema, migrations, and tests
│ └── supabase/ # Supabase migrations
│ └── supabase/ # Legacy Supabase schema used for one-time migration
├── scripts/ # Build and install scripts
├── deployments/ # OTel Collector config
└── Dockerfile # Multi-platform binary builder
Expand Down Expand Up @@ -129,6 +147,8 @@ dashboard_url=https://your-dashboard-url
```bash
cd dashboard
npm install
cp .env.example .env.local
npm run migrate:sqlite
npm run dev # http://localhost:3000

# Run tests
Expand All @@ -138,6 +158,36 @@ npm test # 202 vitest tests
SKIP_AUTH=true MOCK_API=true npm run dev
```

### Existing Supabase -> SQLite migration

If you have an existing Supabase-backed deployment, migrate it to SQLite before upgrading to this runtime model. After the migration, Zeude runs against SQLite for operational state.

```bash
cd dashboard
SUPABASE_URL=... \
SUPABASE_SERVICE_ROLE_KEY=... \
DATABASE_PATH=.data/zeude.db \
npm run migrate:supabase-to-sqlite -- --dry-run

SUPABASE_URL=... \
SUPABASE_SERVICE_ROLE_KEY=... \
DATABASE_PATH=.data/zeude.db \
npm run migrate:supabase-to-sqlite
```

Use `--force` only when you intentionally want to import into a non-empty SQLite DB.

### Basic server verification

After `install-server.sh` or `docker compose up -d --build`:

```bash
curl -s http://localhost:3000/api/health
docker compose --env-file /opt/zeude/config/zeude.env -f /opt/zeude/app/dashboard/docker-compose.yaml ps
docker compose --env-file /opt/zeude/config/zeude.env -f /opt/zeude/app/dashboard/docker-compose.yaml logs -f
sqlite3 /var/lib/zeude/zeude.db ".tables"
```

### Go binaries

```bash
Expand Down
20 changes: 20 additions & 0 deletions zeude/dashboard/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
NODE_ENV=development
DATABASE_PATH=.data/zeude.db
ZEUDE_DATA_DIR=.data
SESSION_SECRET=dev-session-secret

NEXT_PUBLIC_APP_URL=http://localhost:3000

CLICKHOUSE_URL=http://localhost:8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=dev
CLICKHOUSE_DATABASE=default

# Optional, only for one-time migration from an existing Supabase deployment
SUPABASE_URL=
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=

# Optional
OPENROUTER_API_KEY=
OPENROUTER_MODEL=anthropic/claude-3.5-sonnet
1 change: 1 addition & 0 deletions zeude/dashboard/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ yarn-error.log*

# env files (can opt-in for committing if needed)
.env*
!.env.example

# vercel
.vercel
Expand Down
22 changes: 17 additions & 5 deletions zeude/dashboard/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,41 @@
# This file is for local dashboard-only development

# Build stage
FROM node:20-alpine AS builder
FROM node:20-bookworm-slim AS builder

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci

ENV NODE_ENV=production
ENV DATABASE_PATH=/tmp/zeude-build.db
ENV SESSION_SECRET=build-session-secret
ENV NEXT_PUBLIC_APP_URL=http://localhost:3000
ENV CLICKHOUSE_URL=http://localhost:8123
ENV CLICKHOUSE_USER=default
ENV CLICKHOUSE_PASSWORD=build
ENV CLICKHOUSE_DATABASE=default

# Copy source and build
COPY . .

# Build with standalone output
RUN npm run build

# Production stage
FROM node:20-alpine AS runner
FROM node:20-bookworm-slim AS runner

WORKDIR /app

ENV NODE_ENV=production

# Create non-root user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Create non-root user and SQLite data dir
RUN groupadd --system --gid 1001 nodejs && \
useradd --system --uid 1001 --gid 1001 nextjs && \
mkdir -p /var/lib/zeude && \
chown -R nextjs:nodejs /var/lib/zeude

# Copy built assets
COPY --from=builder /app/public ./public
Expand All @@ -38,5 +49,6 @@ EXPOSE 3000

ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENV DATABASE_PATH=/var/lib/zeude/zeude.db

CMD ["node", "server.js"]
61 changes: 41 additions & 20 deletions zeude/dashboard/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,57 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
# Zeude Dashboard

## Getting Started
Operational state lives in SQLite. Analytics stay in ClickHouse.

First, run the development server:
SQLite is the only supported operational runtime database. Supabase is retained only as a one-time migration source.

## Local development

```bash
cp .env.example .env.local
npm install
npm run migrate:sqlite
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
Default local SQLite path is `.data/zeude.db`.

## One-time migration from Supabase

Existing Supabase-backed deployments must migrate to SQLite before upgrading to this runtime model.

```bash
SUPABASE_URL=... \
SUPABASE_SERVICE_ROLE_KEY=... \
DATABASE_PATH=.data/zeude.db \
npm run migrate:supabase-to-sqlite -- --dry-run

SUPABASE_URL=... \
SUPABASE_SERVICE_ROLE_KEY=... \
DATABASE_PATH=.data/zeude.db \
npm run migrate:supabase-to-sqlite
```

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
Use `--force` only if the target SQLite DB already has data and you intend to replace conflicting rows.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## Production

## Learn More
`docker-compose.yaml` now assumes:

To learn more about Next.js, take a look at the following resources:
- `DATABASE_PATH=/var/lib/zeude/zeude.db`
- a persistent volume mounted at `/var/lib/zeude`

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
ClickHouse remains external and must still be configured via env vars.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
From the repo root you can also run:

## Deploy on Vercel
```bash
bash scripts/install-server.sh
```

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Quick smoke checks after install:

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
```bash
curl -s http://localhost:3000/api/health
docker compose --env-file /opt/zeude/config/zeude.env -f /opt/zeude/app/dashboard/docker-compose.yaml ps
sqlite3 /var/lib/zeude/zeude.db ".tables"
```
15 changes: 8 additions & 7 deletions zeude/dashboard/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
version: '3.8'

services:
dashboard:
build:
context: .
context: ..
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- SUPABASE_URL=${SUPABASE_URL}
- SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
- SUPABASE_SERVICE_ROLE_KEY=${SUPABASE_SERVICE_ROLE_KEY}
- DATABASE_PATH=/var/lib/zeude/zeude.db
- SESSION_SECRET=${SESSION_SECRET}
- CLICKHOUSE_URL=${CLICKHOUSE_URL}
- CLICKHOUSE_USER=${CLICKHOUSE_USER}
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD}
- CLICKHOUSE_DATABASE=${CLICKHOUSE_DATABASE}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY:-}
- OPENROUTER_MODEL=${OPENROUTER_MODEL:-anthropic/claude-3.5-sonnet}
volumes:
- ${ZEUDE_DATA_DIR:-/var/lib/zeude}:/var/lib/zeude
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"]
test: ["CMD", "node", "-e", "fetch('http://localhost:3000/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
interval: 30s
timeout: 10s
retries: 3
Expand Down
1 change: 1 addition & 0 deletions zeude/dashboard/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const withBundleAnalyzer = bundleAnalyzer({

const nextConfig: NextConfig = {
output: 'standalone',
serverExternalPackages: ['better-sqlite3'],
experimental: {
optimizePackageImports: ['recharts', 'lucide-react'],
},
Expand Down
Loading