This is a quickstart guide for those that wish to run a paid Nostr relay. There are now tens of relay implementations out there, but only one with plug-n-play support for Bitcoin Lightning Network payments — Nostream.

This is a technical walkthrough of how to get it all setup!

VM Setup

Choose your preferred VM provider - whether you use Linode, Digital Ocean, AWS, GCP, Azure, etc. For this guide I used the following setup in DigitalOcean:

  • Ubuntu 22.10, 8GB memory, 160GB NVME SSDs

We recommend at least 8GB of memory given the resource intensive nature of always-on websocket connections. Once your instance is up and running, SSH into that VM and follow the next steps.

# Update deps
sudo apt update

# Install nodejs, npm, nginx, certbot
sudo apt install nodejs npm nginx certbot python3-certbot-nginx

# Setup new `nostream` user (don't run nostream on root)
useradd -m -G docker nostream
# If the group `docker` doesn't exist run groupadd docker

# Set new nostream user password
passwd nostream

# Set bash shell for nostream user
chsh -s /bin/bash nostream

Setup Docker + Install

Commands below will install Docker in your VM.

# Create the keyring folder
sudo mkdir -p /etc/apt/keyrings

# Fetch and add it to folder
curl -fsSL | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Setup proper folder permissions
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Setup `apt` Docker repository (this is a one-liner)
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker
sudo apt update && sudo apt-get install docker-ce docker-ce-cli docker-compose-plugin

# Check installation is successful by checking verions
docker --version


Use the commands below to setup NGINX reverse proxy.

# Delete the default nginx settings file
rm -rf /etc/nginx/sites-available/default

# Paste in new settings file contents (see heading NGINX Settings below)
sudo nano /etc/nginx/sites-available/default

# Restart nginx
sudo service nginx restart

# Map DNS A record to IP of VM machine (see DNS Settings below)

# Request SSL cert from letsencrypt/certbot
sudo certbot --nginx -d

NGINX Settings

Use the contents below as the contents of the default NGINX settings file. Do remember to change the to your domain.

server {
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

DNS Settings

To map your VM’s IP address to your you need to have an A record like below in your domain DNS settings.

DNS Settings for Nostr Relay

DNS Settings for Nostr Relay

You may need to setup a static/reserved IP address in order to map the A record to the

ZBD Setup

Now that our VM is setup, let’s get our Nostr relay hooked up to ZBD. First you’re going to need a ZBD Dev Dashboard account.

Follow our in-depth guide on how to setup a ZBD Dev Dashboard account for more details.

Once you’re all set with your ZBD account, let’s create a project and title it something like Nostr Relay.

Create Project on ZBD Dev Dashboard

Create Project on ZBD Dev Dashboard

Once your project is created, you will be taken to the PROJECT DETAILS view. Each project in the dashboard has a fully-programmable Bitcoin Lightning wallet, and each wallet can be managed using the API Key provided in the API tab, as shown below.

Copy this API Key, you’re going to need it when setting up Nostream.

You will need a Production API Key for this integration. Sandbox API Keys are not supported yet for Nostr Relays. To get a Production API Key, you need to click LIVE on your Project dashboard.
Project Details - API

Project Details - API

Bonus: you are also encouraged to place your VM’s IP addresses in the whitelisting field to ensure API calls to ZBD using your API Key are only ever coming from the provided IP addresses.

Now that we’ve gotten the ZBD API Key, let’s store it in the configuration file for Nostream and set it live!

Nostream Setup

Now that your VM is all setup, and you’ve got your ZBD API Key, let’s install and configure Nostream to run a paid relay powered by ZBD.

# Change to nostream user
su - nostream

# Clone `nostream` repo
git clone

# Open a TMUX session
# (to be able to detach and maintain process running)

# Start the relay

# You want to start the relay once such that all Docker images are downloaded/built, and the default settings.yaml file is automatically copied over.

# Stop the relay (you will see the NOSTREAM logo once it's running)
Ctrl + C (you can use ./scripts/stop as well)

# Edit the settings file to your liking
# (see Settings.yaml Configuration below)

# Add local.env file to root
touch local.env

# Edit local.env file and add ZEBEDEE_API_KEY and SECRET
# SECRET is a 128bit random hash
nano local.env

ZEBEDEE_API_KEY="your API key goes here"
SECRET="your SECRET goes here"

# You may need to add a `env_file` property to docker-compose.yml
  - local.env

# Restart Nostream

# To detach from the TMUX session
Ctrl+B  +  D
# To re-attach to the TMUX session
tmux a

Settings.yaml Configuration

Go ahead and edit the contents of your Nostream settings file. The file can be found at .nostr/settings.yaml

settings.yaml Configuration

settings.yaml Configuration

At first, make sure to change the info properties so they match your taste. This information is public and is provided to any client app that connects to your relay.

Then scroll down to payments properties and enable the ZBD processor and select the admission fee cost you’d like to charge. You can also add any pubkeys to a whitelist if you wish to bypass the charge.

settings.yaml Configuration

settings.yaml Configuration

Under paymentsProcessors make sure to change to your actual Nostr relay domain.

settings.yaml Configuration

settings.yaml Configuration

Change limits.event.pubkey.minBalance to the amount you are charging for admission to your relay. (this should not be 0)

settings.yaml Configuration

settings.yaml Configuration

Your paid relay configuration is now complete! Go back up to continue with the commands and add your ZEBEDEE_API_KEY to local.env file.

Start Relay

Once you restart the relay, you should see a console that looks a little bit like this.



The special part is Payments Provider: zebedee and Pay-to-relay = enabled. You’re all set, let’s test the relay!

Relay Connectivity

In order to check that the relay is setup correctly, head on over to WebSocketKing and test the connection to your

WebSocket King

WebSocket King

If you’re able to connect to your relay, then it is time to test that the paid access functionality is working. To go through that flow head on over to and follow the admission payment flows.

Nostream Relay Payment Screen

Nostream Relay Payment Screen

For more details on this flow, check out the How It All Works section on the The Rise of Paid Nostr Relays post by our CTO Andre Neves.