Skip to content

Architecture overview

Keferboeck Ltd runs two applications on one shared DigitalOcean droplet, deployed with Kamal and fronted by kamal-proxy (TLS via Let's Encrypt).

flowchart LR
    subgraph Visitors
        V[Browser]
    end

    subgraph Droplet["keferboeck-ltd droplet · 161.35.42.199 · lon1"]
        P[kamal-proxy 80/443]
        subgraph Website["keferboeck.com (Next.js)"]
            W[keferboeck-web]
            WDB[(keferboeck Postgres)]
        end
        subgraph Portal["hub.keferboeck.com (Rails 8)"]
            H[portal-web]
            HDB[(portal Postgres)]
        end
    end

    subgraph External
        MJ[Mailjet HTTP API]
        ST[Stripe]
        AN[Anthropic API]
        GH[GitHub]
    end

    V --> P
    P --> W
    P --> H
    W --> WDB
    H --> HDB
    H -. read only .-> WDB
    W -- workshop + newsletter relay --> H
    W --> AN
    H --> AN
    H --> MJ
    GH -. kamal deploy from laptop .-> Droplet

The website — keferboeck.com

  • Repo: keferboeck/keferboeck.com, local ~/Development/RoR/keferboeck.com.
  • Stack: Next.js (App Router), Tailwind, Prisma on Postgres, framer-motion. Bilingual (en-gb, de-at).
  • Notable: articles with seeded content, the AI advisor (/api/advisor, Anthropic), the free workshop signup, the newsletter banner (relays server side to the portal with a shared secret so the secret never reaches a browser), the demo store showcase pages.
  • Deploy: kamal deploy from the repo. Builder uses the plain docker driver (see incident log: buildkit registry pushes failed).

The portal (hub) — hub.keferboeck.com

  • Repo: keferboeck/keferboeck-portal, local ~/Development/RoR/georgkeferboeck/keferboeck-portal.
  • Stack: Rails 8.1, Hotwire (Turbo + Stimulus), Tailwind, Solid Queue/Cache/Cable in a single Postgres, Devise with mandatory TOTP two factor, Active Record encryption.
  • Domains: companies and users, documents, workshop requests with indicative pricing, the newsletter (contacts, topics, append-only consent ledger, vouchers), campaigns and AB tests, the growth simulator (scenarios, debts, committed projects, actuals), the charity pledge (charities, donations), audit events on every admin action.
  • Deploy: kamal deploy; the container entrypoint runs db:prepare, so migrations apply on boot.

Cross-app integration

  • The website relays workshop requests and newsletter signups server side to the portal API, authenticated by the shared WORKSHOP_SHARED_SECRET header.
  • The portal has read only access to the website database (SITE_DATABASE_URL) for advisor insights and search statistics.
  • The five Solidus demo shops (documented in their own knowledge base) push leads into the portal's consent ledger with per-store API keys.