Setting up a server

Optional. Adds an internet path when one exists, without affecting off-grid operation.

What it does

The rendezvous server is where two IRIS 3 devices meet over the internet. You use it to pair devices with a QR code and to send messages and data with Channel C, to one specific device or group. It keeps only a small directory of which device is where and forwards encrypted packets.

When you need it

You need it for nothing else. The map, field entries and communication over the bridge all work without a server. The server adds a second path when internet is available, and you can have both active at once.

Channel B (bridge)Channel C (server)
MediumRadio, no networkInternet
RecipientAll connected devicesOne device or one group
PrerequisiteConnected bridgeServer address and QR pairing

Before you start

The app needs an address of the form https://host:port, with no trailing /, reachable over HTTPS from every device. The guide assumes no IT background: each step says what you do and why. You need about an hour, a Windows computer, an email address and the IRIS 3 project folder, from which the server is built.

Option A: Oracle Cloud

Recommended. Free forever on the Always Free plan. Fixed address, no dependence on your home power or internet.

Option B: Raspberry Pi

Your own machine at home (around €60 to €90). No third-party dependence, but you need access to the router.

Option C: Paid cloud VPS

Any provider (DigitalOcean, Hetzner and others), around €4 to €6 a month. Useful if you do not want Oracle's sign-up.

Option D: Server on Windows

Run the server on a Windows machine (a PC at home or a Windows VPS), with no SSH and no Linux.

Option A: Oracle Cloud

  1. Open an Oracle Cloud account

    Go to oracle.com/cloud/free and click “Start for free”. You will be asked for an email, country and card details for identity verification. You are not charged on the Always Free plan. Pick a data region close to you, for example in Europe.

  2. Create the virtual machine

    1. In the menu: Compute, Instances, Create Instance.
    2. Name: iris3-server.
    3. Image: Ubuntu, latest LTS.
    4. Shape: Ampere (Always Free) or VM.Standard.E2.1.Micro. Both are free.
    5. Under “Add SSH keys” choose “Save private key” and keep the .key file. If you lose it, you cannot log in to the server.
    6. Click Create and wait for Running. Note the Public IP Address.
  3. Open port 443

    On the instance page click the Subnet, then the Security List, Add Ingress Rules. Source CIDR 0.0.0.0/0, protocol TCP, destination port 443.

    Do not open port 8443. The server listens on it internally only. Every request carries a bearer token, and if 8443 were open to the outside it would travel unencrypted.

  4. Log in over SSH from Windows

    Open PowerShell. Replace the path and the IP with your own.

    icacls "C:\Users\you\Downloads\ssh-key-xxxx.key" /inheritance:r /grant:r "${env:USERNAME}:R"
    ssh -i "C:\Users\you\Downloads\ssh-key-xxxx.key" ubuntu@132.145.x.x

    At “yes/no” type yes. When the prompt becomes ubuntu@iris3-server:~$, you are in.

  5. Install Java

    The server is written in Kotlin/Java. Inside the SSH session:

    sudo apt-get update
    sudo apt-get install -y openjdk-17-jre
  6. Get the package and send it to the server

    Download the ready-made server package to your own computer and unzip it. Inside you will find a folder named rendezvous-server.

    If you prefer to build it yourself, and you have the IRIS 3 project, run this inside its folder, in a second PowerShell window:

    .\gradlew.bat :rendezvous-server:installDist

    The build creates the folder rendezvous-server\build\install\rendezvous-server\. Whichever option you chose, send the rendezvous-server folder with WinSCP (free, winscp.net): SFTP protocol, host is the server IP, user ubuntu, and under Advanced, SSH, Authentication use the same .key file (if it offers to convert it to .ppk, click OK). Create the folder /opt/iris3 and drag rendezvous-server into it.

    If WinSCP will not let you write to /opt, first run this in SSH:

    sudo mkdir -p /opt/iris3 && sudo chown ubuntu /opt/iris3
  7. Make the admin token

    Before you set the server up as a permanent service, make a second, separate secret. It is not the SSH key and it does not get you into the machine. It only lets the admin tool see and manage the device list. In SSH:

    openssl rand -hex 32

    A long string of letters and digits will print. Copy it and keep it somewhere safe. You need it in the next step and again in the admin tool. Anyone who has it can see and delete devices, so do not share it.

  8. Make it run permanently

    The server will start by itself after every reboot. In SSH open the file:

    sudo nano /etc/systemd/system/iris3-rendezvous.service

    Paste this, replacing YOUR-TOKEN with the string you copied in the previous step. Save with Ctrl+O and Enter, and exit with Ctrl+X:

    [Unit]
    Description=IRIS3 Rendezvous Server
    After=network.target
    
    [Service]
    Environment=RENDEZVOUS_DB_URL=jdbc:sqlite:/opt/iris3/rendezvous.db
    Environment=RENDEZVOUS_PORT=8443
    Environment=RENDEZVOUS_ADMIN_TOKEN=YOUR-TOKEN
    ExecStart=/opt/iris3/rendezvous-server/bin/rendezvous-server
    Restart=always
    User=ubuntu
    
    [Install]
    WantedBy=multi-user.target
    sudo systemctl enable --now iris3-rendezvous
    curl http://127.0.0.1:8443/health

    If it answers OK, the server works.

    If you skipped the previous step: without the RENDEZVOUS_ADMIN_TOKEN line the server works normally for the app, but the admin routes are closed and the admin tool will not connect. You can add it any time: open the file again, add the line, save and run sudo systemctl daemon-reload && sudo systemctl restart iris3-rendezvous.

  9. Get a domain name

    The app needs HTTPS, and HTTPS needs a name, not a bare IP. The easy free option is DuckDNS: sign in at duckdns.org with a Google or GitHub account, choose a sub-domain (for example iris3 gives iris3.duckdns.org), put the server's Public IP in “current ip” and click “update ip”. If you own a domain, create an A record there pointing to the same IP.

  10. Add HTTPS with nginx

    nginx stands in front of the server, speaks HTTPS to the outside and passes requests internally to port 8443.

    sudo apt-get install -y nginx certbot python3-certbot-nginx
    sudo nano /etc/nginx/sites-available/default

    Delete what is there and paste the following, with your own name in place of iris3.example.org:

    server {
        listen 80;
        server_name iris3.example.org;
    
        location / {
            proxy_pass http://127.0.0.1:8443;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_http_version 1.1;
            proxy_read_timeout 300s;
        }
    }
    sudo nginx -t
    sudo systemctl reload nginx
    sudo certbot --nginx -d iris3.example.org

    certbot asks for an email for expiry notices and sets up a free certificate that renews itself every 90 days.

    Why the three proxy_set_header lines: the app keeps a persistent WebSocket open to receive messages instantly. Without them nginx closes it and the app silently falls back to slower operation, with no visible error.

  11. Check from outside

    In a browser on your computer open:

    https://iris3.example.org/health

    If it shows OK, the whole chain works: app, internet, nginx, server. Then go to “Setting it in the app”.

Option B: Raspberry Pi

The logic is the same as option A (SSH, Java, service, nginx). Three things change: you do not rent a machine, the port opens on the router, and a trick is needed so the name follows your home's changing IP.

  1. Prepare the Raspberry Pi

    Download Raspberry Pi Imager (raspberrypi.com/software). Choose your model and Raspberry Pi OS Lite (64-bit). Before writing the card (microSD, at least 8 GB) click the gear: enable SSH, set a user and password, and enter your Wi-Fi. Put the card in the Pi, power it and wait about a minute. Find its local IP in the router's device list.

  2. SSH, Java and copying the server

    As in steps 4, 5 and 6 of option A, with two differences: you log in with the local user and IP (no Oracle key), and you install Java 21, because newer Pi OS versions do not have the 17 package.

    ssh your-user@192.168.1.xx
    sudo apt-get update
    sudo apt-get install -y openjdk-21-jre-headless
  3. Check the port is free

    If the Pi runs another service, it may already be using 8443.

    sudo ss -tlnp

    If you see something on :8443, use 9443. The steps below assume it.

  4. Make it run permanently

    The same service file as step 8 of option A. Change RENDEZVOUS_PORT to 9443 if you chose another port, and User to your own user.

    Also make the admin token as in step 7 (openssl rand -hex 32) and put it on the RENDEZVOUS_ADMIN_TOKEN line.

    sudo systemctl enable --now iris3-rendezvous
    curl http://127.0.0.1:9443/health
  5. A name that follows your home connection

    Your home has no fixed public IP. Create the domain at DuckDNS as in step 9 of option A and add a small script that refreshes it every 5 minutes.

    mkdir ~/duckdns && cd ~/duckdns
    nano duck.sh

    Inside the file put (with your own token and domain from the DuckDNS page):

    echo url="https://www.duckdns.org/update?domains=iris3&token=YOUR_TOKEN&ip=" | curl -k -o ~/duckdns/duck.log -K -
    chmod 700 duck.sh
    crontab -e

    Add at the end of the file that opens:

    */5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1
  6. Port forwarding on the router

    This replaces the cloud Security List. Open your router's admin page (often 192.168.1.1), find Port Forwarding or Virtual Server and create a rule: external port 443, internal IP the Pi's local IP, internal port 443.

  7. HTTPS with nginx

    Follow step 10 of option A, with one change: in proxy_pass use the port you chose.

    proxy_pass http://127.0.0.1:9443;

    Then run certbot and do the check from step 11. If you are moving from an Oracle server and want to keep your devices, copy rendezvous.db with WinSCP to the Pi's /opt/iris3/ before starting the service. Otherwise start with an empty database and the devices re-register themselves.

Option C: Paid cloud VPS

If you do not want to go through Oracle's sign-up, or want a more predictable machine without the Always Free limits, you can use any VPS provider, e.g. DigitalOcean, Hetzner or Linode. The logic is the same as option A. What changes is the sign-up, the cost (usually €4 to €6 a month for the smallest machine) and a few names in the interface.

  1. Sign up and create the machine

    Sign up with the provider (digitalocean.com, hetzner.com/cloud or linode.com). It needs a card and you will be charged every month, there is no free plan. Then create a new machine (“Droplet” at DigitalOcean, “Server” at Hetzner):

    1. Operating system: Ubuntu 22.04 or 24.04 LTS.
    2. Size: the smallest and cheapest plan is enough (1 vCPU, 1 GB RAM).
    3. Authentication: choose an SSH key instead of a password. If you have no key pair, make one in PowerShell:
      ssh-keygen -t ed25519 -f "$env:USERPROFILE\.ssh\iris3_vps"
      Paste the contents of iris3_vps.pub into the provider's “SSH Key” field.
    4. Click create. In 1 to 2 minutes you will see a public IP (e.g. 167.99.x.x). Note it down.
  2. Open port 443 in the provider's firewall

    As in step 3 of option A. The firewall is called “Firewalls” at DigitalOcean and “Firewall” in the Hetzner Cloud console. Create an inbound rule: TCP, port 443, source 0.0.0.0/0, and apply it to the machine. Do not open 8443, for the same reason.

    Some providers (e.g. Hetzner) leave all ports open if you create no firewall. Then this step is optional, but adding one anyway is recommended.

  3. Continue from step 4 of option A

    Follow steps 4 to 11 of option A as they are, typing the new IP and your own key instead of Oracle's in SSH. Then go to the “Setting it in the app” section.

    ssh -i "$env:USERPROFILE\.ssh\iris3_vps" root@167.99.x.x

    Different username. Most VPS providers log you in as root, not ubuntu. As root you do not need sudo (it still works with it). In the service file of step 8, change User=ubuntu to User=root, and in WinSCP use user root.

Option D: Server on Windows

If you already have a Windows machine that can stay on all the time (a PC at home or a Windows VPS), you can run the server there, with no SSH, Linux or WinSCP. Instead of systemd we use the free tool NSSM, which wraps the server in a normal Windows service. Instead of nginx and certbot we use Caddy, a single program that gets a free HTTPS certificate on its own.

  1. Install Java

    Download the free Eclipse Temurin JDK 17 (the .msi for Windows) from adoptium.net and install it, leaving “Set JAVA_HOME” and “Add to PATH” selected. Check in a new PowerShell window:

    java -version
  2. Copy the program

    Use the server package (step 6 of option A). It also contains a Windows launcher, bin\rendezvous-server.bat. Copy the rendezvous-server folder to the target machine, e.g. to C:\iris3\rendezvous-server. On a PC, copy and paste is enough. On a Windows VPS use Remote Desktop (drag the folder into the window) or a cloud drive.

  3. Make the admin token

    Windows has no openssl, but PowerShell produces the same result with a secure random generator:

    $b = New-Object byte[] 32; [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($b); ($b | ForEach-Object { $_.ToString('x2') }) -join ''

    Copy the string that prints and keep it somewhere safe. You need it in the next step and again in the admin tool.

  4. Make it run permanently

    Download NSSM (free, nssm.cc/download), unzip it and put nssm.exe at C:\iris3\nssm.exe. Create the file C:\iris3\start.bat (right-click in the folder, New, Text Document, rename it, open it with Notepad) with this content, using your own token:

    @echo off
    set RENDEZVOUS_DB_URL=jdbc:sqlite:C:\iris3\rendezvous.db
    set RENDEZVOUS_PORT=8443
    set RENDEZVOUS_ADMIN_TOKEN=YOUR-TOKEN
    C:\iris3\rendezvous-server\bin\rendezvous-server.bat

    Then, in PowerShell as administrator (right-click the icon, “Run as administrator”):

    C:\iris3\nssm.exe install IRIS3Rendezvous "C:\iris3\start.bat"
    C:\iris3\nssm.exe set IRIS3Rendezvous AppDirectory C:\iris3
    C:\iris3\nssm.exe start IRIS3Rendezvous

    The IRIS3Rendezvous service will start by itself on every reboot and NSSM will restart it if it dies, like Restart=always in step 8 of option A. Check:

    curl http://127.0.0.1:8443/health
  5. Open port 443 in the Windows firewall

    In PowerShell as administrator:

    New-NetFirewallRule -DisplayName "IRIS3 HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
    • If it is a PC at home, also add port forwarding on the router, as in the “Port forwarding on the router” step of option B (external 443, the PC's internal IP, internal 443).
    • If it is a Windows VPS, also open 443 in the provider's firewall, as in step 2 of option C.
  6. HTTPS with Caddy

    nginx and certbot are made for Linux. On Windows the simplest equivalent is Caddy: it does the reverse proxy and also gets and renews an HTTPS certificate on its own. Download caddy_windows_amd64.exe from caddyserver.com/download, rename it to caddy.exe and put it in C:\iris3\caddy\. Create a file there named Caddyfile (no extension), with your own domain in place of iris3.example.org:

    iris3.example.org {
        reverse_proxy 127.0.0.1:8443
    }

    Install this one as a service with NSSM too (PowerShell as administrator):

    C:\iris3\nssm.exe install IRIS3Caddy "C:\iris3\caddy\caddy.exe" "run --config C:\iris3\caddy\Caddyfile"
    C:\iris3\nssm.exe set IRIS3Caddy AppDirectory C:\iris3\caddy
    C:\iris3\nssm.exe start IRIS3Caddy

    Caddy gets a certificate from Let's Encrypt the first time it receives traffic on 443. For that, the domain must already point to the right IP (next step).

  7. Domain name

    Create the domain at DuckDNS as in step 9 of option A. If it is a Windows VPS with a fixed IP, you update it once and you are done.

    If it is a PC at home (the IP changes), create a scheduled task that refreshes DuckDNS every 5 minutes, instead of the cron of option B:

    1. Open Task Scheduler and click Create Task.
    2. Trigger: Repeat task every 5 minutes, for a duration of Indefinitely.
    3. Action: Start a program, Program powershell.exe, Arguments (with your own token and domain):
      -Command "Invoke-WebRequest 'https://www.duckdns.org/update?domains=iris3&token=YOUR_TOKEN&ip='"
  8. Check from outside

    As in step 11 of option A, from a browser:

    https://iris3.example.org/health

    If it shows OK, continue with the “Setting it in the app” and “Windows admin tool” sections. They are the same wherever the server runs.

Setting it in the app

  1. Enter the address

    Open the menu (☰), then Communication Setup. In the server address field enter, for example, https://iris3.example.org with no trailing slash, and save. Do this on every device that will use the server. Without an address, the Rendezvous Pairing screen says “No rendezvous server address is set.”

  2. Set the Network Key

    The Server panel only opens once a Network Key exists.

  3. Pair your devices

    See the next section.

Pairing with QR

Open Rendezvous Pairing from the navigation drawer. One device shows a code, the other scans it.

  1. Device A: Generate Code

    A QR and text code appear with a countdown. The code expires.

  2. Device B: Scan Code

    Needs Camera permission. If the device is new, name it. If it is already known, “Pairing successful” appears.

  3. Device A: Refresh and Save

    The side that made the code does not see that it was scanned on its own. Tap Refresh in Known Devices, name the device and Save.

  4. Send with Channel C

    On any “Send”, choose Channel C and then a recipient: one Known Device or one Group.

Groups are created in the Server panel, with members from your Known Devices. Only a group's creator can edit or delete it.

Windows admin tool

The Rendezvous Admin Tool is a Windows app for whoever runs the server. It shows which devices are registered, clears pending messages and checks that the network path works, with no SSH and no hand-written SQL. It never sees message content.

Windows 10 or 11, 64-bit. No installer and no .NET needed: download and run RendezvousAdminTool.exe (about 116 MB). Windows may show “Windows protected your PC”, because the program is not digitally signed. Click “More info” and then “Run anyway”.

What it does

  • Device list: device id, endpoint, when it was last seen, how many messages it sent and how many are still undelivered.
  • Delete one, several or all devices.
  • Clear all pending messages on the server.
  • Retention time: how long the server keeps an undelivered message before dropping it (default 3 days).
  • Diagnostics: checks the database, message routing and a real WebSocket connection to /mailbox, from your computer to the server.
  • Restart the server remotely.
  • Auto-refresh every 5 seconds.

Setup

  1. Set the admin token on the server

    If you built the server with the guide above, the token is already set. If not, make a random secret, for example with openssl rand -hex 32, and add it to the service file under [Service]:

    Environment=RENDEZVOUS_ADMIN_TOKEN=your-secret
    sudo systemctl daemon-reload
    sudo systemctl restart iris3-rendezvous

    With no token set, the server answers 404 on every admin route. Admin is closed by default.

  2. Open the tool

    In Server URL enter the same address as the Android app, with no trailing slash, e.g. https://iris3.example.org. In Admin Token enter the secret from step 1 and press Connect/Refresh.

  3. The values are saved

    After the first successful connection, the tool keeps them in %APPDATA%\IrisRendezvousAdmin\config.json and connects on its own at the next start.

The token is an admin key. Anyone who has it can delete devices and restart the server. config.json stores it as plain text, so do not share it and do not leave it on a shared computer.

What each control does

ControlWhat it does
Device tableDevice Id, Endpoint, Last Seen (local time), Sent, Undelivered. Devices seen longest ago come first.
Delete selectedEnabled once you select rows. Asks for confirmation and deletes one by one. If one fails the rest continue, and you get a summary. Deleting cannot be undone, but a device re-registers on its own if it connects again.
Delete allDeletes every registered device, with a second, stronger confirmation.
Run diagnosticsAn OK/FAIL list per check, with response time.
Clear all pendingDeletes the pending messages of every device. It cannot be undone.
Undelivered timeout + SaveReads and changes the retention time of undelivered messages.
Restart serverRequests a restart. systemd (Restart=always) brings it back in a few seconds and every /mailbox connection reconnects.
Total undeliveredTotal number of pending messages on the whole server.

If something fails

What you seeWhat to do
401Wrong or empty Admin Token. It must match the server's RENDEZVOUS_ADMIN_TOKEN.
404 on everythingThe server has no token set. Set it (step 1) and restart.
Network errorCheck the Server URL (https://...), that nginx and HTTPS work and that you can reach port 443. Not the server's internal port directly.
Only the WebSocket check failsnginx is probably not passing the WebSocket through to /mailbox. Check the proxy_set_header Upgrade and Connection lines in its config.

It does not manage groups, pairings or message content, has no multiple admins and no action log. When you delete a device, its pairings stay behind, inactive, and are not removed.

Security notes

  • Keep 8443 closed to the outside. Only 443, with HTTPS, should be visible.
  • The pairing code expires, and an invalid or expired code is rejected. You cannot pair with your own device.
  • Channel C always sends to a specific recipient, never to the whole network.
  • The Network Key encrypts communication over the bridge. Change it when the team's composition changes.
  • Keep the SSH key file safe and do not share the server address with people outside the team.

If something fails

What you seeWhat to do
curl http://127.0.0.1:8443/health gets no answerRun sudo systemctl status iris3-rendezvous to see the error.
The HTTPS address does not open from outsideCheck that 443 is open (step 3 or port forwarding) and that the IP at DuckDNS is correct.
The server IP changedSign in to DuckDNS and click “update ip” again.
You rebooted the serverNothing. systemctl enable starts it by itself.
Raspberry Pi: stopped after a power cut or router rebootWait up to 5 minutes for DuckDNS to refresh, or run ~/duckdns/duck.sh by hand.
BindException: Address already in useAnother service has the port. Check with sudo ss -tlnp, choose another and change both RENDEZVOUS_PORT and proxy_pass.
The admin tool shows “Refresh failed” or UnauthorizedThe token you entered does not match the RENDEZVOUS_ADMIN_TOKEN in the service file, or the line is missing. Compare them character by character. If you fixed it, run sudo systemctl daemon-reload && sudo systemctl restart iris3-rendezvous and click Connect/Refresh again.
Windows blocks the admin tool from openingIn the SmartScreen window click “More info” and then “Run anyway”. The program is not digitally signed, which is why Windows treats it as unknown.
(Cloud VPS) You cannot connect with SSHCheck that you use the right username (root at DigitalOcean, Hetzner and Linode, not ubuntu) and the right private key.
(Windows) The service does not startRun C:\iris3\nssm.exe status IRIS3Rendezvous, or open Windows Services (services.msc) and look for IRIS3Rendezvous or IRIS3Caddy for the error.
(Windows) Caddy does not get an HTTPS certificateUsually the domain does not point to the right public IP yet, or 443 is not really open from outside. Let's Encrypt must reach port 443 from the internet to confirm the domain.

Want to try it?

The app is available in open testing on Google Play. Download it, try it and tell us what you think.

Try it on Google Play