Build a Raspi Pi3B Homebrew Hotspot DMR only
2026-05-28 19:55:09
Raspberry Pi 3B Homebrew DMR Hotspot with DOH Dashboard and Tailscale Protection
This guide shows how to build a homebrew DMR hotspot on a Raspberry Pi 3B using plain Raspberry Pi OS Lite, an MMDVM-compatible modem, DOH for the DMR stack, the built-in DOH dashboard, and Tailscale for secure remote access.[cite:16][cite:73]
System design
The build uses Raspberry Pi OS Lite on a Pi 3B, a modem that works with MMDVM-based software, DOH as the DMR-only host, and the optional DOH dashboard for browser-based management.[cite:16] The dashboard should stay private because the DOH project notes that its mini web server is fine behind a firewall but is not intended for direct public exposure.[cite:16]
A secure remote-access design is to keep the dashboard local and reach it over Tailscale, optionally using Tailscale Serve and policy-based access control.[cite:60][cite:77][cite:105]
Parts list
Raspberry Pi 3 Model B
16 GB or larger microSD card
Stable 5V power supply
MMDVM-compatible simplex or duplex hotspot board
Suitable antenna for the modem board
Ethernet connection or Wi-Fi credentials
Amateur radio callsign and DMR ID
DOH is intended for MMDVM-based modems, and the project provides configuration for simplex and duplex-capable hardware.[cite:16]
1. Prepare Raspberry Pi OS Lite
Install Raspberry Pi Imager on another computer.
Select the Raspberry Pi 3 as the target device.
Select Raspberry Pi OS Lite.
Select the microSD card.
Open the advanced customization settings before writing the image.
Set hostname, username, password, locale, and Wi-Fi details if using Wi-Fi.
Enable SSH.
Write the image and move the card to the Pi.
Attach the hotspot modem board and antenna.
Power up the Pi.
Tailscale and DOH both work fine on standard Linux installs, so using plain Raspberry Pi OS Lite avoids appliance-image limitations.[cite:16][cite:73]
2. First login and OS update
SSH into the Pi:
bash
ssh pi@raspberrypi.local
Or connect to the Pi’s LAN IP address instead.[cite:16]
Update the OS:
bash
sudo apt update
sudo apt full-upgrade -y
sudo reboot
After the reboot, reconnect and run:
bash
sudo raspi-config
Confirm hostname, locale, timezone, Wi-Fi country, and SSH settings.[cite:38]
3. Enable the Pi 3B serial port for the modem
On a Pi 3B, it is usually best to reference the modem as /dev/serial0, because Raspberry Pi serial aliases are more stable across models and mappings than hard-coding /dev/ttyAMA0.[cite:37]
In raspi-config:
Open Interface Options.
Open Serial Port.
Answer No to the serial login shell.
Answer Yes to enabling the serial hardware.
Then edit the boot config file. Depending on your Raspberry Pi OS version, use either /boot/config.txt or /boot/firmware/config.txt:
bash
sudo nano /boot/config.txt
Add or confirm these lines:
ini
enable\_uart=1
dtoverlay=disable-bt
Disabling Bluetooth on the Pi 3B frees the primary UART so the main serial interface can be used for the modem.[cite:38]
Reboot:
bash
sudo reboot
After reboot, verify the serial mapping:
bash
ls -l /dev/serial0 /dev/serial1
dmesg | grep -E "ttyAMA0|ttyS0|serial"
If /dev/serial0 points to /dev/ttyAMA0, then the full UART is assigned there; if not, use /dev/serial0 in your hotspot config instead of forcing ttyAMA0.[cite:37][cite:38]
4. Install packages required for DOH and the dashboard
Install the build dependencies and dashboard packages:
bash
sudo apt install -y git build-essential curl libsqlite3-dev sqlite3 \\
php-common php-fpm php-sqlite3 dnsutils avahi-daemon
DOH documents libsqlite3-dev and curl as build requirements, and it lists php-common, php-fpm, sqlite3, php-sqlite3, and dnsutils for the dashboard.[cite:16] The project also notes that avahi-daemon can help if the hostname-based dashboard URL does not resolve on your network.[cite:16]
5. Verify the modem device
Confirm which serial device the modem is using:
bash
dmesg | grep -i tty
ls /dev/ttyAMA\* /dev/ttyACM\* /dev/ttyUSB\* /dev/serial\* 2>/dev/null
For a Pi-header-connected modem on a Pi 3B, /dev/serial0 is the preferred device path to use in the configuration.[cite:37][cite:38] If your modem connects over USB, it may appear as /dev/ttyUSB0 or /dev/ttyACM0 instead.[cite:123]
6. Download and build DOH
Clone and build the project:
bash
cd \~
git clone https://github.com/n7tae/doh.git
cd doh
make
DOH is built from source with make, and the repository provides both the host application and dashboard installer.[cite:16]
7. Create the DOH configuration
Start the guided configuration tool:
bash
cd \~/doh
./config
The DOH project documents this menu-driven tool and says it writes the configuration when you exit and save.[cite:16]
If you prefer to edit by hand:
bash
cp dmr.ini dmr.cfg
nano dmr.cfg
The DOH documentation says to set your callsign and DMR ID in the \[General] section, set duplex mode to match your modem, set frequency in the \[Info] section, and confirm that the \[Modem] section matches your MMDVM-based modem.[cite:16]
Use this checklist:
Callsign
DMR ID
Duplex setting, simplex or duplex
Modem port, preferably /dev/serial0 on a Pi-header-connected Pi 3B modem
RX frequency
TX frequency
DMR network type and destination
Startup talkgroup if desired
A sample configuration layout is:
```ini
[General]
Callsign=YOURCALL
Id=YOURDMRID
Duplex=0
[Info] RXFrequency=433500000 TXFrequency=433500000
[Modem] Port=/dev/serial0
[DMR Network]
Startup=9990
The shipped template remains the authoritative source because exact options can vary by DOH version and network choice.[cite:16]
8. Optional: add DMRGateway for multi-network access
If you want to connect to multiple DMR networks, DOH documents using Jonathan G4KLX’s DMRGateway alongside the hotspot.[cite:16]
Build it like this:bash
cd \~
git clone https://github.com/g4klx/DMRGateway.git
cd DMRGateway
make
cp DMRGateway.ini DMRGateway.cfg
nano DMRGateway.cfg
Then return to the DOH directory and install both components.[cite:16]
9. Install DOH and optional gateway
Install the hotspot software:bash
cd \~/doh
sudo make install
If you built DMRGateway and plan to use it, also run:bash
sudo make installgateway
These are the install commands documented by the DOH project.[cite:16]
10. Install and test the DOH dashboard
Install the dashboard:bash
cd \~/doh
sudo make installdash
The DOH documentation says the dashboard can be reached by hostname or internal IP, for example `hotspot-hostname.local` or the Pi’s LAN IP address.[cite:16]
Try these URLs from a browser on your LAN:
`http://hostname.local`
`http://pi-lan-ip`
If the `.local` hostname does not resolve, install or restart Avahi:bash
sudo apt install -y avahi-daemon
sudo systemctl enable --now avahi-daemon
The DOH README specifically recommends `avahi-daemon` if `.local` name resolution is not working.[cite:16]
11. Monitor the hotspot locally
You can watch the live service log with:bash
sudo journalctl -u doh -f
The DOH project documents `journalctl -u doh -f` as a way to monitor the running service while the dashboard is still evolving.[cite:16]
You can refresh the DMR ID table with:bash
sudo update-dmrid
sudo systemctl restart doh
The project documents `update-dmrid` and notes that restarting the service makes the updated table take effect immediately.[cite:16]
12. Install Tailscale for secure remote access
Install Tailscale on the Pi:bash
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Tailscale’s Linux install docs describe this installation flow and bringing the node online with `tailscale up`.[cite:73]
When the login URL appears, open it in a browser, authenticate, and approve the Pi in the Tailscale admin console.[cite:97]
Check the Tailscale address:bash
tailscale ip -4
tailscale status
The Tailscale quickstart explains that devices appear in the admin console after authentication and can then be managed there.[cite:97]
13. Protect the hotspot with Tailscale instead of public exposure
The safest setup is to keep the DOH dashboard off the public internet and access it only through your Tailscale tailnet.[cite:16][cite:60] Tailscale Serve can proxy a local service to other devices in the tailnet, including HTTPS access inside the tailnet.[cite:60][cite:79][cite:82]
If your DOH dashboard is available locally on HTTP, you can either browse to the Pi’s Tailscale IP directly or use Tailscale Serve.
To expose a local dashboard through Tailscale Serve, use a command in the form documented by Tailscale Serve examples, pointing at the local dashboard URL.[cite:60][cite:79][cite:82]
A typical pattern is:bash
sudo tailscale serve https / http://127.0.0.1:80
Adjust the local port if your DOH dashboard uses a different one.[cite:79][cite:82]
14. Apply a grants-based Tailscale policy
Tailscale’s documentation says grants are the newer recommended policy model, while ACLs are the original network-layer approach.[cite:105][cite:80]
A practical grants-based policy for a hotspot is:json
{
"tagOwners": {
"tag:hotspot": ["your-email@example.com"]
},
"grants": [
{
"src": ["autogroup:member"],
"dst": ["tag:hotspot"],
"ip": ["tcp:80", "tcp:8080"]
},
{
"src": ["group:admin"],
"dst": ["tag:hotspot"],
"ip": ["tcp:22"]
}
],
"ssh": [
{
"action": "check",
"src": ["group:admin"],
"dst": ["tag:hotspot"],
"users": ["pi"]
}
]
}
The tailnet policy file uses HuJSON syntax, supports grants and SSH rules, and can be used to limit dashboard and SSH access to only the identities you choose.[cite:86][cite:87][cite:105]
Apply the tag to the Pi with:bash
sudo tailscale up --ssh --advertise-tags=tag:hotspot
Tailscale tags let you assign a device a role-based identity, which works well for a server-like hotspot rather than a user-owned endpoint.[cite:97][cite:100]
15. Final security checklist
Do not forward the DOH dashboard directly on your router.[cite:16]
Keep the hotspot reachable only from your Tailscale devices.[cite:60][cite:77]
Use Tailscale SSH or restricted SSH access for administration.[cite:87][cite:90]
Use `journalctl -u doh -f` to monitor the service after changes.[cite:16]
Keep Raspberry Pi OS, DOH, and Tailscale updated regularly.[cite:16][cite:73]
16. Troubleshooting
The modem does not key up
Verify the modem port, confirm serial is enabled, and prefer `/dev/serial0` for a Pi 3B header-connected modem rather than assuming `/dev/ttyAMA0`.[cite:37][cite:38]
The dashboard does not open on `hostname.local`
Install and start Avahi, or use the Pi’s LAN IP directly.[cite:16]
The dashboard works locally but not remotely
Confirm the Pi is online in Tailscale, verify the grants policy, and check whether Tailscale Serve is pointing to the correct local URL.[cite:60][cite:77][cite:79]
Tailscale SSH does not work
Confirm you used `sudo tailscale up --ssh`, and make sure the tailnet policy file includes both network access and SSH rules for the hotspot device.[cite:87][cite:90]
17. Maintenance commandsbash
sudo apt update \&\& sudo apt full-upgrade -y
cd \~/doh \&\& git pull \&\& make \&\& sudo make install
sudo update-dmrid
sudo systemctl restart doh
tailscale status
tailscale ip -4
```
These commands update the OS, rebuild DOH from the latest source, refresh the DMR ID table, restart the hotspot service, and confirm Tailscale connectivity.[cite:16][cite:73][cite:97]