From 4122014ff7d72fcae0d238f8c5d5f477889d7927 Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Sat, 17 Feb 2024 16:07:32 +1300 Subject: [PATCH] README and doc updates --- README.md | 35 +++---------- contrib/README.md | 108 +++++++++++++++++++---------------------- docs/PERFORMANCE.md | 16 ++++++ docs/PERSONAL_RELAY.md | 30 ++++++++++++ 4 files changed, 104 insertions(+), 85 deletions(-) create mode 100644 docs/PERFORMANCE.md create mode 100644 docs/PERSONAL_RELAY.md diff --git a/README.md b/README.md index 81355d6..706c1de 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,17 @@ # Chorus -Chorus is a nostr relay in development +Chorus is a nostr relay. -Development is early and rapid. This is NOT ready to use by any stretch of the imagination. +It is pretty fast: [docs/PERFORMANCE.md](docs/PERFORMANCE.md). -## Plans +It can work as your personal relay: [docs/PERSONAL_RELAY.md](docs/PERSONAL_RELAY.md). -High performance due to: +It does not have any provisions for charging users. -- Rust language -- Asynchronous multithreading -- Memory mapped storage -- Event memory map is almost lock-free (limited to one writer at a time) -- Direct indexing: indices yield the memory offset of the event, not an ID that requires another lookup -- LMDB used for indexes -- In-place zero-copy event field access (does not require deserialization) -- Custom JSON parsing without memory allocation +## Deploying chorus -Simple to deploy due to: +Read [contrib/README.md](contrib/README.md) -- Being the webserver and the relay for standalone deployment -- TLS optional, to support both standalone and behind-proxy deployment -- Just a single configuration file -- systemd and nginx setups contributed +## Status -Flexible nostr usage: - -- Can use as personal relay, inbox, DM inbox, etc, with flexible rules around access - -## Not Planned (yet) - -Bitcoin/Lightning integration: - -- I don't plan to add this any time soon. -- You won't be able to charge for service. +Chorus isn't quite finished, but we hope to release in February 2024. diff --git a/contrib/README.md b/contrib/README.md index f9c57a0..8e94d99 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -10,70 +10,62 @@ configure your firewall/router for this. We leave this up to you. ## Deploying the files -As root, you'll want to create a `chorus` user. Here is an example for debian based systems: +You'll want to create a `chorus` user. Here is an example for debian based systems: -```sh -# useradd -r -d /opt/chorus -s /bin/bash chorus +```bash +sudo useradd -r -d /opt/chorus -s /bin/bash chorus ``` -As root, you'll want to make the following directories +You'll want to make the following directories -```sh -# mkdir -p /opt/chorus/{etc,src,var,sbin,lib} -# mkdir -p /opt/chorus/var/{chorus,www} -# mkdir -p /opt/chorus/lib/systemd/system -# chown -R chorus /opt/chorus +```bash +sudo mkdir -p /opt/chorus/{etc,src,var,sbin,lib} +sudo mkdir -p /opt/chorus/var/{chorus,www} +sudo mkdir -p /opt/chorus/lib/systemd/system +sudo chown -R chorus /opt/chorus ``` -Now you can clone the chorus source code onto the server. +Now we need to clone the chorus source code. We presume you will do this as yourself, but +we will put it under `/opt/chorus/src` -If you will be building as a different user (e.g. your personal login), you might want to change -the ownership of this directory to yourself. This is particularly useful if you already have rust -installed via rustup and don't want to install another rust system under the chorus user. - -We continue presuming you will be installing rust under the chorus user. - -```sh -# sudo -iu chorus -$ cd /opt/chorus/src -$ git clone https://github.com/mikedilger/chorus -$ cd chorus +```bash +sudo chown $(id -u) /opt/chorus/src +cd /opt/chorus/src +git clone https://github.com/mikedilger/chorus +cd chorus ``` -Now we install rust as the chorus user. Beware this uses a fair amount of space for rust package -downloads that is not shared with any other user on the system. +Check if you have `rustc` and `cargo` installed. If so, you can skip this part. -If you have `rustc` and `cargo` installed at the system level you can use those -instead and can skip this step. This step comes from (https://rustup.rs)[https://rustup.rs] +This step comes from [https://rustup.rs](https://rustup.rs) -```sh -$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` If you are coming back here after some time, you may wish to update rust instead: -```sh -$ rustup update +```bash +rustup update ``` Now let's continue by building chorus: -```sh -$ cd /opt/chorus/src/chorus -$ cargo build --release +```bash +cargo build --release ``` Ok now let's install that: -```sh -$ install --mode=0700 ./target/release/chorus /opt/chorus/sbin/chorus +```bash +sudo install --mode=0700 --owner=chorus ./target/release/chorus /opt/chorus/sbin/chorus ``` Now let's create our config file -```sh -$ cp /opt/chorus/src/chorus/contrib/chorus.ron /opt/chorus/etc/ +```bash +sudo -u chorus cp /opt/chorus/src/chorus/contrib/chorus.ron /opt/chorus/etc/ ``` Go ahead and edit that file to your liking. In particular: @@ -94,7 +86,7 @@ The second is to run chorus behind an nginx proxy. If you want chorus to respond on port 443, and you host other virtual servers on the machine, you'll need to run chorus behind an nginx proxy. -But you can run in on a different port (e.g. 444) too. Remember to open up your firewall +But you can run it on a different port (e.g. 444) too. Remember to open up your firewall for this if necessary. @@ -102,8 +94,8 @@ for this if necessary. Copy the systemd service file from the source code to the install location: -```sh -$ cp /opt/chorus/src/chorus/contrib/chorus-direct.service /opt/chorus/lib/systemd/system/chorus.service +```bash +sudo -u chorus cp /opt/chorus/src/chorus/contrib/chorus-direct.service /opt/chorus/lib/systemd/system/chorus.service ``` Edit this file to change the `letsencrypt` paths to include your actual domain (replace the @@ -117,58 +109,58 @@ root so it needs copies that are owned by chorus that it can access). Make the directory for certificate copies: -```sh -$ mkdir -p --mode=0700 /opt/chorus/etc/tls +```bash +sudo -u chorus mkdir -p --mode=0700 /opt/chorus/etc/tls ``` As root, enable the service and start the service: -```sh -# systemctl enable /opt/chorus/lib/systemd/system/chorus.service -# systemctl start chorus.service +```bash +sudo systemctl enable /opt/chorus/lib/systemd/system/chorus.service +sudo systemctl start chorus.service ``` ### Running behind nginx Copy the systemd service file from the source code to the install location: -```sh -$ cp /opt/chorus/src/chorus/contrib/chorus-proxied.service /opt/chorus/lib/systemd/system/chorus.service +```bash +sudo -u chorus cp /opt/chorus/src/chorus/contrib/chorus-proxied.service /opt/chorus/lib/systemd/system/chorus.service ``` Copy the nginx config file to the install location: -```sh -$ cp /opt/chorus/src/chorus/contrib/chorus.nginx.conf /opt/chorus/etc/chorus.nginx.conf +```bash +sudo -u chorus cp /opt/chorus/src/chorus/contrib/chorus.nginx.conf /opt/chorus/etc/chorus.nginx.conf ``` Change the port on the `proxy_pass` line if you are running chorus on a different port. As root, enable the service and start the service: -```sh -# systemctl enable /opt/chorus/lib/systemd/system/chorus.service -# systemctl start chorus.service +```bash +sudo systemctl enable /opt/chorus/lib/systemd/system/chorus.service +sudo systemctl start chorus.service ``` Link the nginx config file -```sh -# ln -s /opt/chorus/etc/chorus.nginx.conf /etc/nginx/sites-available/chorus.nginx.conf -# ln -s ../sites-available/chorus.nginx.conf /etc/nginx/sites-enabled/chorus.nginx.conf +```bash +sudo ln -s /opt/chorus/etc/chorus.nginx.conf /etc/nginx/sites-available/chorus.nginx.conf +sudo ln -s ../sites-available/chorus.nginx.conf /etc/nginx/sites-enabled/chorus.nginx.conf ``` Restart nginx -```sh -# systemctl restart nginx.service +```bash +sudo systemctl restart nginx.service ``` ## Monitoring the service You can watch the logs with a command like this -```sh -# journalctl -f -u chorus.service +```bash +sudo journalctl -f -u chorus.service ``` diff --git a/docs/PERFORMANCE.md b/docs/PERFORMANCE.md new file mode 100644 index 0000000..ed6c24a --- /dev/null +++ b/docs/PERFORMANCE.md @@ -0,0 +1,16 @@ +# Performance + +At the time of this writing, I don't know if chorus is fast or not. It has not been +profiled or optimized yet. It has only been designed for performance. + +Here are the design choices made in order to help achieve eventual high performance: + +- Rust language: low level language runs as fast as your hardware with no runtime and no overhead. +- Asynchronous multithreading: maximizes the utilization of each and every CPU core available. +- Memory mapped storage: Accessing persistent storage is usually just as fast as accessing main +memory (once swapped in). This is achieved via a custom memory map for events and LMDB for indices. +- The event memory map is append-only making it almost lock-free (limited to one writer at a time, but unlimited readers who can read while writes are happening) +- Direct indexing: indices yield the memory offset of the event, not an ID that requires yet another b-tree lookup to fetch the actual event data. +- Events and filters are custom binary structures with in-place zero-copy field access. +- Events and filters have custom JSON parsing that uses very little (usually no) memory allocation. + diff --git a/docs/PERSONAL_RELAY.md b/docs/PERSONAL_RELAY.md new file mode 100644 index 0000000..8b4f0e0 --- /dev/null +++ b/docs/PERSONAL_RELAY.md @@ -0,0 +1,30 @@ +# Personal Relay + +A personal relay is a relay that serves as an OUTBOX and an INBOX for a small set of +users, perhaps just yourself. + +It hosts your own events and makes them available to the public. + +It accepts events that tag your users, but doesn't allow the public to read them back. Only +your users (after being authenticated) can see them. + +One nice thing about a personal relay is that you are in control, and you have a record +of your events in your possession. + +Another nice thing is that you don't have to moderate content, since the only content +that is served to the public is content that your trusted users created. + +## The Dark Side + +There is a dark side to running a personal relay. If lots of people do this, nostr will +become more difficult for clients, especially clients running on mobile phones. Because +they will need to setup SSL connections to far too many relays. + +It may be better for others if people were to use a smaller number of larger relay services. + +But who am I to say? You are the sovereign. Here is your personal relay. + +## Incompleteness + +At the time of this writing, chorus is not yet complete. It doesn't even do AUTH, and it +accepts and serves events from and to anybody.