Mastodon relays are servers that forward public posts from one instance to many others, boosting federation visibility without manual follows. If your small Mastodon instance struggles to discover content from other servers, a relay can pull in posts automatically. This guide explains how to set up a Mastodon-compatible relay on a Raspberry Pi 4 or 5 running Raspberry Pi OS. By the end, you will have a working relay that your instance and others can subscribe to.
Key Takeaways: Setting Up a Mastodon Relay on Raspberry Pi
- Pub-Relay software: The open-source relay server that forwards public posts between Mastodon instances.
- Raspberry Pi 4 or 5 with 4 GB RAM: Minimum hardware requirement for handling moderate relay traffic.
- Nginx reverse proxy: Handles TLS termination and forwards requests to the relay service running on port 8080.
- systemd service file: Ensures the relay starts automatically on boot and restarts on failure.
Why Run a Mastodon Relay on a Raspberry Pi
A Mastodon relay collects public posts from all connected instances and redistributes them to every subscriber. This means your instance sees posts from many servers without manually following each one. Running a relay on a Raspberry Pi keeps your federation independent from third-party relay operators who may shut down or change policies. The Raspberry Pi consumes under 10 watts of power, making it a low-cost, always-on server for this task. The official reference relay software is Pub-Relay, written in Python and designed to work with the ActivityPub protocol.
Hardware Requirements
A Raspberry Pi 4 or 5 with at least 4 GB of RAM is recommended. The relay process uses about 500 MB to 1 GB of memory with a few dozen connected instances. Storage needs are minimal because the relay does not store posts permanently — it only caches them briefly during forwarding. A 32 GB microSD card or an external SSD is sufficient. A static IP address or a dynamic DNS service is required so instances can reach your relay.
Software Stack
The relay runs on Python 3.9 or later. Nginx serves as a reverse proxy to handle HTTPS certificates from Let’s Encrypt. The relay listens on port 8080 internally, and Nginx forwards external HTTPS traffic on port 443 to that internal port. Git is used to clone the Pub-Relay repository.
Steps to Install and Configure the Mastodon Relay
Follow these steps on a fresh Raspberry Pi OS installation (Debian Bookworm or later). You need sudo access and a domain name pointing to your Pi’s public IP address.
- Update system packages and install prerequisites
Runsudo apt update && sudo apt upgrade -y. Then install Python 3, pip, git, and Nginx withsudo apt install python3 python3-pip git nginx certbot python3-certbot-nginx -y. - Clone the Pub-Relay repository
Rungit clone https://github.com/glitch-soc/mastodon-relay.git /opt/relay. This places the relay code in the/opt/relaydirectory. - Create a Python virtual environment and install dependencies
Runcd /opt/relay && python3 -m venv venv && source venv/bin/activate && pip install -r requirements.txt. The virtual environment isolates the relay’s Python packages from the system. - Create a configuration file
Copy the example config:cp config.py.example config.py. Edit the file withnano config.py. ChangeRELAY_PORTto8080. SetRELAY_DOMAINto your domain name (for example,relay.example.com). SetPUBLIC_RELAYtoTrueif you want any instance to subscribe without approval. Save the file. - Generate a secret key for the relay
Runpython3 -c "import secrets; print(secrets.token_hex(32))". Copy the output. Inconfig.py, setSECRET_KEYto that value. This key signs relay messages and prevents spoofing. - Set up the systemd service for automatic startup
Create a service file:sudo nano /etc/systemd/system/relay.service. Add the following content:[Unit]
Description=Mastodon Relay
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/opt/relay
ExecStart=/opt/relay/venv/bin/python /opt/relay/run.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetSave the file. Run
sudo systemctl daemon-reload && sudo systemctl enable relay && sudo systemctl start relay. - Configure Nginx as a reverse proxy
Create an Nginx site config:sudo nano /etc/nginx/sites-available/relay. Add the following:server {
listen 80;
server_name relay.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name relay.example.com;
ssl_certificate /etc/letsencrypt/live/relay.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/relay.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Replace
relay.example.comwith your actual domain. Enable the site withsudo ln -s /etc/nginx/sites-available/relay /etc/nginx/sites-enabled/. Remove the default site if it conflicts:sudo rm /etc/nginx/sites-enabled/default. Test the config withsudo nginx -tand reload withsudo systemctl reload nginx. - Obtain a TLS certificate with Certbot
Runsudo certbot --nginx -d relay.example.com. Follow the prompts to get a free Let’s Encrypt certificate. Certbot automatically updates the Nginx config. Verify the certificate renewal works withsudo certbot renew --dry-run. - Test the relay
Open a browser and go tohttps://relay.example.com. You should see a JSON response with relay information. If you see an error, check the relay logs withsudo journalctl -u relay -f.
Common Issues and Configuration Mistakes
Relay Returns a 502 Bad Gateway Error
This means Nginx cannot reach the relay process on port 8080. Check that the relay service is running with sudo systemctl status relay. If it is inactive, start it with sudo systemctl start relay. Verify that no other service is using port 8080 with sudo ss -tlnp | grep 8080.
Instances Cannot Subscribe to the Relay
The instance administrator must add the relay URL in the instance’s Admin panel under Federation > Relays. The URL must be the full HTTPS address, for example https://relay.example.com. If the relay is set to PUBLIC_RELAY = False, the instance will not be accepted automatically. Set PUBLIC_RELAY = True in config.py and restart the relay with sudo systemctl restart relay.
Posts Are Not Appearing After Subscribing
The relay only forwards public posts from instances that are themselves subscribed to the relay. Each instance must have the relay added and enabled. After subscribing, wait up to 15 minutes for the first batch of posts to arrive. Check the relay logs with sudo journalctl -u relay -f for any connection errors.
Pub-Relay vs Manual Federation: Key Differences
| Item | Pub-Relay on Raspberry Pi | Manual Federation (Following Individual Instances) |
|---|---|---|
| Setup effort | Requires server configuration and domain | No additional server needed |
| Content discovery | Automatic — receives all public posts from connected instances | Requires manually following specific accounts or instances |
| Server load | Increases with number of connected instances | Load is on the instance’s own federation worker |
| Network bandwidth | Relay sends all public posts to every subscriber | Instance pulls only followed accounts’ posts |
| Control | Full control over relay policies (public or restricted) | Depends on instance admin’s follow policies |
The relay approach centralizes the federation stream, making it easier for small instances to see a broad range of content. Manual federation gives the instance admin finer control over which servers to follow but requires more active management.
You now have a self-hosted Mastodon relay running on your Raspberry Pi. Your instance can subscribe to this relay to pull in public posts from all other connected instances automatically. For better performance, consider moving the relay data to an external SSD instead of the microSD card. You can also enable PUBLIC_RELAY = True to allow any Mastodon instance to join without your approval.