Self-Hosting
This page covers the different ways to self-host Keyper and the runtime model that applies to each.
Runtime assumptions in app code
Section titled “Runtime assumptions in app code”- Supabase URL/key are supplied by the user at runtime and stored in local storage.
- Username context is also local-storage driven (
keyper-username). - Registration handoff uses local state (
keyper-show-registration) to route from lock screen into new-user creation. - Credential and category table access is filtered by
user_idin client queries.
Deployment options
Section titled “Deployment options”Docker (recommended for servers)
Section titled “Docker (recommended for servers)”The Docker image serves the compiled Vite/React SPA from nginx. No Node.js runtime is required in production.
Quick start with Docker Compose:
git clone https://github.com/pinkpixel-dev/keyper.gitcd keyper
# Start on http://localhost:8080docker compose up -d
# Use a different host portHOST_PORT=3030 docker compose up -d
# Rebuild after source changesdocker compose up -d --build
# Stopdocker compose down
# View logsdocker compose logs -fCheck container health:
curl http://localhost:8080/healthz# returns: okRun without Compose:
docker build -t keyper .docker run -d -p 8080:80 --name keyper --restart unless-stopped keyperNo environment variables or volumes are required. Configuration (Supabase credentials, provider selection, username context, optional SQLite path/name) is entered in-app. In browser-hosted usage, config is stored in browser localStorage and SQLite data persists in browser storage. In Electron, SQLite can also use a file on disk.
Multi-user onboarding is self-service in the app itself (lock screen Create New User or Dashboard Settings → User Management → Add New User). No admin account is required or available.
HTTPS in production
Section titled “HTTPS in production”For HTTPS, place a reverse proxy (Caddy, nginx, Traefik) in front of the container. Example Caddy snippet:
keyper.example.com { reverse_proxy keyper:80}The container itself does not terminate TLS.
npm / Node.js server
Section titled “npm / Node.js server”For Node.js environments, the CLI bin/keyper.js starts a Vite preview server on port 4173 (configurable via --port):
npm install -g @pinkpixel/keyperkeyper --port 4173Electron desktop app
Section titled “Electron desktop app”See Install and Run for the currently published Windows and Linux desktop download links, plus local build options for additional Electron targets.
Operational recommendations
Section titled “Operational recommendations”- Run Keyper over HTTPS in production.
- Keep Supabase project credentials and policies tightly controlled.
- Be explicit about SQLite storage mode in user-facing docs: browser/PWA uses browser-local persistence, while Electron can also use a disk-backed database file.
- Validate that the SQL setup script matches the current app release before onboarding users.
- For existing databases, apply release migrations (for example
migration-add-document-misc-types.sql) before enabling new credential features in production. - Periodically audit docs against implementation to avoid security misunderstandings.
- Row Level Security is enabled on all Supabase tables — do not disable it.