return to title

Snac2 (or Snac) lightweight ActivityPub server

Date: 2024-11-22
Tags: ActivityPub, Mastodon, sysadmin

Snac2 is a lightweight ActivityPub server, it rely on SQLite DB by user and files on disks, that's all. Don't overgrow like some other servers (Pleroma). It is wrote in C language without unfinite libs dependency, so fast, reliable, not a myriad on unreliable/unmaintained/backdoored language modules.

For reference, installed size of Arch Linux binary (daemon and command) for release 2.64 is:

So this can run coupled with nginx on a really light Solar Powered SBC (There are a lot of very efficient and cheap ARM or RISC-V SBC available now).

ArchLinux

Snac2 is available as AUR package on ArchLinux:

yay -S snac

Its better to use a specific/dedicated user for the daemon and instances. I create an user called snac for this example. You need to give him the rights to launch own user systemd service

useradd --create-home snac
loginctl enable-linger snac

Choose your unguessable long password, add the ssh key

mkdir ~snac/.ssh
cat $mypubkey >~snac/.ssh/authorized_keys

Connect to the user via ssh (sudo will not work for lauching the deamon via systemd, I call my instance snac too here, but can be unrelated to username.

ssh snac@127.0.0.1
snac init ~snac/snac
snac adduser ~snac/snac
mkdir -p ~snac/.config/snac/
echo "SNAC_DATA=${HIME}/snac" >~snac/.config/snac/snac.conf
systemctl --user start snac

If everything works fine, ensure daemon will still be launched after reboot

systemctl --user enable snac

Nginx rules

Here is the case for HTTP/2, you could want to enable HTTP/3 too depending on the state and version of nginx you use

I've a brotli+nginx compression directives file called compress.conf, that I reuse inside server {} directive:

# compressing for brotli (you need to have the brotli module patch
brotli on;
# default 20
#brotli_min_length     20;
#brotli_proxied        expired no-cache no-store private auth;
brotli_buffers        32 4k;
brotli_static         on;
# text/html is always compressed with nginx (see http_zip_module doc)
brotli_types          text/plain text/css application/wasm application/x-tic80-item;
brotli_types          text/xml application/xml application/xhtml+xml application/json;
brotli_types          application/rss+xml application/atom_xml;
brotli_types          text/javascript application/javascript application/x-javascript;
brotli_types          application/x-httpd-php application/x-httpd-fastphp application/x-httpd-eruby;
brotli_types          image/svg+xml application/vnd.ms-excel;
brotli_types          x-shader/x-fragment x-shader/x-geometry x-shader/x-vertex;

gzip  on;
gzip_min_length     500;
gzip_proxied        expired no-cache no-store private auth;

# text/html is always compressed with nginx (see http_zip_module doc)
gzip_types          text/plain text/css application/wasm application/x-tic80-item;
gzip_types          text/xml application/xml application/xhtml+xml application/json;
gzip_types          application/rss+xml application/atom_xml;
gzip_types          text/javascript application/javascript application/x-javascript;
gzip_types          application/x-httpd-php application/x-httpd-fastphp application/x-httpd-eruby;
gzip_types          image/svg+xml application/vnd.ms-excel;
gzip_types          x-shader/x-fragment x-shader/x-geometry x-shader/x-vertex;

Ths can be tested with curl by using:

 curl -I  -H 'Accept-Encoding: gzip, deflate, br' https://www.websitename.com/file.txt
# media cache, can improve a bit performances.
proxy_cache_path /tmp/snac2-media-cache levels=1:2 keys_zone=snac2_media_cache:10m max_size=10g
                 inactive=720m use_temp_path=off;

server {
  listen 443 ssl;
  server_name snac2.popolon.org;
  http2 on;

  include "rules/compress.conf";
  # the nginx default is 1m, not enough for large media uploads tune depending on your needs
  client_max_body_size 16m;

  location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # this is explicitly IPv4 since Snac2.Web.Endpoint binds on IPv4 only
    # and `localhost.` resolves to [::0] on some systems: see issue #930
    proxy_pass http://127.0.0.1:8001;

    client_max_body_size 16m;
  }
  location ~ ^/(media|proxy) {
    proxy_cache        snac2_media_cache;
    slice              1m;
    proxy_cache_key    $host$uri$is_args$args$slice_range;
    proxy_set_header   Range $slice_range;
    proxy_http_version 1.1;
    proxy_cache_valid  200 206 301 304 1h;
    proxy_cache_lock   on;
    proxy_ignore_client_abort on;
    proxy_buffering    on;
    chunked_transfer_encoding on;
    proxy_pass         http://127.0.0.1:4001;
  }

  #Administration pages are limited to some IP address for security concern
  location ~ ^/.*/admin/ {
    allow $my_public_ip
    deny all;

    proxy_cache        snac2_media_cache;
    slice              1m;
    proxy_cache_key    $host$uri$is_args$args$slice_range;
    proxy_set_header   Range $slice_range;
    proxy_http_version 1.1;
    proxy_cache_valid  200 206 301 304 1h;
    proxy_cache_lock   on;
    proxy_ignore_client_abort on;
    proxy_buffering    on;
    chunked_transfer_encoding on;
    proxy_pass         http://127.0.0.1:8001;
  }
}
nginx -t
systemctl reload nginx.service
``` 
You shold now be able connect to your account with the URL/account given 


## Available man pages

```bash
man snac2    # Describe Web interface and command line options
man 5 snac2  # Message formatting and file format documentation
man 8 snac2  # Administration: How to build it, server parameters, migration between Mastodon and Snac

When installing the package for first time, advices

Remember that you must create snac configuration before first run.

To run with system unit:

snac init /var/lib/snac

To run with user unit (note that SNAC_DATA can point to wherever you want):

mkdir -p ~/.config/snac/
echo "SNAC_DATA=/home/user/.local/share/snac" > ~/.config/snac/snac.conf
snac init /home/user/.local/share/snac
Tags: ActivityPub, Mastodon, sysadmin