High Availability Vault for Events on Nostr
Source repository ↗Log in to deploy this app.
Log inservices: haven: image: holgerhatgarkeinenode/haven-docker:v1.2.2@sha256:df1826b7124150510a174d64385a1137ab58610310a67d1c8cff432f16302835 # The image sets `USER nonroot` (a name), which the kubelet cannot verify # under runAsNonRoot. `nonroot` is uid 1000 in this image (Alpine # `adduser -D nonroot`), and 1000 also becomes the fsGroup so the db and # blossom volumes are writable. user: "1000" resources: { cpu: 500m, memory: 512Mi } ports: - { name: ws, container: 3355, protocol: http, expose: ingress } env: OWNER_NPUB: "${owner_npub}" RELAY_URL: "${HOSTNAME}" RELAY_PORT: "3355" RELAY_BIND_ADDRESS: "0.0.0.0" DB_ENGINE: "badger" BLOSSOM_PATH: "blossom/" # Every var below down to IMPORT_START_DATE is read with HAVEN's `getEnv`, # which is `log.Fatalf` on unset — one at a time, so a missing one looks # like an endless queue of missing ones rather than a single fault. PRIVATE_RELAY_NAME: "${private_relay_name}" PRIVATE_RELAY_NPUB: "${owner_npub}" PRIVATE_RELAY_DESCRIPTION: "${private_relay_description}" PRIVATE_RELAY_ICON: "${private_relay_icon}" CHAT_RELAY_NAME: "${chat_relay_name}" CHAT_RELAY_NPUB: "${owner_npub}" CHAT_RELAY_DESCRIPTION: "${chat_relay_description}" CHAT_RELAY_ICON: "${chat_relay_icon}" OUTBOX_RELAY_NAME: "${outbox_relay_name}" OUTBOX_RELAY_NPUB: "${owner_npub}" OUTBOX_RELAY_DESCRIPTION: "${outbox_relay_description}" OUTBOX_RELAY_ICON: "${outbox_relay_icon}" INBOX_RELAY_NAME: "${inbox_relay_name}" INBOX_RELAY_NPUB: "${owner_npub}" INBOX_RELAY_DESCRIPTION: "${inbox_relay_description}" INBOX_RELAY_ICON: "${inbox_relay_icon}" INBOX_PULL_INTERVAL_SECONDS: "${inbox_pull_interval_seconds}" IMPORT_START_DATE: "${import_start_date}" IMPORT_SEED_RELAYS_FILE: "relays_import.json" BLASTR_RELAYS_FILE: "relays_blastr.json" BLASTR_TIMEOUT_SECONDS: "${blastr_timeout_seconds}" WHITELISTED_NPUBS_FILE: "whitelisted_npubs.json" BLACKLISTED_NPUBS_FILE: "blacklisted_npubs.json" WOT_DEPTH: "${wot_depth}" WOT_MINIMUM_FOLLOWERS: "${wot_minimum_followers}" WOT_REFRESH_INTERVAL: "${wot_refresh_interval}" HAVEN_LOG_LEVEL: "${log_level}" BACKUP_PROVIDER: "none" env_from: extra_env files: - path: /app/relays_import.json content: "${import_relays}" - path: /app/relays_blastr.json content: "${blastr_relays}" - path: /app/whitelisted_npubs.json content: "${whitelisted_npubs}" - path: /app/blacklisted_npubs.json content: "${blacklisted_npubs}" volumes: - { name: db, path: /app/db, size: 5Gi, label: events } - { name: blossom, path: /app/blossom, size: 5Gi, label: media } backup: { volume: db, quiesce: true, artifact: haven-db } config: # HAVEN panics in nPubToPubkey on anything that is not an npub, so a mistyped # character is a paid-for deployment that crashloops. The pattern # is bech32: `npub1` + 58 characters from the bech32 alphabet (no 1/b/i/o). - { name: owner_npub, label: "Owner npub", type: string, required: true, pattern: "npub1[02-9ac-hj-np-z]{58}" } - { name: private_relay_name, label: "Relay name", type: string, default: "My private relay" } - { name: private_relay_description, label: "Relay description", type: string, default: "A HAVEN relay" } - { name: private_relay_icon, label: "Private relay icon URL", type: string, default: "", pattern: '(https?://\S+)?', group: "Relay info" } - { name: chat_relay_name, label: "Chat relay name", type: string, default: "Chat relay", group: "Relay info" } - { name: chat_relay_description, label: "Chat relay description", type: string, default: "Private chats", group: "Relay info" } - { name: chat_relay_icon, label: "Chat relay icon URL", type: string, default: "", pattern: '(https?://\S+)?', group: "Relay info" } - { name: outbox_relay_name, label: "Outbox relay name", type: string, default: "Outbox relay", group: "Relay info" } - { name: outbox_relay_description, label: "Outbox relay description", type: string, default: "Public messages and media", group: "Relay info" } - { name: outbox_relay_icon, label: "Outbox relay icon URL", type: string, default: "", pattern: '(https?://\S+)?', group: "Relay info" } - { name: inbox_relay_name, label: "Inbox relay name", type: string, default: "Inbox relay", group: "Relay info" } - { name: inbox_relay_description, label: "Inbox relay description", type: string, default: "Interactions", group: "Relay info" } - { name: inbox_relay_icon, label: "Inbox relay icon URL", type: string, default: "", pattern: '(https?://\S+)?', group: "Relay info" } - { name: inbox_pull_interval_seconds, label: "Inbox pull interval (seconds)", type: int, default: "3600", pattern: "[1-9][0-9]*", group: "Import and broadcast" } - { name: import_start_date, label: "Import notes since (YYYY-MM-DD)", type: string, default: "2023-01-01", pattern: "[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])", group: "Import and broadcast" } - { name: import_relays, label: "Relays to import from (JSON list)", type: string, default: '["wss://relay.damus.io", "wss://nos.lol", "wss://relay.primal.net"]', pattern: '\[\s*("(wss?://)?[^"\s\\]+"(\s*,\s*"(wss?://)?[^"\s\\]+")*)?\s*\]', group: "Import and broadcast" } - { name: blastr_relays, label: "Relays to broadcast to (JSON list)", type: string, default: '["wss://relay.damus.io", "wss://nos.lol", "wss://relay.primal.net"]', pattern: '\[\s*("(wss?://)?[^"\s\\]+"(\s*,\s*"(wss?://)?[^"\s\\]+")*)?\s*\]', group: "Import and broadcast" } - { name: blastr_timeout_seconds, label: "Broadcast timeout (seconds)", type: int, default: "5", pattern: "[1-9][0-9]*", group: "Import and broadcast" } - { name: whitelisted_npubs, label: "Extra npubs allowed to write (JSON list)", type: string, default: "[]", pattern: '\[\s*("npub1[02-9ac-hj-np-z]{58}"(\s*,\s*"npub1[02-9ac-hj-np-z]{58}")*)?\s*\]', group: "Access" } - { name: blacklisted_npubs, label: "Blocked npubs (JSON list)", type: string, default: "[]", pattern: '\[\s*("npub1[02-9ac-hj-np-z]{58}"(\s*,\s*"npub1[02-9ac-hj-np-z]{58}")*)?\s*\]', group: "Access" } - { name: wot_depth, label: "Web of trust depth", type: int, default: "3", pattern: "[0-9]+", group: "Access" } - { name: wot_minimum_followers, label: "Web of trust minimum followers", type: int, default: "0", pattern: "[0-9]+", group: "Access" } - { name: wot_refresh_interval, label: "Web of trust refresh interval (e.g. 24h)", type: string, default: "24h", pattern: "([0-9]+(h|m|s))+", group: "Access" } - { name: log_level, label: "Log level", type: string, default: "INFO", pattern: "DEBUG|INFO|WARNING|ERROR", group: "Advanced" } - { name: extra_env, label: "Advanced: extra environment variables (KEY=value per line)", type: file, default: "", group: "Advanced" }