Piehnat

04 Dez, 2025

Mastodon auf dem Raspberry Pi hosten

Gestern kam die Frage von jemandem, der offensichtlich Bock auf eine eigene Mastodon-Instanz hat, ob das auf einem Raspberry Pi geht. Er hat einfach die Schnauze voll von Twitter & Co., will sich aber auch auf keiner bestehenden Mastodon-Instanz anmelden, bei der er völlig dem Betreiber ausgeliefert ist und jederzeit abgeschossen werden könnte.

Einen V-Server mieten? Keine Chance, will er nicht. Stattdessen wollte er wissen, ob das Ganze auf einem Raspberry Pi zu Hause machbar ist. Da ich selbst keines dieser Netzwerke nutze, also auch keine Erfahrungen damit habe, dachte ich mir, probiere ich es einfach mal aus und dokumentiere das Ganze hier, damit er alles Schritt für Schritt nachlesen kann.

Was du brauchst

  • Raspberry Pi 4 mit mindestens 4 GB RAM (2 GB geht nur mit Swap-Tricks, Performance leidet)
  • SSD empfohlen, SD-Karte geht, aber nur hochwertige z. B. Samsung Pro Endurance; überwache Gesundheit mit smartctl oder fsck
  • Domain/Subdomain, die auf deine öffentliche IP zeigt
  • Routerzugang für Portforwarding (80 und 443)
  • SSH-Zugang und Basiskenntnisse für Terminalbefehle

Optional, aber stark empfohlen:

  • DynDNS (z. B. duckdns) für wechselnde IP
  • SSH-Key für sicheren Zugriff
  • Backup-Speicher extern (Festplatte/NAS/Cloud)

Schritt 1: Raspberry Pi OS Lite installieren

    1. Raspberry Pi OS Lite auf SD-Karte oder SSD schreiben (Raspberry Pi Imager).
    2. Pi starten, per SSH einloggen:
      ssh pi@raspberrypi.local
    3. Alles updaten und Grundpakete installieren:
      sudo apt update
      sudo apt upgrade -y
      sudo apt install -y git curl wget ca-certificates unzip nano ufw fail2ban
    4. Nach Kernel-Updates reboot:
sudo reboot
  1. Swap erhöhen bei 2 GB RAM (optional):
    sudo dphys-swapfile swapoff
    sudo sed -i 's/CONF_SWAPSIZE=.*/CONF_SWAPSIZE=2048/' /etc/dphys-swapfile
    sudo dphys-swapfile setup
    sudo dphys-swapfile swapon
  2. Statische IP einstellen (Beispiel für /etc/dhcpcd.conf):
    interface eth0
    static ip_address=192.168.1.100/24
    static routers=192.168.1.1
    static domain_name_servers=1.1.1.1 8.8.8.8

Schritt 2: Docker & Docker Compose installieren

  1. Docker installieren:
    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    sudo usermod -aG docker $USER

    Hinweis: danach abmelden und wieder anmelden oder SSH neu starten.

  2. Docker Compose Plugin installieren:
    sudo apt install -y docker-compose-plugin
  3. Prüfen:
    docker --version
    docker compose version
    docker info

    Falls docker info meckert:

    sudo systemctl restart docker

Schritt 3: Mastodon-Verzeichnis & Code klonen

  1. Verzeichnis erstellen:
    sudo mkdir -p /srv/mastodon
    sudo chown $USER:$USER /srv/mastodon
    cd /srv/mastodon
  2. Mastodon-Code klonen und stabile Version nutzen:
    git clone https://github.com/mastodon/mastodon.git .
    git checkout v4.3.0

Schritt 4: Docker Compose Datei erstellen

docker-compose.yml anlegen:

nano docker-compose.yml

Inhalt:

version: '3.3'

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: mastodon
      POSTGRES_PASSWORD: mastodon
      POSTGRES_DB: mastodon
    volumes:
      - ./postgres:/var/lib/postgresql/data
    restart: always

  redis:
    image: redis:7
    command: redis-server --save 60 1 --loglevel warning
    volumes:
      - ./redis:/data
    restart: always

  web:
    build: .
    env_file: .env.production
    command: bundle exec puma -C config/puma.rb
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
    volumes:
      - ./public/system:/mastodon/public/system
    restart: always

  streaming:
    build: .
    env_file: .env.production
    command: node ./streaming/index.js
    ports:
      - "4000:4000"
    depends_on:
      - db
      - redis
    restart: always

  sidekiq:
    build: .
    env_file: .env.production
    command: bundle exec sidekiq
    depends_on:
      - db
      - redis
    volumes:
      - ./public/system:/mastodon/public/system
    restart: always

Schritt 5: .env.production anlegen & konfigurieren

  1. Datei kopieren:
    cp .env.production.sample .env.production
    nano .env.production
  2. Wichtige Anpassungen:
    LOCAL_DOMAIN=deinedomain.de
    WEB_DOMAIN=deinedomain.de
    
    DB_HOST=db
    DB_USER=mastodon
    DB_NAME=mastodon
    DB_PASS=supergeheim
    
    REDIS_HOST=redis
    
    SMTP_SERVER=smtp.deinmailanbieter.example
    SMTP_PORT=587
    SMTP_LOGIN=deinlogin
    SMTP_PASSWORD=deinapppasswort
    SMTP_FROM_ADDRESS=no-reply@deinedomain.de
  3. Keys generieren:
    docker compose run --rm web rake secret
    docker compose run --rm web rake mastodon:webpush:generate_vapid_key
  4. Datei schützen:
    chmod 600 .env.production

    Hinweis: Keys niemals öffentlich speichern; Passwort-Manager oder verschlüsselte Datei verwenden.

  5. SMTP-Hinweis: Bei Gmail App-Passwort nutzen oder „Unsichere Apps“ aktivieren.

Schritt 6: Mastodon bauen & Setup

  1. Build starten:
    docker compose build
    sudo chown -R 991:991 public
  2. Setup ausführen (Admin anlegen, DB-Tabellen erstellen):
    docker compose run --rm web bundle exec rake mastodon:setup
  3. Container starten:
    docker compose up -d

    Tipp: Build dauert auf Pi 4 gerne 1–2 Stunden. Kaffee holen.

Schritt 7: Reverse Proxy & HTTPS (Caddy)

  1. Caddy installieren:
    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add -
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
    sudo apt update
    sudo apt install -y caddy
  2. Caddyfile erstellen:
    sudo nano /etc/caddy/Caddyfile

    Beispielinhalt:

    deinedomain.de {
        reverse_proxy localhost:3000
        @notls {
            protocol http
        }
        redir @notls https://{host}{uri}
        limit_rps 100
    }
  3. Reload:
    sudo systemctl reload caddy
  4. Router: Ports 80 & 443 (IPv4 und IPv6) weiterleiten.

Schritt 8: Firewall & Sicherheit

  1. UFW konfigurieren:
    sudo ufw allow 2222/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable
  2. Fail2Ban aktivieren:
    sudo systemctl enable fail2ban
    sudo systemctl start fail2ban
  3. Beispiel Jail für Mastodon-Logs:
    [mastodon]
    enabled = true
    filter = mastodon
    logpath = /srv/mastodon/log/*.log
    maxretry = 3
    bantime = 1h

Schritt 9: Backups

  • Datenbank komprimiert sichern:
    docker compose exec db pg_dump -U mastodon mastodon | gzip > /srv/mastodon/backups/backup-$(date +%F).sql.gz
  • Medien sichern:
    tar czf /srv/mastodon/backups/media_backup_$(date +%F).tar.gz public/system
  • Cronjob für tägliche Backups:
    crontab -e
    0 3 * * * docker compose exec db pg_dump -U mastodon mastodon | gzip > /srv/mastodon/backups/backup-$(date +\%F).sql.gz
  • Offsite-Backup mit rclone:
    rclone copy /srv/mastodon/backups remote:backups/mastodon/

Schritt 10: Updates & Wartung

cd /srv/mastodon
git pull
docker compose build
docker compose run --rm web bundle exec rails db:migrate
docker compose up -d
docker system prune -f

Hinweis: Docker-Prune nur ausführen, wenn alle Container laufen. Downtime kurz, ggf. Nutzer vorher informieren.

Schritt 11: Häufige Fehler

  • Styles fehlen → Domain in .env.production prüfen
  • Build-Abbruch → RAM, evtl. docker compose build --no-cache oder auf stärkerem Rechner bauen
  • Logs wachsen → Logrotation:
    /srv/mastodon/log/*.log {
        daily
        missingok
        rotate 7
        compress
        delaycompress
        notifempty
        create 644 mastodon mastodon
    }
  • Mailversand → SMTP prüfen, App-Passwort nötig

Schritt 12: Sicherheit & Monitoring

  • HTTPS erzwingen (Admin)
  • Rate-Limiting in Caddy (siehe oben)
  • Monitoring mit netdata:
    bash <(curl -Ss https://my-netdata.io/kickstart.sh)
    # Zugriff lokal: http://deine-ip:19999

Schritt 13: Fediverse-Kompatibilität

curl https://deinedomain.de/nodeinfo/2.0
curl https://deinedomain.de/.well-known/webfinger?resource=acct:admin@deinedomain.de

Wenn das nicht klappt: Domain, HTTPS-Zertifikat, Port 443 prüfen.

Schritt 14: Rechtliches

  • Impressum Pflicht, Beispiel:
    <p>Verantwortlich für diese Instanz:<br>
    Max Mustermann<br>
    Musterstraße 1<br>
    12345 Musterstadt<br>
    E-Mail: admin@deinedomain.de</p>
  • DSGVO beachten
  • Urheberrecht bei Medieninhalten beachten

Schritt 15: Erste Schritte nach Installation

  1. Als Admin einloggen → /admin
  2. HTTPS erzwingen
  3. Registrierung aktivieren (falls erwünscht)
  4. Mailversand testen:
    docker compose logs web | grep 'SMTP'
  5. Freunde einladen und eigene Social-Media-Blase starten

3 Kommentare

    1. Habe ich versucht, aber um es mit seinen Worten auszudrücken „Wenn schon, dann will ich den vollen Funktionsumfang, keine abgespeckte Version mit Einschränkungen“. Machste nix.

Hinterlasse einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind mit * markiert. Deine Daten werden ausschließlich lokal gespeichert.