Zum Inhalt springen

Installiere Paperless, pi-hole % Nextcloud auf einer Pi-hole

12. Juli 2025 durch
Mário Santiago

Raspberry Pi 5 Server Setup: Vollständige Anleitung für Homeserver mit Docker-Diensten

Einleitung und Voraussetzungen

Diese technische Anleitung beschreibt die vollständige Einrichtung eines Raspberry Pi 5 als Homeserver mit Docker-basierten Diensten. Das System wird als zentraler Server für Dokumentenverwaltung, Netzwerk-DNS, Cloud-Speicher und Reverse-Proxy-Funktionalität konfiguriert.

Hardware-Voraussetzungen

Erforderliche Hardware:

  • Raspberry Pi 5 (mindestens 4GB RAM, 8GB empfohlen)
  • 128GB microSD-Karte (Klasse 10 oder UHS-1, A2-Klasse bevorzugt)
  • Offizielles 27W USB-C PD Netzteil (5.1V @ 5A)
  • Aktive Kühlung empfohlen (Official Active Cooler)
  • Ethernet-Verbindung für optimale Performance

Netzwerk-Voraussetzungen:

Software-Übersicht

Installierte Dienste:

  • Paperless-ngx: Dokumentenverwaltung mit OCR-Funktionalität
  • Pi-hole: DNS-Sinkhole für Werbeblocker
  • Nginx: Reverse Proxy mit SSL-Terminierung
  • Nextcloud AIO: Cloud-Speicher und Kollaborationsplattform (optional)
  • noip-duc: Dynamische DNS-Updates
  • Docker: Container-Orchestrierung für alle Dienste

Grundinstallation

Raspberry Pi OS Installation

Schritt 1: Image-Erstellung

# Raspberry Pi Imager herunterladen von raspberrypi.com/software
# OS auswählen: "Raspberry Pi OS (64-bit)"
# Erweiterte Optionen konfigurieren:
# - SSH aktivieren
# - Benutzername/Passwort festlegen
# - WLAN-Zugangsdaten (optional)
# - Tastaturlayout: Deutsch

Schritt 2: Erstes System-Update

# Nach dem ersten Boot per SSH verbinden
sudo apt update && sudo apt upgrade -y

# Essenzielle Pakete installieren
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release htop vim git

# Zeitzone setzen
sudo timedatectl set-timezone Europe/Berlin

# Hostname ändern (optional)
sudo hostnamectl set-hostname pi5-server

Schritt 3: System-Optimierung

# GPU-Speicher reduzieren (headless System)
echo "gpu_mem=16" | sudo tee -a /boot/firmware/config.txt

# Swap vergrößern für Docker-Builds
sudo dphys-swapfile swapoff
sudo sed -i 's/CONF_SWAPSIZE=100/CONF_SWAPSIZE=1024/g' /etc/dphys-swapfile
sudo dphys-swapfile setup
sudo dphys-swapfile swapon

# Reboot für Änderungen
sudo reboot

Docker Installation

Offizielle Docker-Installation (empfohlen für 64-bit OS):

# Docker GPG-Schlüssel hinzufügen
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Repository hinzufügen
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Docker installieren
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Benutzer zur Docker-Gruppe hinzufügen
sudo usermod -aG docker $USER

# Neuanmeldung oder Reboot erforderlich
sudo reboot

Docker-Konfiguration optimieren:

# Log-Rotation für Docker konfigurieren
sudo tee /etc/docker/daemon.json > /dev/null <<EOF
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF

# Docker-Dienst aktivieren und starten
sudo systemctl enable docker
sudo systemctl restart docker

# Installation verifizieren
docker --version
docker compose version
sudo docker run hello-world

Dienste-Installation

Paperless-ngx Setup

Schritt 1: Projektstruktur erstellen

# Projektverzeichnis anlegen
mkdir -p ~/docker/paperless-ngx
cd ~/docker/paperless-ngx

# Benötigte Verzeichnisse erstellen
mkdir -p consume export

Schritt 2: Docker Compose Konfiguration

# docker-compose.yml erstellen
cat > docker-compose.yml << 'EOF'
version: "3.4"

services:
  broker:
    image: docker.io/library/redis:8
    restart: unless-stopped
    volumes:
      - redisdata:/data

  db:
    image: docker.io/library/postgres:17
    restart: unless-stopped
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: paperless

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
    ports:
      - "8000:8000"
    volumes:
      - data:/usr/src/paperless/data
      - media:/usr/src/paperless/media
      - ./export:/usr/src/paperless/export
      - ./consume:/usr/src/paperless/consume
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
      USERMAP_UID: 1000
      USERMAP_GID: 1000
    env_file:
      - docker-compose.env

  gotenberg:
    image: docker.io/gotenberg/gotenberg:8
    restart: unless-stopped
    command:
      - "gotenberg"
      - "--chromium-disable-javascript=true"
      - "--chromium-allow-list=file:///tmp/.*"

  tika:
    image: docker.io/apache/tika:latest-full
    restart: unless-stopped

volumes:
  data:
  media:
  pgdata:
  redisdata:
EOF

Schritt 3: Environment-Datei erstellen

# docker-compose.env erstellen
cat > docker-compose.env << 'EOF'
# Sicherheitseinstellungen
PAPERLESS_SECRET_KEY=change-this-to-a-secure-random-string-with-at-least-32-characters
PAPERLESS_URL=http://localhost:8000

# Admin-Benutzer
PAPERLESS_ADMIN_USER=admin
PAPERLESS_ADMIN_PASSWORD=change-this-password
PAPERLESS_ADMIN_MAIL=admin@localhost

# Raspberry Pi Optimierungen
PAPERLESS_WEBSERVER_WORKERS=1
PAPERLESS_TASK_WORKERS=1
PAPERLESS_THREADS_PER_WORKER=1

# OCR-Einstellungen für schwächere Hardware
PAPERLESS_OCR_MODE=skip
PAPERLESS_OCR_SKIP_ARCHIVE_FILE=with_text
PAPERLESS_OCR_CLEAN=none

# Erweiterte Dokumentenverarbeitung
PAPERLESS_TIKA_ENABLED=1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT=http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT=http://tika:9998

# Zeitzone
PAPERLESS_TIME_ZONE=Europe/Berlin

# Deutsche Spracheinstellungen
PAPERLESS_OCR_LANGUAGE=deu
PAPERLESS_OCR_LANGUAGES=deu eng
EOF

Schritt 4: Service starten

# Container starten
docker compose up -d

# Logs verfolgen
docker compose logs -f webserver

# Status prüfen
docker compose ps

Pi-hole Setup

Schritt 1: Pi-hole Verzeichnis erstellen

mkdir -p ~/docker/pihole
cd ~/docker/pihole

Schritt 2: Docker Compose Konfiguration

cat > docker-compose.yml << 'EOF'
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8080:80/tcp"
      - "8443:443/tcp"
    environment:
      TZ: 'Europe/Berlin'
      FTLCONF_webserver_api_password: 'Scroll#Vagabond9#Alumni#Chamber'
      FTLCONF_dns_listeningMode: 'all'
      FTLCONF_dns_upstreams: '8.8.8.8;8.8.4.4;1.1.1.1'
      PIHOLE_UID: 1000
      PIHOLE_GID: 1000
    volumes:
      - './etc-pihole:/etc/pihole'
    cap_add:
      - NET_ADMIN
      - SYS_TIME
      - SYS_NICE
    restart: unless-stopped
    dns:
      - 127.0.0.1
      - 8.8.8.8
EOF

Schritt 3: Pi-hole starten

# Container starten
docker compose up -d

# Logs verfolgen
docker compose logs -f pihole

# Web-Interface testen: http://PI_IP:8080/admin

Nginx Installation (nativ)

Schritt 1: Nginx installieren

# Apache entfernen (falls vorhanden)
sudo apt remove apache2 -y

# Nginx installieren
sudo apt install nginx -y

# Nginx aktivieren und starten
sudo systemctl enable nginx
sudo systemctl start nginx

# Installation verifizieren
nginx -v
sudo systemctl status nginx

Schritt 2: Firewall konfigurieren

# UFW installieren und konfigurieren
sudo apt install ufw -y
sudo ufw enable
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw status

Let’s Encrypt SSL-Zertifikate

Schritt 1: Certbot installieren

# Snapd installieren
sudo apt install snapd -y

# Alte Certbot-Versionen entfernen
sudo apt remove certbot python3-certbot-nginx -y

# Certbot über Snap installieren
sudo snap install --classic certbot

# Symlink erstellen
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Schritt 2: SSL-Zertifikat erstellen

# Voraussetzung: Domain muss auf Pi-IP zeigen
# Zertifikat mit automatischer Nginx-Konfiguration erstellen
sudo certbot --nginx -d ihre-domain.com -d www.ihre-domain.com

# Automatische Erneuerung testen
sudo certbot renew --dry-run

noip-duc DynDNS Setup

Schritt 1: noip-duc installieren

# Aktuelle Version herunterladen
cd ~/Downloads
wget --content-disposition https://www.noip.com/download/linux/latest
tar xf noip-duc_3.3.0.tar.gz
cd noip-duc_3.3.0/binaries

# Für ARM64 (Pi 5)
sudo apt install ./noip-duc_3.3.0_arm64.deb

Schritt 2: Konfiguration

# Konfigurationsdatei erstellen
sudo mkdir -p /etc/default
sudo tee /etc/default/noip-duc > /dev/null <<EOF
NOIP_USERNAME=ihr-username
NOIP_PASSWORD=ihr-password
NOIP_HOSTNAMES=ihre-domain.ddns.net
EOF

# Sicherheitsberechtigungen setzen
sudo chmod 600 /etc/default/noip-duc
sudo chown root:root /etc/default/noip-duc

Schritt 3: Systemd-Service einrichten

# Service aktivieren und starten
sudo systemctl daemon-reload
sudo systemctl enable noip-duc
sudo systemctl start noip-duc

# Status prüfen
sudo systemctl status noip-duc
sudo journalctl -u noip-duc -f

Nginx Reverse Proxy Konfiguration

Schritt 1: Reverse Proxy für alle Dienste

# Nginx-Konfiguration erstellen
sudo tee /etc/nginx/sites-available/homeserver > /dev/null <<'EOF'
server {
    listen 80;
    server_name ihre-domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name ihre-domain.com;
    
    ssl_certificate /etc/letsencrypt/live/ihre-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ihre-domain.com/privkey.pem;
    
    # SSL-Sicherheitskonfiguration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    
    # Sicherheitsheader
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    
    # Paperless-ngx
    location /paperless/ {
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
    
    # Pi-hole Admin
    location /pihole/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
    
    # Nextcloud (falls installiert)
    location /nextcloud/ {
        proxy_pass http://127.0.0.1:11000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        
        # Nextcloud-spezifische Headers
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Forwarded-Server $host;
        proxy_max_temp_file_size 0;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 300;
        proxy_buffering off;
    }
    
    # Standard-Weiterleitung zu Paperless
    location / {
        return 301 https://$server_name/paperless/;
    }
}
EOF

Schritt 2: Konfiguration aktivieren

# Site aktivieren
sudo ln -s /etc/nginx/sites-available/homeserver /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default

# Konfiguration testen
sudo nginx -t

# Nginx neu laden
sudo systemctl reload nginx

Nextcloud AIO Setup (Optional)

Schritt 1: Nextcloud AIO installieren

mkdir -p ~/docker/nextcloud
cd ~/docker/nextcloud

# Docker Compose Konfiguration
cat > docker-compose.yml << 'EOF'
services:
  nextcloud-aio-mastercontainer:
    image: ghcr.io/nextcloud-releases/all-in-one:latest
    init: true
    restart: always
    container_name: nextcloud-aio-mastercontainer
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - "11000:11000"
      - "8081:8080"
      - "8444:8443"
    environment:
      - WATCHTOWER_DOCKER_SOCKET_PATH=/var/run/docker.sock
      - NEXTCLOUD_DATADIR=/opt/nextcloud/data
      - NEXTCLOUD_UPLOAD_LIMIT=16G
      - NEXTCLOUD_MEMORY_LIMIT=1024M
      - APACHE_PORT=11000
      - APACHE_IP_BINDING=127.0.0.1
      - SKIP_DOMAIN_VALIDATION=false

volumes:
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer
EOF

Schritt 2: Nextcloud starten

# Container starten
docker compose up -d

# AIO-Interface aufrufen: https://PI_IP:8081
# Domain konfigurieren und Container bereitstellen

Fritz!Box-Konfiguration

Port-Freigaben einrichten

Schritt 1: Statische IP für Pi einrichten

Fritz!Box-Webinterface → Heimnetz → Netzwerk → Netzwerkverbindungen
→ Pi auswählen → Bearbeiten → "Diesem Netzwerkgerät immer die gleiche IPv4-Adresse zuweisen"

Schritt 2: Port-Freigaben konfigurieren

Fritz!Box-Webinterface → Internet → Freigaben → Portfreigaben
→ Gerät für Freigaben hinzufügen → Raspberry Pi auswählen
→ Neue Freigabe → Andere Anwendung

Port-Freigaben:
- HTTP: Port 80 (TCP) → Pi-IP:80
- HTTPS: Port 443 (TCP) → Pi-IP:443
- DNS: Port 53 (TCP/UDP) → Pi-IP:53

DynDNS konfigurieren

Fritz!Box DynDNS-Einstellungen:

Fritz!Box-Webinterface → Internet → Freigaben → DynDNS
→ DynDNS benutzen: aktivieren
→ DynDNS-Anbieter: No-IP
→ Update-URL: https://dynupdate.no-ip.com/nic/update?hostname=<domain>&myip=<ipaddr>
→ Domainname: ihre-domain.ddns.net
→ Benutzername: ihr-no-ip-username
→ Kennwort: ihr-no-ip-password

Pi-hole DHCP-Integration

Option 1: Fritz!Box DHCP mit Pi-hole DNS

Fritz!Box-Webinterface → Heimnetz → Netzwerk → Netzwerkeinstellungen
→ IP-Adressen → IPv4-Konfiguration
→ Lokaler DNS-Server: Pi-IP eingeben (z.B. 192.168.178.100)
→ Übernehmen

Option 2: Pi-hole als Fritz!Box Upstream-DNS

Fritz!Box-Webinterface → Internet → Zugangsdaten → DNS-Server
→ Bevorzugter DNSv4-Server: Pi-IP
→ Alternativer DNSv4-Server: Pi-IP

IPv6-Konfiguration

IPv6 in Fritz!Box aktivieren:

Fritz!Box-Webinterface → Internet → Zugangsdaten → IPv6
→ IPv6-Unterstützung aktiv: aktivieren
→ IPv6-Adresszuteilung: DHCPv6
→ DNS-Server: Pi-IPv6-Adresse hinzufügen

Sicherheit und Wartung

Grundlegende Sicherheitsmaßnahmen

Systemsicherheit:

# Automatische Updates aktivieren
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades

# Fail2ban für SSH-Schutz
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# SSH-Konfiguration härten
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl restart ssh

Nginx-Sicherheit:

# DH-Parameter generieren
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

# Nginx-Sicherheitskonfiguration erweitern
sudo tee -a /etc/nginx/nginx.conf > /dev/null <<'EOF'
# Weitere Sicherheitseinstellungen
server_tokens off;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
EOF

Backup-Strategien

Paperless-ngx Backup:

# Backup-Script erstellen
cat > ~/backup_paperless.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/mnt/backup/paperless"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"
cd ~/docker/paperless-ngx

# Dokumente exportieren
docker compose exec webserver document_exporter /usr/src/paperless/export/backup_$DATE

# Volumes sichern
docker run --rm -v paperless-ngx_data:/data -v "$BACKUP_DIR":/backup alpine tar czf /backup/paperless_data_$DATE.tar.gz -C /data .
docker run --rm -v paperless-ngx_media:/data -v "$BACKUP_DIR":/backup alpine tar czf /backup/paperless_media_$DATE.tar.gz -C /data .
EOF

chmod +x ~/backup_paperless.sh

Pi-hole Backup:

# Pi-hole Konfiguration sichern
sudo cp -r ~/docker/pihole/etc-pihole ~/backup/pihole_config_$(date +%Y%m%d)

Wartungsaufgaben

Monatliche Wartung:

# System-Updates
sudo apt update && sudo apt upgrade -y

# Docker-Images aktualisieren
cd ~/docker/paperless-ngx && docker compose pull && docker compose up -d
cd ~/docker/pihole && docker compose pull && docker compose up -d

# Logs bereinigen
docker system prune -f
journalctl --vacuum-time=30d

# SSL-Zertifikate prüfen
sudo certbot certificates

Monitoring-Script:

# System-Status-Script
cat > ~/system_check.sh << 'EOF'
#!/bin/bash
echo "=== System Status Check ==="
echo "Datum: $(date)"
echo "Uptime: $(uptime)"
echo "Speicher: $(free -h | grep Mem)"
echo "Festplatte: $(df -h /)"
echo "Temperatur: $(vcgencmd measure_temp)"
echo "Docker Container:"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo "=== Ende ==="
EOF

chmod +x ~/system_check.sh

FAQ und Troubleshooting

Häufige Probleme und Lösungen

Problem: Docker-Container starten nicht

# Logs überprüfen
docker compose logs service_name

# Container-Status prüfen
docker ps -a

# Ports überprüfen
sudo netstat -tulpn | grep LISTEN

# Lösung: Neustart der Container
docker compose down && docker compose up -d

Problem: Pi-hole blockiert gewünschte Websites

# Whitelist hinzufügen
docker compose exec pihole pihole -w example.com

# Blacklist prüfen
docker compose exec pihole pihole -q example.com

Problem: SSL-Zertifikat funktioniert nicht

# Nginx-Konfiguration testen
sudo nginx -t

# Certbot-Logs prüfen
sudo journalctl -u certbot

# Zertifikat manuell erneuern
sudo certbot renew --force-renewal

Problem: Paperless-ngx langsam

# Ressourcen-Monitoring
docker stats

# OCR deaktivieren für bessere Performance
# In docker-compose.env:
PAPERLESS_OCR_MODE=skip

Problem: Externe Verbindung funktioniert nicht

# Port-Erreichbarkeit testen
nmap -p 80,443 ihre-domain.com

# Fritz!Box-Freigaben prüfen
# DynDNS-Status überprüfen
nslookup ihre-domain.ddns.net

# Firewall-Regeln prüfen
sudo ufw status

Performance-Optimierung

Raspberry Pi 5 spezifische Optimierungen:

# SSD für Docker-Volumes verwenden (falls verfügbar)
# Docker-Volumes auf SSD verschieben
docker volume ls
# Volumes zu SSD-Mount verschieben

# Temperatur-Monitoring
watch -n 1 'vcgencmd measure_temp && vcgencmd get_throttled'

# Aktive Kühlung aktivieren
# Fan-Konfiguration in /boot/firmware/config.txt:
echo "dtparam=fan_temp=60000" | sudo tee -a /boot/firmware/config.txt

Docker-Performance:

# Container-Ressourcen begrenzen
# In docker-compose.yml:
deploy:
  resources:
    limits:
      cpus: '0.5'
      memory: 512M

Netzwerk-Debugging

Verbindungsprobleme analysieren:

# DNS-Auflösung testen
nslookup ihre-domain.com
dig ihre-domain.com

# Erreichbarkeit testen
ping ihre-domain.com
traceroute ihre-domain.com

# Port-Verfügbarkeit prüfen
telnet ihre-domain.com 443
nc -zv ihre-domain.com 443

Fritz!Box-Debugging:

# Fritz!Box-Logs über Webinterface prüfen
# System → Ereignisse → Systemereignisse
# Internetverbindung → DynDNS-Status prüfen

Diese Anleitung bietet eine vollständige Einrichtung eines professionellen Homeservers auf Basis des Raspberry Pi 5. Alle Konfigurationen basieren auf offiziellen Dokumentationen und bewährten Praktiken für Stabilität und Sicherheit.