Skip to content

clustralabs/kaelix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kaelix

Self-hostable deployment platform. One docker compose. Your fleet. Comparable in scope to Coolify / Dokploy, simpler than Vercel.

Status: Phase 1. Auth, organizations, projects, API keys, REST API, RBAC, Solid Queue, React/Inertia dashboard, all running on Postgres. See docs/PHASE_0.md for the design and the Phase 2/3 backlog.

Stack

  • Backend — Rails 8.1, Ruby 3.4
  • Frontend — Inertia.js + React 19 + Tailwind v4
  • DB — PostgreSQL 16
  • Jobs / cache / websockets — Solid Queue, Solid Cache, Solid Cable (all Postgres-backed, no Redis in Phase 1)
  • Bundler — Bun 1.3 (also drives Vite at :3036)
  • Auth (web) — Devise (cookie sessions)
  • Auth (API) — opaque klx_… bearer tokens
  • Authorization — Pundit (role-based per organization)

Quickstart (Docker, one command)

Prereqs: Docker Desktop (or any Docker ≥ 24 + Compose v2), nothing else.

docker compose up --build

What you get:

Service Port What it is
db 5432 PostgreSQL 16
web 3000 Rails (Puma + Inertia + Tailwind + Vite)
worker Solid Queue supervisor + workers

On first boot the entrypoint:

  1. Waits for Postgres
  2. Installs gems + JS deps into named volumes (cached across restarts)
  3. db:prepare (loads db/schema.rb into the dev DB) + seeds a demo user
  4. Starts the web (foreman with web + vite + css) and the worker

Visit http://localhost:3000 and sign in with the seeded user:

email:    demo@kaelix.local
password: demopass123

Or create a new account from /users/sign_up — your first organization is created automatically.

Useful commands

docker compose logs -f web         # tail Rails logs
docker compose logs -f worker      # tail Solid Queue supervisor
docker compose exec web bash       # shell into the web container
docker compose exec web bin/rails db:migrate
docker compose exec web bin/rails console
docker compose down                # stop (keeps volumes)
docker compose down -v             # stop + delete volumes (full reset)

Local dev without Docker

Prereqs: Ruby 3.4.9 (via mise/rbenv/asdf), Postgres 16, Node 22+, Bun 1.3+.

bundle install
bun install
bin/rails db:prepare db:seed
bin/dev

bin/dev is foreman; it runs web (Puma) + vite (HMR) + css (Tailwind watch). Open http://localhost:3000.

Architecture (TL;DR)

                ┌──────────────────────────────────────────────┐
                │            kaelix (control plane)            │
   Browser ───► │  Rails 8.1                                   │
   (Inertia)    │  ├─ Web (Puma) — Inertia + JSON API          │
                │  ├─ Worker (Solid Queue) — build/deploy jobs │
   CLI ───────► │  └─ Solid Queue supervisor / cron            │
   (API token)  └─────┬───────────────────────────┬──────────┘
                      │                           │
                      ▼                           ▼
                ┌──────────┐               ┌──────────────┐
                │ Postgres │               │ Target nodes │
                │  (one)   │               │ (ssh agents) │
                └──────────┘               └──────────────┘

See docs/PHASE_0.md for the full architecture, schema, API contracts, RBAC matrix, and the Phase 2/3 plan (deployments, servers, domains, templates, volumes, build workers).

Project layout

app/
  controllers/
    application_controller.rb     # Inertia + Pundit + shared props
    users/                        # Devise overrides (Inertia-shaped)
    dashboard_controller.rb
    organizations_controller.rb
    projects_controller.rb
    memberships_controller.rb
    api_keys_controller.rb
    api/v1/                       # JSON API (Bearer token auth)
      base_controller.rb          # ApiKey.authenticate + Pundit
      auth_controller.rb          # POST /api/v1/auth/login
      me_controller.rb            # GET  /api/v1/me
      organizations_controller.rb
      projects_controller.rb
      memberships_controller.rb
      api_keys_controller.rb
  models/
    user.rb organization.rb membership.rb project.rb api_key.rb
  policies/                       # Pundit
  services/                       # PORO service objects (Auth, ApiKey, Membership, Project)
  jobs/
    application_job.rb
    deployments/create_job.rb     # Phase 2 stub: logs "would deploy", flips status
    projects/ping_job.rb
    projects/notify_job.rb
  frontend/
    entrypoints/inertia.tsx
    pages/                        # React pages, resolved by Inertia
    components/                   # Layout, Field, Button

db/
  schema.rb                       # primary + Solid Queue/Cache/Cable tables
  seeds.rb                        # demo user + org + project in development

config/
  database.yml                    # single PG; primary connection
  initializers/
    cors.rb                       # public API
    devise.rb
    inertia_rails.rb

docs/
  PHASE_0.md                      # design doc

docker-compose.yml                # db, web, worker
Dockerfile                        # dev-friendly, ~10s build (deps in entrypoint)
Procfile                          # web (Puma) + vite + css (Tailwind)
bin/docker-entrypoint             # wait-db, bundle, bun, db:prepare, exec

API

All endpoints under /api/v1/. Bearer token (the klx_… string, shown once when the key is created) in the Authorization header.

# Login → returns a token
curl -X POST localhost:3000/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo@kaelix.local","password":"demopass123"}'

# Use the token
curl localhost:3000/api/v1/me -H "Authorization: Bearer klx_…"
curl localhost:3000/api/v1/organizations
curl -X POST localhost:3000/api/v1/organizations/demo-org/projects \
  -H "Authorization: Bearer klx_…" -H 'Content-Type: application/json' \
  -d '{"project":{"name":"web","repository_url":"https://github.com/me/web","branch":"main"}}'

Full contract: docs/PHASE_0.md.

Phase 0/1 — what's done, what's next

Phase 0 (doc) — planning, schema, API contracts, RBAC matrix.

Phase 1 (this commit) — backend foundation:

  • Auth: Devise (web) + bearer tokens (API)
  • Organizations, memberships, RBAC (Pundit, 4 roles)
  • Projects CRUD (web + API)
  • API keys with HMAC-stored secrets, scopes, expiry
  • Service objects under app/services/
  • Solid Queue wired (worker container, deployments/create_job stub)
  • Inertia/React dashboard for everything above
  • One-command Docker bring-up

Phase 2 — deployments: servers, deployments, domains, env_vars, logs, webhooks, build workers on target nodes via SSH.

Phase 3 — templates, volumes, notifications, audit log UI, billing hooks.

License

MIT.

About

Self Hostable Deployment Solution

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors