Nostr Series — Part 3: Setting Up A Relay

Michael Stewart
5 min readApr 22, 2024

--

Welcome to part 3 of the Nostr series! This installment of the series will be a quickstart guide to setting up a relay for communication. A relay is, simply put, a WebSocket server that follows the Nostr protocol. They are the backbone of the network, the core back-end providing the ability for real-time communication in a decentralized manner.

Relay Implementations

There are a number of different relay implementations available, each offering it’s own set of features and benefits. They should all work out-of-the-box with only a small amount of configuration changes. We are going to be using nostream, written in Typescript and packaged up into a Docker container. It is very easy to set up, open-source and production-ready.

Some other popular relay implementations are:

  • nostr-rs-relay — lightweight relay written in Rust
  • strfry — C++ implementation
  • saltivka — Ruby implementation with a user interface
  • LNBits Relay — launch a relay from your LBBits server with a single click

Infrastructure

You can set up a Nostr relay on any set of infrastructure, from your preferred cloud provider to your own personal laptop. However, an important factor in deciding where to set up your relay is centralization — for instance, if everyone running a relay sets it up on AWS, Amazon becomes a centralizing force and single point of failure within the network. Therefore, I would highly recommend self-hosting a relay on your own hardware, if you have that available.

Since this implementation runs inside a Docker container, we can spin it up from any operating system with Docker installed. For instructions on how to install for your chosen operating system, check out the Docker documentation. If you prefer to run the application outside of a Docker environment, the codebase includes scripts for that, too.

Considerations

The first question you might ask is should I run my own relay? The answer to that is going to depend on your motivation in using the Nostr network. Many public and private relays exist, so it is fine to just connect to these on your client without the additional overhead of setting up a relay yourself. However, if you want to ensure that your speech is uncensorable, there is no better way than running your own relay. This ensures that you preserve all data transmitted on the network forever, with no central entity having the ability to take that away. Moreover, the interoperable nature of Nostr means that this data can be used and replicated on any other relay, since they all follow the same underlying protocol.

Another important point to note is that due to Nostr’s decentralized mechanism for storing and retrieving data, slow clients are generally due to the relay or relays that are being used. If you are experiencing performance issues on a client, you may want to add or change the relays that are being used. If your own relay is proving to not be performant, you may want to look into resource allocation on your server infrastructure.

Instructions

  • Clone git repository
    git clone https://github.com/Cameri/nostream.git
  • Update configuration
    – Under the source, open the file ./nostr/settings.yml
    – Ensure that payments is disabled for now, you may want to set that up later but it is outside the scope of this guide
    – Update relay_url to be your relay address, for instance ws://localhost:8008 (WSS is not needed when running locally) or wss://relay.ghostcopywrite.com
    – Everything else should be able to be left as-is
  • Install all pre-requisites
    – Docker should have been set up from the previous section
    – Install nodejs, npm, nginx and certbot: sudo apt install nodejs npm nginx certbot python3-certbot-nginx
  • Set up nginx
    – Delete the default nginx file: rm -rf /etc/nginx/sites-available/default
    – Create a new nginx configuration file at the same location (update references to the server name where appropriate), and then restart nginx with: sudo service nginx restart:
server{
server_name relay.ghostcopywrite.com;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8008;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
  • Set up certificate
    sudo certbot --nginx -d [relay URL, eg. relay.ghostcopywrite.com]
  • Add a DNS A record referencing the IP Address of the machine to your domain or subdomain of choice, for instance relay.ghostcopywrite.com, so that our WebSocket endpoint will be wss://relay.ghostcopywrite.com
  • Run application
    Option 1) If you want to run the application locally, outside of a docker container: .scripts/start_local
    — The relay will then be accessible via ws://localhost:8008
    Option 2) If you want to run the Docker container, first ensure Docker is running and then: npm run docker:compose:start
    — You may wish to run this inside a new terminal session, using a terminal multiplexer like tmux
  • You should then be greeted with the following to indicate that the relay server has started correctly
nostream welcome message

Testing

NostrDebug is a useful tool to verify that everything is working correctly.

Navigate to Relays and connect to the relay URL you just set up:

connect to our new relay

Then, we can check queries as well as publishing new messages:

publishing a new message to our relay
retrieving the previously published message

Our Nostr relay is all set up and working! We can now start developing clients that connect to this relay, publishing and subscribing to events.

Like this post and want to support the series? Tip me some sats on lightning at mikkthemagnificent@getalby.com:

--

--