| 1 | # Klonkt
|
|---|
| 2 |
|
|---|
| 3 | Your own, **self-hosted** corner of the web — for your story, your visuals and
|
|---|
| 4 | your sound. Built on **Node + SQLite + htmx**: lightweight, server-rendered, and
|
|---|
| 5 | yours. No algorithm, no ads, no platform sitting in between.
|
|---|
| 6 |
|
|---|
| 7 | ## What it does
|
|---|
| 8 |
|
|---|
| 9 | - **Solo or hub** — one personal site, or a label/collective with multiple
|
|---|
| 10 | makers under one roof.
|
|---|
| 11 | - **Blog & photos** — posts with cover, tags, timeline or grid.
|
|---|
| 12 | - **Host your own music** — built-in audio player with tracks, albums and playlists.
|
|---|
| 13 | - **Fans & comments** — visitors sign in with Google (optional) and comment.
|
|---|
| 14 | - **Grow**: newsletter, download-for-email, EPK/press kit, link-in-bio,
|
|---|
| 15 | show calendar, and **cookie-free statistics**.
|
|---|
| 16 | - **Circles** — connect your site with other Klonkt sites and show each other's
|
|---|
| 17 | public posts; decentralized, with no central platform (Ed25519-signed federation).
|
|---|
| 18 | - **Themes & languages** — multiple palettes (light + dark), interface in EN/NL/DE.
|
|---|
| 19 | - **Installable (PWA)**, **privacy-first** (self-hosted fonts, no tracking).
|
|---|
| 20 |
|
|---|
| 21 | ### Lite mode (no audio)
|
|---|
| 22 |
|
|---|
| 23 | Set `KLONKT_AUDIO=off` in `.env` to disable the entire audio/music feature.
|
|---|
| 24 | Klonkt then runs as a lightweight **blog/photo/EPK/links site without ffmpeg** —
|
|---|
| 25 | ideal for minimal hosting. Hub, Circles and external embeds
|
|---|
| 26 | (YouTube/SoundCloud/Spotify) keep working.
|
|---|
| 27 |
|
|---|
| 28 | ## Self-hosting
|
|---|
| 29 |
|
|---|
| 30 | Klonkt is a **Node app** — run it on a **VPS, in Docker, or on a Node hosting
|
|---|
| 31 | platform (PaaS)**. **Not** on classic shared PHP hosting. The database (SQLite)
|
|---|
| 32 | creates itself on first start.
|
|---|
| 33 |
|
|---|
| 34 | ### Option A — One-command VPS installer (recommended)
|
|---|
| 35 |
|
|---|
| 36 | The simplest way on a fresh Debian/Ubuntu VPS. One command installs Node 20,
|
|---|
| 37 | Caddy (automatic HTTPS) and a systemd service, and is coexistence-safe (won't
|
|---|
| 38 | touch an existing Node/web server):
|
|---|
| 39 |
|
|---|
| 40 | ```bash
|
|---|
| 41 | curl -fsSL https://klonkt.com/install.sh | sudo bash -s -- --domain yourdomain.com
|
|---|
| 42 | ```
|
|---|
| 43 |
|
|---|
| 44 | Then open your domain and finish setup in the browser. Update later with `klonkt-update`.
|
|---|
| 45 |
|
|---|
| 46 | ### Option B — Docker
|
|---|
| 47 |
|
|---|
| 48 | Node, ffmpeg and cwebp are inside the image; you only need Docker.
|
|---|
| 49 |
|
|---|
| 50 | ```bash
|
|---|
| 51 | git clone https://github.com/roboburr/klonkt.git && cd klonkt
|
|---|
| 52 | cp .env.example .env # set SESSION_SECRET + PUBLIC_BASE_URL
|
|---|
| 53 | docker compose up -d
|
|---|
| 54 | ```
|
|---|
| 55 |
|
|---|
| 56 | Data (database + media) stays in the `klonkt-data` volume, even across updates.
|
|---|
| 57 | Updating: `git pull && docker compose up -d --build`.
|
|---|
| 58 |
|
|---|
| 59 | ### Option C — bare Node (20+)
|
|---|
| 60 |
|
|---|
| 61 | ```bash
|
|---|
| 62 | git clone https://github.com/roboburr/klonkt.git && cd klonkt
|
|---|
| 63 | npm ci
|
|---|
| 64 | cp .env.example .env # set SESSION_SECRET + PUBLIC_BASE_URL
|
|---|
| 65 | npm start # the database is created on first start
|
|---|
| 66 | ```
|
|---|
| 67 |
|
|---|
| 68 | For production, put it behind a process manager (pm2/systemd) and a
|
|---|
| 69 | reverse proxy. `cwebp` is optional (`apt install webp`) for WebP images.
|
|---|
| 70 |
|
|---|
| 71 | ### HTTPS (Docker / bare Node)
|
|---|
| 72 |
|
|---|
| 73 | Put a reverse proxy in front of the app. With **Caddy** (automatic Let's Encrypt):
|
|---|
| 74 |
|
|---|
| 75 | ```caddy
|
|---|
| 76 | yourdomain.com {
|
|---|
| 77 | reverse_proxy localhost:3000
|
|---|
| 78 | encode gzip zstd
|
|---|
| 79 | }
|
|---|
| 80 | ```
|
|---|
| 81 |
|
|---|
| 82 | (The VPS installer sets up Caddy + HTTPS for you already.)
|
|---|
| 83 |
|
|---|
| 84 | ### First run
|
|---|
| 85 |
|
|---|
| 86 | Open your site → you get the **setup wizard**: pick your language, name your site
|
|---|
| 87 | and create your admin. The **first user automatically becomes the administrator**;
|
|---|
| 88 | registration then closes. Lost your password?
|
|---|
| 89 | `npm run reset-admin` (Docker: `docker compose exec klonkt npm run reset-admin`).
|
|---|
| 90 |
|
|---|
| 91 | ## Configuration (`.env`)
|
|---|
| 92 |
|
|---|
| 93 | | Variable | Required | What |
|
|---|
| 94 | |---|---|---|
|
|---|
| 95 | | `SESSION_SECRET` | ✅ | Random string of ≥32 characters |
|
|---|
| 96 | | `PUBLIC_BASE_URL` | ✅ | Canonical URL (e.g. `https://yourdomain.com`) |
|
|---|
| 97 | | `GOOGLE_CLIENT_ID` / `_SECRET` / `_REDIRECT_URI` | — | Google login for listeners (your own OAuth client; never grants admin) |
|
|---|
| 98 | | `SMTP_HOST` / `_PORT` / `_USER` / `_PASS` / `_FROM` | — | Email for password reset + newsletter |
|
|---|
| 99 | | `KLONKT_DEFAULT_LANG` | — | Default language for visitors (`en`/`nl`/`de`) |
|
|---|
| 100 | | `KLONKT_AUDIO` | — | `off` = lite mode (no audio/ffmpeg) |
|
|---|
| 101 |
|
|---|
| 102 | ## Stack
|
|---|
| 103 |
|
|---|
| 104 | - **Runtime:** Node 20+
|
|---|
| 105 | - **Web:** Express + Helmet + express-session
|
|---|
| 106 | - **DB:** better-sqlite3 (WAL), self-migrating on boot
|
|---|
| 107 | - **Templates:** EJS (server-rendered) + **htmx 1.9** (vendored, no build step)
|
|---|
| 108 | - **Audio:** ffmpeg-static (bundled)
|
|---|
| 109 | - **Circles:** Ed25519-signed pull (libsodium via Node crypto)
|
|---|
| 110 | - **Fonts:** self-hosted variable woff2 (Fraunces / Plus Jakarta Sans)
|
|---|
| 111 |
|
|---|
| 112 | ## Project structure
|
|---|
| 113 |
|
|---|
| 114 | ```
|
|---|
| 115 | src/
|
|---|
| 116 | ├── server.js # Express bootstrap + route mounting
|
|---|
| 117 | ├── config/ # database, mailer, google, feature flags
|
|---|
| 118 | ├── db/migrations/ # SQLite schema (001-init.sql)
|
|---|
| 119 | ├── middleware/ # site resolving, auth, render (htmx-aware)
|
|---|
| 120 | ├── routes/ # per-resource Express routers (posts, auth, admin-*, circle, …)
|
|---|
| 121 | ├── services/ # domain logic (federation, stats, mailer, permissions, …)
|
|---|
| 122 | ├── views/ # shell.ejs + partials/ + pages/ (EJS)
|
|---|
| 123 | └── assets/ # css/ (palette tokens + components), js/ (htmx, player), fonts/
|
|---|
| 124 | ```
|
|---|
| 125 |
|
|---|
| 126 | ## License
|
|---|
| 127 |
|
|---|
| 128 | **AGPL-3.0-or-later** — see [LICENSE](LICENSE). Klonkt is free software: you may
|
|---|
| 129 | use, study, modify and distribute it. The AGPL does require that a modified
|
|---|
| 130 | version you offer as a network service makes its source code available to the
|
|---|
| 131 | users of that service. Made by robo.burr (Robin Genis) ·
|
|---|
| 132 | <https://klonkt.com>
|
|---|