lwis docs

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.

  1. Run ntfy with attachments enabled (an attachment-cache-dir), behind HTTPS.

  2. Pair your devices against it:

    lwis pair --label "$(hostname)" --signal https://ntfy.example.org --blobs ntfy
    

    Add --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, set LWIS_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:

PartWhat it doesIn the repository
lwis-webwebsite, /capture/ web app, drop API (presigned uploads, tickets, identities, cards), doorbell relaycrates/lwis-web, a WebAssembly app run by the kasm runtime (infra/kasm/kapp.toml)
ntfysignal plane, with anonymous access limited to the lwis_* and up* topicsauth-default-access: deny-all, then ntfy access everyone 'lwis_*' rw and ntfy access everyone 'up*' rw; attachments off
Object storageencrypted blobs, with one-day lifecycle rules (captures c/1d/, share links s/) and CORS for the web appinfra/tofu/00-s3-users (the bucket user), infra/tofu/30-objectstore (OVHcloud S3; any S3 with presigned PUT works)
CaddyTLS, reverse proxy, per-IP request limits, a small cache for the website's pages and static filesinfra/host/Caddyfile, built with cache-handler and caddy-ratelimit by infra/host/build-caddy.sh
DNS and certificatesrecords, a wildcard certificate, release keys in TXT recordsinfra/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.