New
Apps 1,895Makers 1,890This week 1,690
Promote your app−30%
Klonkt screenshot 1
0views in
the last 30 days

Klonkt

Your own, self-hosted corner of the web — for your story, your visuals and your sound.

Built with Claude Code

by roboburr · Unclaimed · from NLNetherlands · added Oct 29, 2026
no ratings0 comments

Your own, self-hosted corner of the web — for your story, your visuals and your sound. Built on Node + SQLite + htmx: lightweight, server-rendered, and yours. No algorithm, no ads, no platform sitting in between.

What it does

  • Solo — one personal site, entirely yours, on your own domain.
  • Blog & photos — posts with cover, tags, timeline or grid.
  • Host your own music — built-in audio player with tracks, albums and playlists.
  • Fediverse-native — your posts federate over ActivityPub: people follow, like, boost and reply from Mastodon (or another Klonkt). You can follow accounts, see a home timeline, and reply/like back — Klonkt is a full fediverse client.
  • Grow: newsletter, download-for-email, EPK/press kit, link-in-bio, show calendar, and cookie-free statistics.
  • Paid posts — put a post behind your own Patreon. Supporters unlock it with a passkey: no account on your site, no cookie, and a patron's identity (name/email) is never stored — only a pseudonymous, expiring entitlement. You connect your Patreon once in the admin and pick a minimum amount per post.
  • Circles — a curated feed of the makers you choose: feature accounts (other Klonkt sites, Mastodon, PeerTube — any fediverse server) and their public posts appear in your Circle. Decentralized, no central platform — built on ActivityPub.
  • Push notifications — a browser/PWA notification for new followers, replies, mentions, likes, boosts and private messages, even with the site closed. Self-hosted Web Push (VAPID): payloads are encrypted end-to-end to your browser, and private messages never carry their text in the push.
  • Themes & languages — multiple palettes (light + dark), interface in EN/NL/DE.
  • Installable (PWA), privacy-first (self-hosted fonts, no tracking).

Lite mode (no audio)

Set KLONKT_AUDIO=off in .env to disable the entire audio/music feature. Klonkt then runs as a lightweight blog/photo/EPK/links site without ffmpeg — ideal for minimal hosting. Circles and external embeds (YouTube/SoundCloud/Spotify) keep working.

It's fully reversible: set KLONKT_AUDIO back to on (or remove the line) and restart — no reinstall. The flag only toggles the audio routes/UI; the database tables are never dropped, so any tracks you had are preserved.

Self-hosting

Klonkt is a Node app — run it on a VPS, in Docker, or on a Node hosting platform (PaaS). Not on classic shared PHP hosting. The database (SQLite) creates itself on first start.

Requires Node.js 20 or newer. The one-command VPS installer and the Docker image include it; only a manual install needs you to provide it.

Option A — One-command VPS installer (recommended)

Good if: you have (or just rented) a fresh, empty Debian/Ubuntu VPS and want the easiest path. This single line does everything — installs Node 20, sets up Caddy for automatic HTTPS, runs Klonkt as a background service that auto-restarts on reboot, and adds an update command. It's coexistence-safe (if the server already runs something it picks a free port and skips Caddy), but a clean VPS is simplest. Point your domain's DNS (A + AAAA records) at the server first, then run as root:

curl -fsSL https://klonkt.com/install.sh | sudo bash -s -- --domain yourdomain.com

Then open https://yourdomain.com and finish setup in the browser. Update anytime with klonkt-update.

Updates track the stable branch — it only advances to a version that's been verified, so klonkt-update never pulls work-in-progress. Want the bleeding edge instead? Install with --branch main (or set KLONKT_BRANCH=main).

Option B — Docker

Good if: you already use Docker, or want everything bundled in one isolated container. Node, ffmpeg and cwebp are inside the image — you only need Docker + Docker Compose.

git clone https://github.com/roboburr/klonkt.git
cd klonkt
cp .env.example .env          # works as-is; optionally set PUBLIC_BASE_URL to your domain
docker compose up -d

SESSION_SECRET is auto-generated on first start, so the defaults work as-is. Klonkt runs on port 3000 — put your own reverse proxy in front for HTTPS (see step 5 of Option C). Data (database + media) stays in the klonkt-data volume, even across updates. Update: git pull && docker compose up -d --build.

Option C — manual (Node 20+), step by step

Good if: you want full control, are adding Klonkt to a server you already manage, or just want to test it locally.

1. Get the code & install dependencies

git clone https://github.com/roboburr/klonkt.git
cd klonkt
npm ci

2. Create your config. SESSION_SECRET (the key that signs login cookies) is auto-generated on first start, so this works as-is. For production, set PUBLIC_BASE_URL to your site address (e.g. https://yourdomain.com) so email & login links are correct:

cp .env.example .env
nano .env          # optional: PUBLIC_BASE_URL, plus SMTP if you want it

3. Start it — the SQLite database is created automatically on first start:

npm start          # runs on http://localhost:3000

Just testing locally? Stop here and open http://localhost:3000.

4. Keep it running across crashes and reboots (easiest is pm2):

npm install -g pm2
pm2 start src/server.js --name klonkt
pm2 save && pm2 startup     # run the one command it prints, once

5. Add HTTPS with a reverse proxy in front. With Caddy (automatic certificates), put this in /etc/caddy/Caddyfile and reload Caddy:

yourdomain.com {
    reverse_proxy localhost:3000
}

By default the app binds to 127.0.0.1 (via HOST in .env), so only your reverse proxy can reach it — not the open internet. Local testing on the same machine (localhost:3000) still works. Only set HOST=0.0.0.0 if you need direct external access without a proxy (then open the port in your firewall and add HTTPS yourself).

(cwebp is optional — apt install webp — for WebP image conversion.)

HTTPS (Docker / bare Node)

Put a reverse proxy in front of the app. With Caddy (automatic Let's Encrypt):

yourdomain.com {
    reverse_proxy localhost:3000
    encode gzip zstd
}

(The VPS installer sets up Caddy + HTTPS for you already.)

First run

Open your site → you get the setup wizard: pick your language, name your site and create your admin. The first user automatically becomes the administrator; registration then closes. Lost your password? npm run reset-admin (Docker: docker compose exec klonkt npm run reset-admin).

Configuration (.env)

Variable Required What
SESSION_SECRET auto Signs login sessions. Leave empty to auto-generate (storage/.session-secret), or set a random ≥32-char string.
PUBLIC_BASE_URL ✅ Canonical URL (e.g. https://yourdomain.com)
PAID_SECRET auto Encrypts the stored Patreon secrets for paid posts. Leave empty to auto-generate on first use (storage/.paid-secret), or set your own ≥16-char string.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT auto Identify this server to browser push services (push notifications). Leave empty to auto-generate on first use (storage/.vapid).
SMTP_HOST / _PORT / _USER / _PASS / _FROM — Email for password reset + newsletter
KLONKT_DEFAULT_LANG — Default language for visitors (en/nl/de)
KLONKT_AUDIO — off = lite mode (no audio/ffmpeg)
KLONKT_PREMIUM_ENABLED — on (default) enables the Patreon-unlocked extras (incl. paid posts)
HSTS_STRICT — 1 = stricter HTTPS header (includeSubDomains + preload). Only set this if Klonkt owns the whole domain and all its subdomains are HTTPS — it forces every subdomain to HTTPS and can bake your domain into browsers near-permanently. Leave unset otherwise; the default is already safe.

Auto-generated secrets & backups

You never have to hand-edit the env for these: Klonkt generates them on first use and keeps them stable across restarts and updates.

  • SESSION_SECRET → storage/.session-secret (signs login sessions)
  • PAID_SECRET → storage/.paid-secret (encrypts the stored Patreon secrets for paid posts)
  • VAPID_* → storage/.vapid (identifies this server to browser push services; regenerating it would silently break every existing push subscription)

The paid-posts key lives outside the database on purpose: encrypting the Patreon secrets would be pointless if the key sat in the same file a database dump would leak. Set either variable in .env to override the generated one.

Back up the whole storage/ directory (database, media and these key files). Restoring the database without storage/.paid-secret leaves the stored Patreon secrets unreadable — you'd have to reconnect Patreon. Restoring without storage/.vapid breaks push subscriptions — every device would have to re-enable notifications.

Stack

  • Runtime: Node 20+
  • Web: Express + Helmet + express-session
  • DB: better-sqlite3 (WAL), self-migrating on boot
  • Templates: EJS (server-rendered) + htmx 1.9 (vendored, no build step)
  • Audio: ffmpeg-static (bundled)
  • Fediverse / Circles: ActivityPub (HTTP Signatures) — federates with Mastodon, PeerTube and other Klonkt sites. See FEDERATION.md for the supported activities and FEPs.
  • Fonts: self-hosted variable woff2 (Fraunces / Plus Jakarta Sans)

Project structure

src/
├── server.js          # Express bootstrap + route mounting
├── config/            # database, mailer, feature flags
├── db/migrations/     # SQLite schema (001-init.sql)
├── middleware/        # site resolving, auth, render (htmx-aware)
├── routes/            # per-resource Express routers (posts, auth, admin-*, circle, …)
├── services/          # domain logic (federation, stats, mailer, permissions, …)
├── views/             # shell.ejs + partials/ + pages/  (EJS)
└── assets/            # css/ (palette tokens + components), js/ (htmx, player), fonts/

License

AGPL-3.0-or-later — see LICENSE. Klonkt is free software: you may use, study, modify and distribute it. The AGPL does require that a modified version you offer as a network service makes its source code available to the users of that service. Made by robo.burr (Robin Genis) · https://klonkt.com

Acknowledgements

Klonkt stands on a lot of open-source work — Node.js, FFmpeg, SQLite, libwebp, resvg, htmx, EJS and more, plus the Fraunces, Plus Jakarta Sans and Literata fonts. See THIRD-PARTY-NOTICES.md for the full list and their licences. Thank you to everyone who made them.

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#self-hosted · #personal-site · #music