Self-hosting a Snac ActivityPub Server with a Raspberry Pi and Caddy

2026-06-07 20:13

TLDR - I'm back on the fediverse - @zkbro@pub.zkbro.com - using a self-hosted instance of snac.

I came across Jeff Sikes' Installing Snac - A Minimalist ActivityPub Server post. I hadn't heard of snac before, but a minimalist, lightweight, small footprint and simple architecture piece of software sounded about how I wanted to return to the fediverse.

Not only that, SNAC is an acronym for "social networks are crap". I love this tongue-in-cheek stab at socials, given snac itself is a social network tool. I've also joined an IRC network recently where the main channel is #antisocial. They are not anti-social. It's just good humour. I'm actually not against socials. I just don't like how the bigwigs operate, so I stay clear of them, and I have some social anxiety that is on me. I think owning a website with personal notes, blogs, logs, or whatever you want to call them, is part of social networking too. Add is RSS, linkrolls, blogrolls, reply posts, emailing, comments, likes and boosts... that's a lot of interaction... you get the point.

But I like the smaller spaces, and smaller alternative software. Hosting my own ActivityPub server with snac, I can control how much I federate, making it as tiny as I like. Only relay hashtags and individuals I subscribe to appear in my feed. This keeps it nice and cosy.

I also just like to try new tools, and go through the process of installing and tweaking them.

I am using snac as a single-user server on my Raspberry Pi 4 running Debian 12 Bookworm. It could be used for multiple users if I wish. Caddy is handling reverse proxies and TLS certificates.

Installation

Install dependencies:

sudo apt install libssl-dev libcurl4-openssl-dev

Install snac:

git clone https://codeberg.org/grunfink/snac2.git
cd snac2
make && make install

Initiate and configure

snac init $HOME/snac

Set up an "A + Dynamic DNS" record in my domain register for pub.zkbro.com. Copy current public IP address into the field.

Update ddclient at /etc/ddclient.conf with the new subdomain, appending pub.zkbro.com to the last line.

Restart the service and force an update to load in the new subdomain:

sudo systemctl restart ddclient.service --force

Allow port 8001 in ufw, or whatever port you choose:

sudo ufw allow 8001
sudo ufw reload

Set up a reverse proxy in Caddy:

sudo nano /etc/caddy/Caddyfile

Add in:

pub.zkbro.com {
  reverse_proxy localhost:8001
  log {
    output file /var/log/pub.log
    format json
  }
  encode gzip
}

Then:

sudo systemctl restart caddy

Copy web interface language files into snac directory:

cp /path/to/repo/po/en.po ~/snac/lang/

This means you can choose your interface language from a dropdown (though it defaulted to English anyway, so not sure if I actually need this. Might help others when searching/filtering actors via language or something).

Add user:

snac adduser $HOME/snac zkbro

A password will be generated. Copy this down.

Add a systemctl service and run server:

sudo nano /etc/systemd/system/snac.service

Enter:

[Unit]
Description=snac ActivityPub Server
After=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/local/bin/snac httpd $HOME/snac
Restart=always

[Install]
WantedBy=multi-user.target  
sudo systemctl daemon-reload
sudo systemctl enable snac.service
sudo systemctl start snac.service
sudo systemctl status snac.service ## check

Now, pub.zkbro.com is up and running. For my user account (zkbro) I just go to pub.zkbro.com/zkbro and login via the private button and I can start using it.

Adding relays

These are for discovery. Other fediverse servers relay their user's feeds through these. When my user zkbro subscribes to #hashtags, it will pull any post with said #hashtag from these relays into my main feed.

On snac we add a special "relay" user and this user subscribes to relays. I am using the fedi.buzz relay endpoints. This bit is a bit confusing to me. I think by using fedi.buzz it reduces load on my own server. I think I could potentially add instance relays directly into snac, but I couldn't figure that out. So... I follow a bunch of instances via the relay user, which means I can focus on #hashtags at the actual user level.

snac adduser $HOME/snac relay
snac follow $HOME/snac relay https://relay.fedi.buzz/instance/mountains.social
snac follow $HOME/snac relay https://relay.fedi.buzz/instance/infosec.exchange
snac follow $HOME/snac relay https://relay.fedi.buzz/instance/mapstodon.space
snac follow $HOME/snac relay https://relay.fedi.buzz/instance/indieweb.social
snac follow $HOME/snac relay https://relay.fedi.buzz/instance/hachyderm.io
etc...

Now any #hashtags I'm subscribed to will come from those servers.

In summary

All in all my setup was pretty straight forward. I had done a few steps in other self-hosting projects so what used to cause me a headache is now a bit more familiar:

  • creating new subdomains on my DNS provider
  • auto updating dynamic DNS records with ddclient
  • creating a systemctl systemd daemon service
  • using Caddy to handle reverse proxies

More specific to snac, I have only done some basic configuration and added a few relays. The default ~/snac/server.json configuration file remains relatively untouched, though I made a couple tweaks regarding how long before posts are purged/removed, and shortened the duration of how long the relayed instance posts stay live.

I do like the simple style of the web interface, however I may set up tut TUI as I sometimes prefer to be in the terminal.

For now though, I'll start to follow some folk and hashtags and try to interact a little.