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.