Simple configuration tool to set up a HAVEN Nostr relay with Docker or Podman with just a few clicks.
Quick Start: Install on Umbrel | Install on StartOS | Using Docker | Using Podman
Haven (High Availability Vault for Events on Nostr) is designed for storing and backing up sensitive notes like eCash, private chats, and drafts.
Haven operates as four specialized relays in one application:
- Private Relay - Restricted to the owner for drafts and sensitive content
- Chat Relay - For direct messages with web-of-trust filtering
- Inbox Relay - Aggregates notes where the owner is mentioned
- Outbox Relay - Publicly accessible storage for owner's posts
- Blossom Media Server - Hosts images and videos for sharing
- Simple & Full Configuration Modes - Choose quick setup or advanced customization
- Web-based configuration interface (no CLI needed)
- Direct .env file editing for advanced users
- Optional relay configuration for:
- Blastr relays: Publish your outbox notes to additional relays
- Import relays: Import your historical notes and tagged content
- One-click note import from configured relays
- One-click restart functionality
- Real-time status monitoring
- BadgerDB or LMDB database support
- Optional S3-compatible cloud backups
- Docker and Podman support
- Open your Umbrel dashboard
- Navigate to the App Store
- Search for "Haven Kit"
- Click Install
Prerequisites: umbrelOS 1.0 or later
- Open your Umbrel dashboard
- Navigate to the App Store
- Click the three-dot menu (⋮) in the top right corner
- Select "Community App Stores"
- Paste this repository URL:
https://github.com/Letdown2491/haven-kit-umbrel - Click "Add"
- Return to the App Store
- Find "Haven Kit" in your community store section
- Click Install
- Wait for the installation to complete
Note: Community app stores are not verified by Umbrel. This store is maintained by the Haven Kit community.
HAVEN is also available as a native StartOS package, maintained in the sibling repository haven-kit-startos. Unlike the Docker/Podman and Umbrel versions, it does not use the web configuration UI — the relay is configured entirely through native StartOS actions.
Prerequisites: StartOS 0.4.x
- Download the
.s9pkfor your server's architecture (haven_x86_64.s9pkorhaven_aarch64.s9pk) from the latest release - In your StartOS dashboard, open System → Sideload a Service
- Upload the
.s9pkand install - Run the Setup action to set your owner npub and relay URL
See the haven-kit-startos README for build-from-source instructions and details on how the package works.
After installation, access the Haven configuration UI through your Umbrel dashboard.
Configure the following settings through the web interface:
OWNER_NPUB- Your Nostr public key (npub format)RELAY_URL- Public hostname for your relay, without a scheme: userelay.your-domain.com, notwss://relay.your-domain.com. Haven prependswss:///https://itself — including a scheme here produces broken Blossom media URLs (uploads work, downloads fail).
DB_ENGINE- Choose betweenbadger(default) orlmdbLMDB_MAPSIZE- Maximum database size in bytes (default: 273000000000 / 273GB)
BACKUP_PROVIDER- Set tos3for cloud backups ornoneto disableBACKUP_INTERVAL_HOURS- How often to backup (default: 24)
S3_ACCESS_KEY_ID- Your S3-compatible storage access keyS3_SECRET_KEY- Your S3-compatible storage secret keyS3_ENDPOINT- Storage provider endpoint URLS3_REGION- Geographic region for your bucketS3_BUCKET_NAME- Name of your storage bucket
BLOSSOM_PATH- Directory for media files (default: /haven/blossom)
Add relay URLs where your outbox posts will be automatically broadcasted. This helps distribute your content across the Nostr network.
Example:
[
"wss://relay.primal.net",
"wss://nos.lol"
]Add relay URLs from which Haven should import your old notes and tagged content.
Example:
[
"wss://relay.primal.net",
"wss://nostr.wine"
]After configuration, your relays will be available at:
- Outbox Relay:
ws://[server-ip]:3355 - Private Relay:
ws://[umbrel-ip]:3355/private - Chat Relay:
ws://[umbrel-ip]:3355/chat - Inbox Relay:
ws://[umbrel-ip]:3355/inbox - Blossom Media Server:
http://[umbrel-ip]:3355
This Umbrel app consists of two services:
- haven_relay - The Haven relay server (port 3355)
- config_ui - Web-based configuration interface (port 8080)
haven-kit/
├── docker-compose.yml # Orchestrates the relay and config UI
├── docker-compose.tor.yml # Optional Tor hidden service overlay
├── umbrel-app.yml # Umbrel app manifest
├── exports.sh # Environment variable exports
├── setup-env.sh # Detects Docker/Podman, creates .env + dirs
├── CHANGELOG.md # Release history
├── haven-relay/
│ ├── Dockerfile # Builds Haven from source (pinned version)
│ └── entrypoint.sh # Syncs config, normalizes RELAY_URL, config gate
├── haven-tor/
│ ├── Dockerfile # Tor sidecar for the optional overlay
│ ├── torrc # Hidden service configuration
│ └── entrypoint.sh # Fixes volume permissions, copies hostname
├── config-ui/
│ ├── Dockerfile # Flask web UI container
│ ├── app.py # Configuration backend
│ ├── requirements.txt # Python dependencies
│ ├── templates/
│ │ └── index.html # Web interface
│ └── static/
│ ├── style.css # Styling
│ └── script.js # Client-side logic
└── data/ # Persistent data (created at runtime, gitignored)
├── config/ # Configuration files
├── blossom/ # Media storage
├── db/ # Database files
├── templates/ # Custom templates
└── tor/ # Onion service keys (optional Tor overlay)
All Haven data is stored in volumes managed by Umbrel:
- Configuration files:
${APP_DATA_DIR}/config/ - Database:
${APP_DATA_DIR}/db/ - Media files:
${APP_DATA_DIR}/blossom/ - Templates:
${APP_DATA_DIR}/templates/
Your data persists across container restarts and app updates.
Note: This section is for local development and testing using Docker or Podman on your computer. This is NOT for installing on Umbrel. For Umbrel installation, see the Installation on Umbrel section above.
The project supports both Docker and Podman. The configuration UI automatically detects which container runtime you're using.
Use the provided setup script to automatically configure your environment:
# Run the setup script
./setup-env.sh
# The script will:
# - Detect Docker or Podman
# - Set up the correct socket path
# - Create necessary directories
# - Generate .env file
# Then start the services
docker-compose up -d # for Docker
# OR
podman-compose up -d # for Podman# Build both services
docker-compose build
# Start the services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the services
docker-compose down# Set the socket path environment variable
export DOCKER_SOCK=/run/user/$UID/podman/podman.sock
# Or for rootful Podman:
# export DOCKER_SOCK=/run/podman/podman.sock
# Build both services
podman-compose build
# Start the services
podman-compose up -d
# View logs
podman-compose logs -f
# Stop the services
podman-compose downNote: The config UI will automatically detect whether you're using Docker or Podman and use the appropriate commands for container management (restart, status checks, etc.).
The Haven version is pinned by the HAVEN_VERSION argument in haven-relay/Dockerfile (currently a commit just after v1.2.2 that includes the .onion relay URL fix). To build a different upstream version/tag, either set the variable when building:
HAVEN_VERSION=v1.2.1 docker-compose build haven_relay(or add HAVEN_VERSION=v1.2.1 to the root .env file), or change the pinned default in haven-relay/Dockerfile:
ARG HAVEN_VERSION=v1.2.2 # Change to desired version/tag from https://github.com/barrydeen/haven/tagsTor Hidden Service (Optional)
On Umbrel, Tor is automatic — the relay's .onion address simply appears in the configuration UI. This section is for local/VPS installs.
To publish your relay (and Blossom media server) as a Tor hidden service, stack the Tor overlay on top of the base compose file:
mkdir -p data/tor # Podman does not auto-create bind-mount sources
docker compose -f docker-compose.yml -f docker-compose.tor.yml up -d
# OR, with Podman:
podman-compose -f docker-compose.yml -f docker-compose.tor.yml up -dTroubleshooting: if the tor network fails to create with
subnet 172.31.78.0/29 is already used on the host, a leftover network from a previous attempt (possibly with the other container engine) is holding the subnet — remove it withdocker network rm haven-kit_tor_netorpodman network rm haven-kit_tor_net.
Use the same container engine your
.envwas set up for.setup-env.shwritesDOCKER_SOCKandCONTAINER_RUNTIMEinto.env; if you bring the stack up with the other engine, the configuration UI ends up controlling the wrong daemon — status shows "Unknown" and restart fails with "no container ... found". If you have both engines installed,CONTAINER_RUNTIME=docker ./setup-env.shforces the choice.
Once Tor starts, the relay's .onion address appears in the configuration UI's Tor section (and in data/tor/hostname). Nostr clients can then reach your relay at ws://<address>.onion.
- The onion address is an identity: its keys live in
data/tor/. Back that directory up to keep the address; delete it to rotate to a new one. - Tor-primary relays: to make Tor your relay's main address (advertised in relay metadata and Blossom media URLs), set the Relay URL in the configuration UI to the
.onionhostname. - Use both files for every command (
down,logs,restart, ...), otherwise the tor container is left out — e.g. adownwith only the base file leaves tor running. To make the overlay the default, addCOMPOSE_FILE=docker-compose.yml:docker-compose.tor.ymlto your.env, after which plaindocker compose up -dincludes Tor. - Blastr and import traffic still uses the clearnet; outbound Tor requires proxy support in upstream Haven.
- If the
172.31.78.0/29subnet collides with an existing network on your host, change it indocker-compose.tor.ymlandhaven-tor/torrc(both files, same IP).
If you want a simple drop-in Nginx configuration for your containers to access the relay publicly, you can copy the Nginx configuration down below.
# /etc/nginx/sites-available/default
# 1) Plain HTTP: only to issue/renew certs & redirect to HTTPS
server {
listen 80;
listen [::]:80;
server_name YOUR_PUBLIC_URL_HERE;
# This will cap your Blossom upload size to 100MB so feel free to edit. Use 0 for no caps.
client_max_body_size 100m;
# ACME challenge path for Certbot (webroot method fallback)
location /.well-known/acme-challenge/ { root /var/www/html; }
# Redirect everything else to HTTPS
location / { return 301 https://$host$request_uri; }
}
# 2) HTTPS: reverse proxy to HAVEN Relay on localhost:3355
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name YOUR_PUBLIC_URL_HERE; # For example, relay.myhavenrelay.com. No need for http or https here.
# SSL Certificates using Let's Encrypt
ssl_certificate /etc/letsencrypt/live/YOUR_PUBLIC_URL_HERE/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_PUBLIC_URL_HERE/privkey.pem;
client_max_body_size 100m;
# (Optional but useful for long-lived WS/uploads)
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
location / {
proxy_pass http://127.0.0.1:3355; # This will prevent yoour relay from being accessed via the public IP address and only internally on your machine for added security.
# keep your relay headers exactly as recommended
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket upgrade
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
- Check the configuration UI for status
- Review logs:
docker-compose logs haven_relay - Ensure
.envfile has valid configuration - Check database size doesn't exceed available disk space
- Verify port 8080 is not in use
- Check logs:
docker-compose logs config_uiorpodman-compose logs config_ui - Ensure Docker/Podman socket is accessible
- For Podman users: Set
DOCKER_SOCKenvironment variable to your Podman socket path- Rootless Podman:
export DOCKER_SOCK=/run/user/$UID/podman/podman.sock - Rootful Podman:
export DOCKER_SOCK=/run/podman/podman.sock
- Rootless Podman:
- Verify port 3355 is exposed correctly
- Check firewall settings on your Umbrel
- Review Haven logs for authentication/configuration issues
This project uses GitHub Actions to automatically build and push Docker images when a new release is created.
To create a release:
- Check upstream Haven releases and bump the pinned
HAVEN_VERSIONdefault inhaven-relay/Dockerfileif a new version is available — the release workflow builds with this default - Update version numbers if needed (in
VERSION,umbrel-app.yml, etc.) - Commit your changes
- Create a new tag:
git tag v1.0.0 git push origin v1.0.0
- Create a GitHub release from the tag
- GitHub Actions will automatically:
- Build both
haven-relayandhaven-config-uiimages - Push to Docker Hub with tags
latestandv1.0.0 - Build for multiple platforms (amd64, arm64)
- Build both
Manual trigger: You can also manually trigger the workflow from the GitHub Actions tab and specify a tag.
Prerequisites: Set up these GitHub repository secrets:
DOCKER_USERNAME- Your Docker Hub usernameDOCKER_PASSWORD- Your Docker Hub password or access token
- HAVEN Kit: https://github.com/Letdown2491/haven-kit
- HAVEN Project: https://github.com/barrydeen/haven
- Umbrel Community: https://community.umbrel.com
- Issues: https://github.com/Letdown2491/haven-kit/issues
- HAVEN Kit is licensed under the MIT License. See LICENSE file for details.
- HAVEN Project is licensed under the MIT License by Bitvora.
- Haven Project: Created by Bitvora, now maintained at barrydeen/haven
- HAVEN Kit Configuration Tool: Created by the HAVEN Kit contributors

