Skip to Content

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

July 12, 2025 by
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.

Nicht suchen, finden. In Paperless