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) | |
|---|---|---|
| Medium | Radio, no network | Internet |
| Recipient | All connected devices | One device or one group |
| Prerequisite | Connected bridge | Server 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
Open an Oracle Cloud account
Go to
oracle.com/cloud/freeand 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.Create the virtual machine
- In the menu: Compute, Instances, Create Instance.
- Name:
iris3-server. - Image: Ubuntu, latest LTS.
- Shape: Ampere (Always Free) or VM.Standard.E2.1.Micro. Both are free.
- Under “Add SSH keys” choose “Save private key” and keep the
.keyfile. If you lose it, you cannot log in to the server. - Click Create and wait for Running. Note the Public IP Address.
Open port 443
On the instance page click the Subnet, then the Security List, Add Ingress Rules. Source CIDR
0.0.0.0/0, protocolTCP, destination port443.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.
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.xAt “yes/no” type
yes. When the prompt becomesubuntu@iris3-server:~$, you are in.Install Java
The server is written in Kotlin/Java. Inside the SSH session:
sudo apt-get update sudo apt-get install -y openjdk-17-jreGet 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:installDistThe build creates the folder
rendezvous-server\build\install\rendezvous-server\. Whichever option you chose, send therendezvous-serverfolder with WinSCP (free,winscp.net): SFTP protocol, host is the server IP, userubuntu, and under Advanced, SSH, Authentication use the same.keyfile (if it offers to convert it to.ppk, click OK). Create the folder/opt/iris3and dragrendezvous-serverinto it.If WinSCP will not let you write to
/opt, first run this in SSH:sudo mkdir -p /opt/iris3 && sudo chown ubuntu /opt/iris3Make 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 32A 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.
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.servicePaste this, replacing
YOUR-TOKENwith the string you copied in the previous step. Save withCtrl+Oand Enter, and exit withCtrl+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.targetsudo systemctl enable --now iris3-rendezvous curl http://127.0.0.1:8443/healthIf it answers
OK, the server works.If you skipped the previous step: without the
RENDEZVOUS_ADMIN_TOKENline 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 runsudo systemctl daemon-reload && sudo systemctl restart iris3-rendezvous.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.orgwith a Google or GitHub account, choose a sub-domain (for exampleiris3givesiris3.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.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/defaultDelete 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.orgcertbot 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.
Check from outside
In a browser on your computer open:
https://iris3.example.org/healthIf 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.
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.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-headlessCheck the port is free
If the Pi runs another service, it may already be using 8443.
sudo ss -tlnpIf you see something on
:8443, use9443. The steps below assume it.Make it run permanently
The same service file as step 8 of option A. Change
RENDEZVOUS_PORTto9443if you chose another port, andUserto your own user.Also make the admin token as in step 7 (
openssl rand -hex 32) and put it on theRENDEZVOUS_ADMIN_TOKENline.sudo systemctl enable --now iris3-rendezvous curl http://127.0.0.1:9443/healthA 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.shInside 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 -eAdd at the end of the file that opens:
*/5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1Port 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 port443, internal IP the Pi's local IP, internal port443.HTTPS with nginx
Follow step 10 of option A, with one change: in
proxy_passuse the port you chose.proxy_pass http://127.0.0.1:9443;Then run
certbotand do the check from step 11. If you are moving from an Oracle server and want to keep your devices, copyrendezvous.dbwith 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.
Sign up and create the machine
Sign up with the provider (
digitalocean.com,hetzner.com/cloudorlinode.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):- Operating system: Ubuntu 22.04 or 24.04 LTS.
- Size: the smallest and cheapest plan is enough (1 vCPU, 1 GB RAM).
- Authentication: choose an SSH key instead of a password. If you have no key pair, make one in PowerShell:
Paste the contents ofssh-keygen -t ed25519 -f "$env:USERPROFILE\.ssh\iris3_vps"iris3_vps.pubinto the provider's “SSH Key” field. - Click create. In 1 to 2 minutes you will see a public IP (e.g.
167.99.x.x). Note it down.
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, source0.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.
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.xDifferent username. Most VPS providers log you in as
root, notubuntu. Asrootyou do not needsudo(it still works with it). In the service file of step 8, changeUser=ubuntutoUser=root, and in WinSCP use userroot.
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.
Install Java
Download the free Eclipse Temurin JDK 17 (the
.msifor Windows) fromadoptium.netand install it, leaving “Set JAVA_HOME” and “Add to PATH” selected. Check in a new PowerShell window:java -versionCopy the program
Use the server package (step 6 of option A). It also contains a Windows launcher,
bin\rendezvous-server.bat. Copy therendezvous-serverfolder to the target machine, e.g. toC:\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.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.
Make it run permanently
Download NSSM (free,
nssm.cc/download), unzip it and putnssm.exeatC:\iris3\nssm.exe. Create the fileC:\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.batThen, 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 IRIS3RendezvousThe
IRIS3Rendezvousservice will start by itself on every reboot and NSSM will restart it if it dies, likeRestart=alwaysin step 8 of option A. Check:curl http://127.0.0.1:8443/healthOpen 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.
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.exefromcaddyserver.com/download, rename it tocaddy.exeand put it inC:\iris3\caddy\. Create a file there namedCaddyfile(no extension), with your own domain in place ofiris3.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 IRIS3CaddyCaddy 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).
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
cronof option B:- Open Task Scheduler and click Create Task.
- Trigger: Repeat task every 5 minutes, for a duration of Indefinitely.
- 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='"
Check from outside
As in step 11 of option A, from a browser:
https://iris3.example.org/healthIf 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
Enter the address
Open the menu (☰), then Communication Setup. In the server address field enter, for example,
https://iris3.example.orgwith 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.”Set the Network Key
The Server panel only opens once a Network Key exists.
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.
Device A: Generate Code
A QR and text code appear with a countdown. The code expires.
Device B: Scan Code
Needs Camera permission. If the device is new, name it. If it is already known, “Pairing successful” appears.
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.
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
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-secretsudo systemctl daemon-reload sudo systemctl restart iris3-rendezvousWith no token set, the server answers
404on every admin route. Admin is closed by default.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.The values are saved
After the first successful connection, the tool keeps them in
%APPDATA%\IrisRendezvousAdmin\config.jsonand 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
| Control | What it does |
|---|---|
| Device table | Device Id, Endpoint, Last Seen (local time), Sent, Undelivered. Devices seen longest ago come first. |
| Delete selected | Enabled 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 all | Deletes every registered device, with a second, stronger confirmation. |
| Run diagnostics | An OK/FAIL list per check, with response time. |
| Clear all pending | Deletes the pending messages of every device. It cannot be undone. |
| Undelivered timeout + Save | Reads and changes the retention time of undelivered messages. |
| Restart server | Requests a restart. systemd (Restart=always) brings it back in a few seconds and every /mailbox connection reconnects. |
| Total undelivered | Total number of pending messages on the whole server. |
If something fails
| What you see | What to do |
|---|---|
| 401 | Wrong or empty Admin Token. It must match the server's RENDEZVOUS_ADMIN_TOKEN. |
| 404 on everything | The server has no token set. Set it (step 1) and restart. |
| Network error | Check 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 fails | nginx 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 see | What to do |
|---|---|
curl http://127.0.0.1:8443/health gets no answer | Run sudo systemctl status iris3-rendezvous to see the error. |
| The HTTPS address does not open from outside | Check that 443 is open (step 3 or port forwarding) and that the IP at DuckDNS is correct. |
| The server IP changed | Sign in to DuckDNS and click “update ip” again. |
| You rebooted the server | Nothing. systemctl enable starts it by itself. |
| Raspberry Pi: stopped after a power cut or router reboot | Wait up to 5 minutes for DuckDNS to refresh, or run ~/duckdns/duck.sh by hand. |
BindException: Address already in use | Another 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 Unauthorized | The 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 opening | In 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 SSH | Check that you use the right username (root at DigitalOcean, Hetzner and Linode, not ubuntu) and the right private key. |
| (Windows) The service does not start | Run 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 certificate | Usually 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. |