Web app

Run your private WebGUI Nostr relay to backup all your activity on Nostr. An official app by Umbrel. Powered by nostr-rs-relay.

Umbrel Nostr Relay webapp

Preparations

Install dependencies

  • These are build dependencies (safe to remove after installation, if you want)
$SU apk add --virtual .build-deps git npm
  • These are runtime dependencies
$SU apk add nodejs-current

Create the umbrel user/group

$SU addgroup -S umbrel
$SU adduser \
    -S \
    -D \
    -H \
    -h /dev/null \
    -s /sbin/nologin \
    -G umbrel \
    -g umbrel \
    umbrel

Add the user satoshi to the group umbrel as well

$SU adduser satoshi umbrel && exec su -l satoshi

Reverse proxy

In the Security section, we set up a reverse proxy. Now we can add the Umbrel Nostr Relay configuration.

  • Enable the reverse proxy to route external encrypted HTTPS traffic internally to the Umbrel Nostr Relay
$SU $EDITOR /etc/caddy/sites/umbrel-nostr-relay.caddy
/etc/caddy/sites/umbrel-nostr-relay.caddy
:8881 {
        import tls
        root * /var/www/umbrel-nostr-relay
        encode gzip
 
        @websockets {
                header Connection *Upgrade*
                header Upgrade    websocket
        }
 
        @nostr {
                header Accept application/nostr+json
        }
 
        @relayproxy {
                path /relay-proxy/*
        }
 
        reverse_proxy @websockets 127.0.0.1:8880
        reverse_proxy @nostr 127.0.0.1:8880
        reverse_proxy @relayproxy 127.0.0.1:81
 
        file_server
}
  • Reload Caddy
$SU rc-service caddy reload

Firewall

  • Configure the firewall to allow incoming HTTPS requests
$SU $EDITOR /etc/awall/optional/umbrel-nostr-relay.json
/etc/awall/optional/umbrel-nostr-relay.json
{
  "description": "Allow Umbrel Nostr Relay webGUI SSL",
 
  "filter": [
    {
      "in": "internet",
      "out": "_fw",
      "service": { "proto": "tcp", "port": 8881 },
      "action": "accept",
      "conn-limit": { "count": 10, "interval": 60 }
    }
  ]
}
  • Enable it
$SU awall enable umbrel-nostr-relay
$SU awall activate

Installation

Clone the source code

We get the latest release of the umbrel-nostr-relay source code, compile it to an executable binary and install it.

  • Download the source code for the latest umbrel-nostr-relay release. You can check the release page to see if a newer release is available. Other releases might not have been properly tested with the rest of the Microbolt configuration, though.
cd /tmp
VERSION=1.1.0
git clone --branch v$VERSION https://github.com/getumbrel/umbrel-nostr-relay

Backend

  • Install the backend dependencies and build the project
cd /tmp/umbrel-nostr-relay/relay-proxy
npm ci --omit=dev --omit=optional

Installation can take some time. There might be a lot of confusing output, but if you see something similar to the following, the installation was successful:

output
2 vulnerabilities (1 low, 1 moderate)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
⚠️

At 2024-09-03 there is at least 2 vulnerabilities not addressable without breaking changes

npm audit fix
  • Make it a global permanent installation
mkdir ./bin
printf "%s\n" \
    "#!/bin/sh" \
    "node \$@ /var/lib/umbrel-nostr-relay/server" \
    > ./bin/cli.sh
chmod +x ./bin/cli.sh
  • Replace the port and STORE constant with an environment variable
sed 's/const port = 80;/const port = process.env.RELAY_PROXY_PORT || 80;/' server.js > _
mv -f _ server.js
sed 's/export const STORE = ".\/data\/store.json";/export const STORE = process.env.RELAY_DATA_STORE || ".\/data\/store.json";/' constants.js > _
mv -f _ constants.js
$SU mv -f /tmp/umbrel-nostr-relay/relay-proxy /var/lib/umbrel-nostr-relay
$SU ln -s /var/lib/umbrel-nostr-relay /usr/lib/node_modules/umbrel-nostr-relay
$SU ln -s ../lib/node_modules/umbrel-nostr-relay/bin/cli.sh /usr/bin/umbrel-nostr-relay

Frontend

  • Install the frontend dependencies and build the project
cd /tmp/umbrel-nostr-relay/ui
npm ci

Installation can take some time. There might be a lot of confusing output, but if you see something similar to the following, the installation was successful:

output
21 vulnerabilities (8 moderate, 11 high, 2 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.
⚠️

At 2024-09-03 there is at least 21 vulnerabilities not addressable without breaking changes

npm audit fix
  • Make it a global permanent installation
sed 's/Umbrel/Microbolt/' public/index.html > _
mv -f _ public/index.html
sed \
    -e 's/{ relayPort }//' \
    -e '/<p className="text-slate-800 dark:text-slate-400 text-xs mt-4 mb-6">/,/<\/p>/d' \
    src/components/ConnectClient.js > _
mv -f _ src/components/ConnectClient.js
npm run build
$SU rm -rf /var/www/umbrel-nostr-relay
$SU mv -f ./build /var/www/umbrel-nostr-relay

Clean up

cd
rm -rf /tmp/umbrel-nostr-relay
$SU apk del .build-deps

Configuration

  • Add this values in the umbrel.env file
$SU mkdir /etc/umbrel-nostr-relay
$SU $EDITOR /etc/umbrel-nostr-relay/umbrel.env
/etc/umbrel-nostr-relay/umbrel.env
RELAY_HOST=127.0.0.1
RELAY_PORT=8880
RELAY_PROXY_PORT=81
RELAY_DATA_STORE=/etc/umbrel-nostr-relay/store.json
Remote access over Tor

To use your nostr relay when you’re on the go, you can easily create a Tor hidden service on the Microbolt and accessing the Umbrel Nostr Relay with the Tor browser from any device.

  • Add the following three lines in the “location-hidden services” section in the torrc file.
$SU $EDITOR /etc/tor/torrc
/etc/tor/torrc
# Hidden Service Umbrel Nostr Relay
HiddenServiceDir /var/lib/tor/umbrel-nostr-relay/
HiddenServiceVersion 3
HiddenServicePoWDefensesEnabled 1
HiddenServicePort 443 127.0.0.1:8881
  • Reload Tor configuration and get your connection address.
$SU rc-service tor reload
$SU cat /var/lib/tor/umbrel-nostr-relay/hostname
output
abcdefg..............xyz.onion
  • You should now be able to connect to your Umbrel Nostr Relay remotely via Tor using your hostname

Autostart on boot

Nostr Relay needs to start automatically on system boot.

  • Create the umbrel-nostr-relay init.d unit and copy/paste the following configuration
$SU $EDITOR /etc/init.d/umbrel-nostr-relay
/etc/init.d/umbrel-nostr-relay
#!/sbin/openrc-run
 
: ${UMBREL_NOSTR_RELAY_ENVFILE:=/etc/umbrel-nostr-relay/umbrel.env}
: ${UMBREL_NOSTR_RELAY_DATADIR:=/var/lib/umbrel-nostr-relay}
: ${UMBREL_NOSTR_RELAY_LOGDIR:=/var/log/umbrel-nostr-relay}
: ${UMBREL_NOSTR_RELAY_USER:=umbrel}
: ${UMBREL_NOSTR_RELAY_GROUP:=umbrel}
: ${UMBREL_NOSTR_RELAY_BIN:=/usr/bin/umbrel-nostr-relay}
: ${UMBREL_NOSTR_RELAY_OPTS=${UMBREL_NOSTR_RELAY_OPTS}}
: ${UMBREL_NOSTR_RELAY_SIGTERM_TIMEOUT:=600}
 
UMBREL_NOSTR_RELAY_PIDDIR="/run/umbrel-nostr-relay"
 
directory="${UMBREL_NOSTR_RELAY_DATADIR}"
required_files="${UMBREL_NOSTR_RELAY_ENVFILE}"
pidfile="${UMBREL_NOSTR_RELAY_PIDDIR}/${SVCNAME}.pid"
retry="${UMBREL_NOSTR_RELAY_SIGTERM_TIMEOUT}"
capabilities="^cap_net_bind_service"
 
name="Umbrel Nostr Relay"
description="A Nostr relay webGUI made by Umbrel"
 
command="${UMBREL_NOSTR_RELAY_BIN}"
command_args="--env-file=${UMBREL_NOSTR_RELAY_ENVFILE}
              ${UMBREL_NOSTR_RELAY_OPTS}"
command_user="${UMBREL_NOSTR_RELAY_USER}:${UMBREL_NOSTR_RELAY_GROUP}"
command_background="true"
 
start_stop_daemon_args="--stdout ${UMBREL_NOSTR_RELAY_LOGDIR}/debug.log
                        --stderr ${UMBREL_NOSTR_RELAY_LOGDIR}/debug.log"
 
depend() {
    need nostr-rs-relay
}
 
start_pre() {
    checkpath --directory --mode 0755 --owner "${command_user}" "${UMBREL_NOSTR_RELAY_ENVFILE%/*}"
    checkpath --file      --mode 0660 --owner "${command_user}" "${UMBREL_NOSTR_RELAY_ENVFILE}"
    checkpath --directory --mode 0750 --owner "${command_user}" "${UMBREL_NOSTR_RELAY_DATADIR}"
    checkpath --directory --mode 0755 --owner "${command_user}" "${UMBREL_NOSTR_RELAY_LOGDIR}"
    checkpath --directory --mode 0755 --owner "${command_user}" "${UMBREL_NOSTR_RELAY_PIDDIR}"
}
 
stop() {
    ebegin "Stopping ${SVCNAME}"
    pkill -TERM -P "$(cat ${pidfile})" > /dev/null 2>&1
    start-stop-daemon \
        --stop \
        --pidfile="${pidfile}" \
        --retry="${UMBREL_NOSTR_RELAY_SIGTERM_TIMEOUT}" \
        --exec="${UMBREL_NOSTR_RELAY_BIN}"
    eend $?
}
  • Enable execution permission
$SU chmod +x /etc/init.d/umbrel-nostr-relay

Enable logrotate

  • Enter the complete next configuration. Save and exit
/etc/logrotate.d/umbrel-nostr-relay
/var/log/umbrel-nostr-relay/*.log {
    weekly
    missingok
    rotate 104
    compress
    delaycompress
    notifempty
    create 0640 nostr nostr
    sharedscripts
    postrotate
        kill -HUP `cat /run/umbrel-nostr-relay/umbrel-nostr-relay.pid`
    endscript
}
  • Test
$SU logrotate /etc/logrotate.d/umbrel-nostr-relay --debug

Enable and start Nostr relay

$SU rc-update add umbrel-nostr-relay
$SU rc-service umbrel-nostr-relay start
  • Check the log to see Umbrel Nostr Relay output. Exit with Ctrl-C
tail -f /var/log/umbrel-nostr-relay/debug.log
  • Ensure the service is working and listening at the default 8881 port
$SU netstat -lntup | grep LISTEN | grep umbrel
output
tcp        0      0 0.0.0.0:8881            0.0.0.0:*               LISTEN      7140/umbrel-nostr-relay

For the future: Umbrel Nostr Relay upgrade

Follow again Umbrel Nostr Relay page replacing the environment variable VERSION=x.xx value for the latest if it has not been already changed in this guide.

  • Update the Umbrel Nostr Relay configuration if necessary (see release notes)
$SU $EDITOR /etc/umbrel-nostr-relay/umbrel.env
  • Restart the service to apply the changes
$SU rc-service umbrel-nostr-relay restart