Reference / Self-hosting
Self-hosting
lwis works with servers you run. There are two levels.
The simple way: your own ntfy
The only server lwis strictly needs between your devices and your machine is an ntfy server. With attachments enabled, it can carry the encrypted images too.
-
Run ntfy with attachments enabled (an
attachment-cache-dir), behind HTTPS. -
Pair your devices against it:
lwis pair --label "$(hostname)" --signal https://ntfy.example.org --blobs ntfyAdd
--pfx <prefix>if your ntfy only allows topics with a prefix, and--tok <token>if it requires an access token.
Everything stays end-to-end encrypted: your ntfy server sees the same metadata the hosted one would (see What the servers can see).
The pairing link still opens a page on lookwhatisee.xyz (the secret stays in the
#part, which never reaches it). To use your own host, setLWIS_PAIR_BASE=https://your-host/pair#in lwisd's environment.
The hosted ntfy (ntfy.lookwhatisee.xyz) has attachments turned off: with it, images go through the hosted drop API and object storage instead.
The full stack
The hosted service at lookwhatisee.xyz is built from these parts, all in the lwis repository:
| Part | What it does | In the repository |
|---|---|---|
| lwis-web | website, /capture/ web app, drop API (presigned uploads, tickets, identities, cards), doorbell relay | crates/lwis-web, a WebAssembly app run by the kasm runtime (infra/kasm/kapp.toml) |
| ntfy | signal plane, with anonymous access limited to the lwis_* and up* topics | auth-default-access: deny-all, then ntfy access everyone 'lwis_*' rw and ntfy access everyone 'up*' rw; attachments off |
| Object storage | encrypted blobs, with one-day lifecycle rules (captures c/1d/, share links s/) and CORS for the web app | infra/tofu/00-s3-users (the bucket user), infra/tofu/30-objectstore (OVHcloud S3; any S3 with presigned PUT works) |
| Caddy | TLS, reverse proxy, per-IP request limits, a small cache for the website's pages and static files | infra/host/Caddyfile, built with cache-handler and caddy-ratelimit by infra/host/build-caddy.sh |
| DNS and certificates | records, a wildcard certificate, release keys in TXT records | infra/tofu/10-dns, 20-acme, 40-release-dns |
Point lwis at your own drop API with --blobs https://your-host when pairing. The Android app and the web app follow the planes named in each pairing.
Running the full stack means operating kasm, which is more work than ntfy alone; most people self-hosting should start with the simple way above.