Pleroma on the Raspberry Pi 3 - wimvanderbauwhede/limited-systems GitHub Wiki

Pleroma on the Raspberry Pi 3

This is a little guide a wrote for myself when setting up Pleroma on my Raspberry Pi 3.

The Raspberry Pi is a very popular Arm-based system that runs Linux. The Pi 3 model B+ has a quad-core Arm Cortex-A53 CPU and 1GB or memory.

Raspberry Pi 3 board

Summary

  • Building and setting up Pleroma is straightforward, I followed the Pleroma guide for Debian based systems. For Pleroma you need Elixir, and the instructions for installing it on the Pi are a little bit different than in the Pleroma guide for Debian, see below.
  • Usually you would set up and test Pleroma on a local port as a first step.
  • But Pleroma only federates if you have a proper domain for your instance, and most ISPs don't allow that for ordinary users. So you need to arrange some form of dynamic DNS. I used FreeMyIP, see below.
  • Typically your home router will have a firewall, so you'll have to make sure people can talk to it from the outside. If you have an Apple Airport this is very easy using the Airport Utility.
  • You need to sort out encryption certificates for your domain, I used LetsEncrypt, see below.
  • I use a different subdomains, e.g. for Pleroma and Mastodon, each with their own certificates. Because I have only one external IP address I can't run both at the same time.

Getting started on the Raspberry Pi 3

The easiest way to get started is to connect a display, keyboard and mouse. With the default image, the Pi will boot straight in to a graphical desktop. It will also automatically find your WiFi. You can then do some basic admin like enabling VNC, setting up wired Ethernet access and creating extra accounts.

Make sure that the Raspbian on your Pi is up-to-date:

    $ sudo apt update
    $ sudo apt full-upgrade

Modify the files /etc/apt/sources.list and /etc/apt/sources.list.d/raspi.list In both files, change every occurrence of the word stretch to buster

    $ sudo apt update
    $ sudo apt -y dist-upgrade

After doing this, the distro is Buster:

    $ cat /etc/os-release
    PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"

Alternatively, you can do a fresh install using rpi-imager. First download the .deb, and install it:

    $ sudo apt install ./

Then run it

    $ rpi-imager

I selected Raspberry Pi OS Lite because to run a Pleroma server I don't need a desktop.

After the installation, this version boots to a login prompt. If you have a display and keyboard connected, yYou can login with user pi, password raspberry. The pi user has sudo.

Headless access

Because I want to run the Pi as a server, I set it up headless, so no need for a display or keyboard.

  • put a file called "ssh" in the "boot" directory

  • put a file called "wpa_supplicant.conf" in the "boot" directory, as explained in the docs:

      country=your ISO 2-character country code (e.g. GB for me)
      update_config=1
      ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
      
      network={
           ssid="your SSID"
           psk="your password in plaintext"
           key_mgmt=WPA-PSK
      }
    

Reboot and you can now ssh into the pi over wifi.

Update and upgrade again to get the latest version:

    $ sudo apt update
    $ sudo apt upgrade

The Linux kernel is now:

    Linux rpi 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l GNU/Linux

This is advertised on log in or you can run uname -a to get this information.

Accounts

Apart from the default pi account, I created another account for key-based ssh access and disallowed ssh access for all other users:

    $ adduser wim

Edit /etc/ssh/sshd_config:

AllowUsers wim
DenyUsers pi pleroma

(the user pleroma will be created during setup of pleroma)

$ sudo systemctl restart ssh

I allowed sudo access for convenience.

IP Setup for wired access

If it is for some reason not possible to create a fixed IP for WiFi access to your Pi you can use wired access. I set up the eth0 interface with a fixed IP of 192.168.x.y.

dhcpcd.conf:static ip_address=192.168.x.y/24
hosts:192.168.x.y	rpi
hosts:192.168.x.y	rpi.limited.systems

Installing Pleroma

Installing Elixir

For Pleroma you need Elixir and Erlang (on which Elixir is based). To install these on the Pi, get the .deb files from Erlang Solutions and install them:

    $ sudo apt install ./elixir_1.8.1-1~raspbian~stretch_armhf.deb
    $ sudo apt install ./esl-erlang_22.1.6-1~raspbian~buster_armhf.deb

After installation you should see:

    $ elixir -v
    Erlang/OTP 21 [erts-10.2.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1]

    Elixir 1.8.1 (compiled with Erlang/OTP 20)

Building and setting up Pleroma

Building and setting up Pleroma is also straightforward, I followed this guide. I ran into a few hitches:

  • During the step to generate the configuration by running sudo -Hu pleroma mix pleroma.instance gen, compiling majic failed due to a linker error. This is because the ei Erlang library is linked in the wrong order. To fix this:
    cd deps/majic
    sudo -Hu pleroma cc -I/usr/lib/erlang/usr/include -I/usr/local/include -std=c99 -g -Wall -Werror -DEI_INCOMPLETE -L/usr/lib/erlang/usr/lib -L/usr/local/lib src/libmagic_port.c -lpthread -lei -lm -lmagic -lerl_interface -lei -o priv/libmagic_port 
    cd ../..

and re-run sudo -Hu pleroma mix pleroma.instance gen

  • Another hitch:
    ** (Mix) You're trying to run :pleroma on Elixir v1.8.1 but it has declared in its mix.exs file it supports only Elixir ~> 1.9

I simply edited mix.exs and changed 1.9 to 1.8, and all was well.

  • A final, minor hitch:
    Compilation failed due to warnings while using the --warnings-as-errors option

There are in fact lots of warnings. To make them non-fatal, tell the build system we're in production mode rather than development:

    sudo -Hu pleroma MIX_ENV=prod mix pleroma.instance gen

Configuration

  • The configuration for Pleroma is, for development mode, in config/dev.exs which includes config/dev.secret.exs or, for production mode, config/prod.exs which includes config/prod.secret.exs.

  • To generate the secret key secret_key_base you can run the command

    pleroma@rpi:~/pleroma $ mix phx.gen.secret
    

    This will print a key which you can copy and paste into secret_key_base: "..."

  • By default, Pleroma runs in development mode. To use production mode,

    pleroma@rpi:~/pleroma MIX_ENV=prod mix phx.server
    
  • After running my instance for a while I noticed that I often got server errors on fetching of notifications. So I doubled the timeouts for Ecto.Adapters.Postgres, that seems to be enough:

    config :pleroma, Pleroma.Repo,
      adapter: Ecto.Adapters.Postgres,
      username: "...",
      password: "...",
      database: "...",
      hostname: "localhost",
      pool_size: 10,
      timeout: 30_000,
      connect_timeout: 10_000,
      pool_timeout: 10_000
    

Making your instance visible from the internet

To make the Pi visible from the internet, you need to open a hole in your firewall, usually this means on your WiFi router.

Change firewall settings

  • I set the Pi WiFi internal IP to 10.0.x.y fixed using the MAC address of the wlan0 interface. The Pi will use this automatically.
  • I opened port 443 (SSL) for the Pi

Update Pi hosts file (optional)

  • I added the fixed IP to /etc/hosts, this is actually not needed for Mastodon or Pleroma.
root@rpi:/etc# grep -r 10.0.x.y
hosts:10.0.x.y	rpi
hosts:10.0.x.y	rpi.limited.systems

To get external IP and Dynamic DNS:

I use freemyip.com. You just register a subdomain, e.g. pleroma.freemyip.com. When you claim the domain you get a unique token $MY_TOKEN. To bind the domain to the IP address of the Pi, I use a script with the following commands:

#!/usr/bin/env bash
# Find your external IP address
MY_IP=`dig +short myip.opendns.com @resolver1.opendns.com`
# Bind it to your domain
curl "https://freemyip.com/update?token=$MY_TOKEN&domain=pleroma.freemyip.com&myip=$MY_IP"

I created a service on the Pi to renew dynamic DNS, see the repo.

So now you can access your Pleroma instance via this domains. But this is not good enough because you can't get an SSL certificate for this domain, you need to use a domain that you own for that purpose.

Setting up a domain

I used Tsohost as provider for my domain, but this should be similar for other providers. I bought the domain limited.systems.

I added the domain rpi.limited.systems as follows:

Name Type Content
...
rpi.limited.systems CNAME pleroma.freemyip.com

Getting an SSL certificate

Like almost everybody else nowadays, I use LetsEncrypt.

Encryption via LetsEncrypt

Once you have your domain bound to your public-facing IP address, you can use LetsEncrypt to get a certificate.

I installed the letsencrypt tool, shut down nginx and generated a certificate:

  $ sudo apt-get install letsencrypt
  $ service nginx stop
  $ letsencrypt certonly --standalone -d rpi.limited.systems

Note that LetsEncrypt needs port 80 (http) to be open on your firewall because it will ask nginx to serve a file over http during the process of getting the certificates.

Final Note

My Raspberry Pi instance is rather ephemeral.