Headless, doch nicht kopflos

Autor: Gerd Raudenbusch
Stand: 07.06.2026

Ein einfacher Rechner mit Linux und angeschlossenem Festspeicher und Backup-Strategie - und schon kann es eigentlich losgehen, ihn als Dateiserver, Musikserver oder Medienserver im Heimnetz einzusetzen.

Doch was muss getan werden, dass die Festplatte nicht schon in jüngster Zeit aufgrund der vielen Schreibzugriffe defekt wird? Welche Protokolle muss der Rechner sprechen, damit andere Geräte - Fernseher, Radios, Rechner - ihn im Heimnetz sofort finden können?

Inhalt

Optimierung von Schreibzugriffen und Energieeinstellungen auf Festspeicher-Medien

Der eigene NAS oder Medienserver zu Hause wird oft Headless betrieben, bzw. man deaktiviert den Bildschirm oder die GUI. Damit die Festspeicher-Medien solcher Server möglichst lange hält, macht es Sinn, die Einstellungen der Festplatte und des Dateisystems dafür zu optimieren.

Minimierung der Festplatten-Schreibzugriffe

Um die Festplatten auf dem NAS maximal zu schonen, müssen vor allem unnötige Schreibvorgänge minimiert und der Parkmodus aktivieret werden. Dies kann auch auf LUKS-Partitionen angewendet werden. Dazu werden zusätzliche mount-Optionen in der Datei /etc/fstab zugefügt. Die perfekte Kombination: zram + noatime + journald volatile führt ohne Benutzerinteraktion zu 0 Schreibzugriffen auf Festplatten.

Anpassung der Mount-Flags

Wichtige Mount-Optionen in der fstab:

Option Schreibzugriffe Crash-Sicherheit NAS/Server
barrier=1 (default) Normal Hoch ✅ sicher
barrier=0 -30% Mittel ⚠️ akzeptabel
commit=60 -80% Hoch ✅ immer

Empfehlung NAS: barrier=0 OK (UPS empfohlen) Empfehlung Root: barrier=1 lassen oder relatime

/dev/mapper/vgubuntu-root / ext4 errors=remount-ro,relatime,nodiratime,commit=60 0 1
# Für ext4 Dateisysteme (typisch für Ubuntu NAS)
UUID=xxxx-xxxx /mnt/nas ext4 defaults,noatime,nodiratime,commit=60,barrier=0 0 2

Aktivierung des Energiesparmodus der Festplatten

hdparmist ein Linux-Kommandozeilenwerkzeug, mit dem man Parameter von ATA/SATA-Festplatten und SSDs anzeigen und ändern sowie einfache Leistungstests durchführen kann. Typische Einsatzzwecke sind:

Es kann mit sudo apt install hdparm installiert werden. Wenn der Energiesparmodus aktiv ist, dann enthält die Ausgabe von hdparm -I die Zeile Power Management feature set. Das ist zu Beginn meist nicht der Fall, und es muss zunächst die Konfiguration angepasst werden mit vi /etc/hdparm.conf:

# Alle Festplatten
/dev/disk/by-id/ata-*
{
    spindown_time = 24      # 120 Sekunden (24*5s)
    apm = 127               # 127 ist als mittlerer Wert ein Kompromiss zwischen Energie sparen und Performance leisten
}

Aktivierung des S.M.A.R.T Parkmodus für Festplatten

smartctl gehört zu smartmontools und ist primär für S.M.A.R.T.-Diagnose, Laufwerkszustand und einige Gerätefunktionen gedacht. Es kann mit sudo apt install smartmontools installiert werden.

Nicht jedes Laufwerk reagiert auf die Befehle hdparm und smartctl gleich; bei manchen Geräten funktioniert einer besser als der andere. Beide können APM beeinflussen, aber smartctl ist stärker auf Diagnose und Überwachung ausgerichtet, während hdparm stärker die klassische Laufwerkskonfiguration fokussiert.

Überprüfung der optimierten Schreibzugriffe

Benutzung von RAM-Disk und Swap

Eine RAM-Disk ist einfach Speicher, der sich wie ein Laufwerk verhält. Sie ist super schnell, aber nur für flüchtige Daten geeignet, weil sie beim Ausschalten leer ist. Swap ist das klassische Auslagern von Speicher auf eine langsamere Speicherseite, damit das System bei vollem RAM weiterarbeiten kann. Das ist langsamer als RAM, aber wichtig für Stabilität. zram ist ein komprimierter Bereich im RAM, der als Swap benutzt wird. Dadurch passen mehr Daten in den Arbeitsspeicher, ohne dass sofort auf Platte ausgelagert werden muss. zswap sitzt zwischen RAM und echtem Swap und hält ausgelagerte Seiten zunächst komprimiert im Speicher, bevor sie bei Bedarf doch auf Disk geschrieben werden.

Begriff Was es ist Wo liegt es Hauptzweck Vorteil Nachteil
RAM-Disk Ein Speicherbereich, der wie ein Laufwerk benutzt wird Im Arbeitsspeicher Sehr schnelle temporäre Dateien Extrem schnell Daten gehen beim Ausschalten verloren, belegt echten RAM
Swap Auslagerungsspeicher für selten genutzte Speicherseiten Meist auf SSD/HDD, manchmal als Datei oder Partition RAM entlasten, Speicherengpässe abfedern Verhindert eher Abstürze bei Speicherdruck Deutlich langsamer als RAM
zram Komprimiertes Swap-Gerät im RAM Im Arbeitsspeicher Mehr effektiver Speicher ohne Disk-I/O Schnell, spart Disk-Zugriffe Verbraucht CPU für Kompression, nutzt echten RAM
zswap Komprimierter Puffer vor dem normalen Swap Im RAM als Cache, dahinter normaler Swap auf Disk Disk-Swap reduzieren Nutzt vorhandenen Swap weiter und puffert komprimiert Ebenfalls CPU-Overhead, funktioniert nur mit echtem Swap im Hintergrund

Die Verlegung von Swap-Speicher auf eine RAM-Disk macht nicht deswegen Sinn, weil der Swap den RAM ersetzt, sondern weil Linux ihn auch dann sinnvoll nutzt, wenn noch freier RAM da ist. Denn Linux hält gern Daten im RAM, die gerade nicht aktiv gebraucht werden, und räumt sie bei Bedarf wieder ab. Swap hilft dabei, selten genutzte Speicherbereiche auszulagern, damit mehr RAM für wirklich wichtige Arbeit bleibt. Das ist besonders nützlich, wenn:

Die Idee ist also nicht, Swap dauerhaft komplett im RAM zu halten, sondern ihn als komprimierten oder ausgelagerten Bereich im Arbeitsspeicher zu organisieren. Dann bleibt mehr "echter" RAM für laufende Anwendungen übrig, obwohl die Auslagerung technisch weiterhin im Speicher statt auf Platte liegt. Der Vorteil liegt nicht in mehr Kapazität im physikalischen Sinn, sondern:

Sinnvoll, bei:

Weniger sinnvoll, wenn:

Swap ist also kein Ersatz für RAM, sondern ein Sicherheitsnetz und ein Werkzeug für Speicherverwaltung. „Swap ins RAM verlegen“ kann sich lohnen, wenn du damit langsame Plattenzugriffe vermeidest und Speicher effizienter nutzt, aber es ist keine Magie gegen echten RAM-Mangel.

Folgende Schritte sind notwendig, um zram zu nutzen:

# Aktuelle Swap deaktivieren
sudo swapoff -a

# Swap aus fstab auskommentieren oder löschen
sudo nano /etc/fstab
# Zeile mit "swap" oder "/swapfile" mit # auskommentieren

# Ubuntu systemd-swapfile deaktivieren
sudo systemctl disable --now systemd-swapfile.service
sudo systemctl mask systemd-swapfile.service
sudo apt update
sudo apt install zram-config
sudo apt install zram-tools

Die Datei `/etc/default/zramswap` folgendermaßen anpassen:

```bash
#
# Faustregel:
# RAM < 04GB? --> zram auf 75% stellen
# RAM > 16GB? --> zram optional, oder swappiness=1
# Sonst: zram auf 50%
#
SIZE=2048    # zram-Größe = 50% des RAM bei 4GB RAM
ALGO=lz4     # Schnellste Kompression
PRIORITY=100 # Höher als Festplatten-Swap
sudo systemctl enable zramswap
sudo systemctl start zramswap
# Minimales Swappen (nur bei RAM-Mangel)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

# Sofort anwenden
sudo sysctl vm.swappiness=10
# Swap-Status
free -h
swapon --show

# zram prüfen
cat /sys/block/zram0/mm_stat
zramctl

Erwartete Beispiel-Ausgabe nach Einrichtung:

               total        used        free      shared  buff/cache   available
Mem:           7.7G        1.2G        4.1G         20M        2.4G        6.2G
Swap:          2.0G          0B        2.0G
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 lz4         2G   0B   0B  0B       4 [SWAP]
reboot
free -h
swapon --show  # Sollte nur zram zeigen
cat << EOF | sudo tee -a /etc/sysctl.conf
vm.swappiness=5
vm.vfs_cache_pressure=50
vm.dirty_ratio=15
vm.dirty_background_ratio=5
EOF
sudo sysctl -p

Die Datei /etc/default/zramswap anpassen:

# Automatisch 50% RAM
ALLOCATION=$(($(free | awk '/Mem:/ {print int($2/1024/2)}'))
# 60s Stress-Test – beobachte free -h
stress --vm 4 --vm-bytes 3G --timeout 60s &
watch -n1 free -h

Optimierung des Schreibens von Log-Dateien

ACHTUNG: Die Umleitung von Log-Dateien ins RAM bedeutet, daß sie nach einem Neustart weg sind! Diese Entscheidung ist Geschmacksache und hat Vor- und Nachteile. RAM-Logging ist schnell und schont die Datenträger, aber Logs gehen beim Reboot verloren und der Platz ist begrenzt. Daher sind die Schritte in diesem Kapiel individuell zu überdenken.

Umleiten von journald (systemd-Logs) ins RAM

[Journal]
Storage=volatile
RuntimeMaxUse=128M
RuntimeKeepFree=32M
MaxRetentionSec=1month

tmpfs für temporäre Dateien nutzen

Zeile in /etc/fstab Wirkung
tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0 Hängt /tmp als tmpfs ein, alle können schreiben, temporäre Dateien gehen beim Reboot verloren
tmpfs /var/log tmpfs defaults,noatime,mode=0755 0 0 Hängt das Standardverzeichnis für Linux-Logdateien /var/log als tmpfs ein, Logdateien gehen beim Reboot verloren, nur Besitzer darf schreiben
tmpfs /var/tmp tmpfs defaults,noatime,mode=1777 0 0 Hängt /var/tmp als tmpfs ein (wie /tmp). Vorsicht: /var/tmp ist eigentlich für persistente temporäre Dateien gedacht, die einen Neustart überleben sollen (z.B. Installer)

Wartungsaufgaben für journal und temp

# Automatisches Journal leeren
echo '0 2 * * * root journalctl --vacuum-time=7d' | sudo tee /etc/cron.d/clean-journal

# Temp leeren
echo '0 3 * * * root rm -rf /tmp/* /var/tmp/*' | sudo tee /etc/cron.d/clean-tmp

Schreibzugriffe von Samba optimieren

Es macht Sinn, die Schreibzugriffe von Samba zu optimieren. Dazu kann die Datei /etc/samba/smb.conf folgendermaßen angepasst werden:

[global]
strict locking = no
strict sync = no
sync always = no

Automatische Paketaktualisierungen mit apt

Optimalerweise aktualisiert der Heimserver sein Betriebssystem selbständig. Das Schlagwort unter Debian-basierten Systemen dafür ist "unattended upgrades" (="unaufgeforderte Aktualisierungen"). Dies wird wiefolgt eingerichtet:

sudo apt update
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
sudo systemctl enable --now unattended-upgrades

Nun kann die Datei /etc/apt/apt.conf.d/10periodic für die tägliche Ausführung angepasst werden:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";

Die automatische Aktualisierung des Kernel kann problematisch sein, da es in manchen Fällen zu Problemen auf der /boot-Partition kommen kann. Diese sollten manuell gemacht werden und es sollte danach zumindest geprüft werden, ob das System potentiell noch bootbar ist und die in /boot gesetzten Links zum Kernel und initramfs noch in Ordnung sind, bevor der Neustart mit einem aktualisierten Kernel durchgeführt wird.

Dazu muss die Datei /etc/apt/apt.conf.d/50unattended-upgrades ergänzt werden unter Unattended-Upgrade::Package-Blacklist:

Unattended-Upgrade::Package-Blacklist {
    "linux-image.*";
    "linux-headers.*";
    "linux-modules.*";
    "linux-kernel.*";
};

Dies verhindert Updates für Kernel, Headers und Module. Nur andere Pakete (z. B. Sicherheitsfixes) werden installiert. Die Timer können überprüft werden mit systemctl status apt-daily.timer apt-daily-upgrade.timer. Standardmäßig laufen sie täglich (z. B. um 6 Uhr mit Zufallsverzögerung). Logs finden sich in /var/log/unattended-upgrades/.

Heimnetzwerk-Multimedia-Protokolle

Kategorie Zweck
Zeroconf Automatische Netzwerk-Konfiguration ohne manuelle Einrichtung
Service Discovery Automatische Erkennung von Geräten und Diensten im Netzwerk
Media Streaming Übertragung von Audio/Video in Echtzeit
File Sharing Dateiübertragung und -freigabe

Für Heimnetzwerk-Medien (Video, Audio, Bilder) sind die wichtigsten:

Anwendung Protokoll
automatische Erkennung (Service Discovery) mDNS / Bonjour / Avahi
Medienstreaming (TV, Stereoanlage) DLNA / UPnP-AV
Apple-Streaming AirPlay
Dateifreigabe (Windows) SMB/CIFS
Dateifreigabe (Linux) NFS
Datei-Transfer FTP / SFTP / WebDAV

Dateitransfer-Protokolle für den Heimserver

Protokoll-Übersicht

Protokoll Beschreibung
SMB (Server Message Block) Windows-Standard für Datei- und Druckfreigaben (auch CIFS genannt)
NFS (Network File System) Unix/Linux-Standard für Netzlaufwerke
FTP (File Transfer Protocol) Klassisches Dateitransfer-Protokoll, früher ungesichert, heute oft als FTPS
SFTP (SSH File Transfer Protocol) Verschlüsseltes FTP über SSH
WebDAV Erweiterung von HTTP für Dateisynchronisation

Datei-Zugriff per Samba

Samba ist eine Open-Source-Software, die es Linux- und Unix-Systemen ermöglicht, mit Windows-Netzwerken zu kommunizieren, also Dateien, Drucker und andere Ressourcen in einem gemischten Netzwerk freizugeben. Windows-Netzwerke nutzen das SMB/CIFS-Protokoll für Datei- und Druckfreigaben, Linux hat das nicht standardmäßig integriert. So implementiert Samba auch für Linux MB/CIFS.

[Bilder]
path = /pfad-zum-ordner
browseable = yes  # wenn ein Inhaltsverzeichnis gezeigt werden soll
read only = yes   # wenn der Inhalt nur lesbar sein soll
valid users = nas # erlaubte Samba-Benutzer für diese Freigabe

Datei-Zugriff per WebDAV

WebDAV (Web-based Distributed Authoring and Versioning) ist eine von vielen Applikationen verwendete Erweiterung von HTTP/1.1, die das Web vom reinen Informationsabruf zu einem beschreibbaren Speichermedium macht. WebDAV lässt sich problemlos dockern. Hier das Kontrollskript webdav.sh dazu:

#!/bin/bash
#
tag="latest"
if [ "${2}" != "" ]; then
    tag="${2}"
fi
name=$(basename ${0} |cut -d "." -f1)
img="sfuhrm/docker-nginx-webdav"
#img="bytemark/webdav"
options="--restart unless-stopped \
    -d \
    -p 80:80 \
    -v /media/deineplatte:/media/data \
    -e LOCATION=/webdav \
    -e USERNAME=username \
    -e PASSWORD=password \
    -m 1g"


menu () {
        while true; do
                cmd=(dialog --clear --backtitle "WebDAV menu" --title "WebDAV menu" --menu "Choice:" 22 120 12)
                options=(
                        1 "Start container"
                        2 "Stop container"
                        3 "Restart container"
                )
                choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
                case "$choice" in
                  1) clear; ${0} start; echo "Press any key."; read ;;
                  2) clear; ${0} stop; echo "Press any key."; read ;;
                  3) clear; ${0} restart; echo "Press any key."; read ;;
                  *) clear; return ;;
                esac
        done
}


echo "Container: ${name}"
if [ "${1}" == "" ]; then
    menu
elif [ "${1}" == "start" ]; then
    echo "Starting"
    docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "stop" ]; then 
    echo "Stopping"
    docker rm -f ${name}
elif [ "${1}" == "restart" ]; then
    docker rm -f ${name} && docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "pull" ]; then
        docker pull ${img}:${tag}
elif [ "${1}" == "login" ]; then
    docker exec -it ${name} /bin/bash
elif [ "${1}" == "commit" ]; then
    docker commit ${name} ${img}:${tag}
elif [ "${1}" == "load" ]; then
    echo "Loading"
    docker load < ${name}.tar.gz
elif [ "${1}" == "save" ]; then
    echo "Saving"
    docker save ${img}:${tag} | gzip > ${name}.tar.gz
else
    echo "Unknown : ${1}"
    exit 1
fi

Service-Discovery-Protokolle für den Heimserver

Protokoll-Übersicht

Protokoll Beschreibung
UPnP-AV (Universal Plug and Play Audio/Video) Der Standard, nach dem die meisten Streaming-Geräte arbeiten
DLNA (Digital Living Network Alliance) Erweitert UPnP-AV, legt Standardformate und Protokolle für Media-Wiedergabe fest
AirPlay (Apple) proprietäres Protokoll für Audio/Video-Streaming von Apple-Geräten
Chromecast (Google) Google-Protokoll zum Streamen von Inhalten auf TV und Lautsprecher
RTP (Real-Time Transport Protocol) Übertragung von Audio/Video-Streams in Echtzeit

Medienzugriff per DLNA

DLNA ist ein Vernetzungsstandard für digitale Geräte im Heimnetzwerk. Das Ziel ist, Multimedia-Daten (Fotos, Videos, Musik) zwischen Geräten unterschiedlicher Hersteller problemlos übertragen zu können. Der Verband wurde 2003 gegründet und umfasst große Hersteller wie Sony, Intel, Samsung und viele weitere. Die Funktionsweise ist einfach: DLNA-Geräte kommunizieren automatisch über das Netzwerk, ohne dass man jedes Gerät manuell konfigurieren muss. Typische DLNA-geräte sind Smart-TVs, PCs, Smartphones, Blu-ray-Player, AV-Receiver und Spielkonsolen. DLNA ist wie eine Art "Übersetzungs-Software", die es ermöglicht, dass beispielsweise das TV die Musik vom Medienserver streamen kann, ohne dass man sich um technische Kompatibilitäten kümmern muss.

MiniDLNA ist ein leichter Open-Source-DLNA-Server, der auch als ReadyMedia bekannt ist. Es macht jeden Linux- oder Unix-Rechner zu einem Medienserver für DLNA-kompatible Geräte. MiniDLNA verbraucht sehr wenig RAM und CPU, funktioniert sofort nach der Installation und ist für ressourcenschonende Systeme (wie Raspberry Pi) sehr beliebt. Die Software stellt eine Medienbibliothek (Fotos, Videos, Musik) im Netzwerk bereit. MiniDLNA ist also die Software, die es ermöglicht, dass DLNA-fähige Geräte (z.B. Smart-TV oder Handy) Musik, Videos und Fotos streamen können.

media_dir=A,/pfad-zu-deiner-Musik
media_dir=P,/pfad-zu-deinen-Bildern
media_dir=V,/pfad-zu-deinen-Videos
db_dir=/var/cache/minidlna
log_dir=/var/log/minidlna
port=8200
friendly_name=Mein Medienserver
inotify=yes
album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg
album_art_names=AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg
album_art_names=Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg

Bojnour und mDNS

mDNS (Multicast DNS) ist ein Netzwerkprotokoll zur Namensauflösung in kleinen lokalen Netzwerken ohne zentralen DNS-Server. Wenn ein Gerät im Netzwerk eine IP-Adresse zu einem Hostnamen finden möchte, muss es nicht gegen einen zentralen DNS-Server (wie 8.8.8.8 von Google) fragen, sondern sendet die Anfrage an alle Geräte im lokalen Netzwerk.

Ein Gerät sendet eine DNS-Anfrage per Multicast an alle Teilnehmer im Netzwerk. Die Anfrage geht an die spezielle Multicast-Adresse 224.0.0.251 auf Port 5353. Die Empfänger der Anfrage können diese per Multicast beantworten. Wenn das gesuchte Gerät im Netzwerk ist, antwortet es mit seiner IP-Adresse.

Hostnamen enden bei mDNS mit .local (z. B. mein-pc.local, printer.local).

Wichtige Eigenschaften:

mDNS ist wie ein „Ruf im Netzwerk". Statt an einen zentralen DNS-Server zu fragen, ruft das Gerät laut „Wer ist mein-pc.local?" und alle hören mit. Wenn das richtige Gerät antwortet, weiß man die IP-Adresse.

Bonjour ist Apple's Software, die mDNS zur Geräteerkennung verwendet. Ein Bonjour-Client kann einen Avahi-Server sehen, da beide mDNS + DNS-SD verwenden. Avahi ist die Linux-Version von Bonjour und beide interagieren perfekt miteinander.

Avahi ist eine freie Open-Source-Implementierung von mDNS und DNS-SD (DNS Service Discovery) für Linux-Systeme. Es ermöglicht die automatische Vernetzung von Geräten im lokalen Netzwerk ohne manuelle Konfiguration.

Vorteile von mDNS mit Avahi:

Mit sudo apt update && sudo apt install avahi-daemon avahi-utils kann Avahi installiert werden. Mit sudo systemctl enable avahi-daemon: sudo systemctl start avahi-daemon wird der Dienst gestartet. Mit sudo apt-get install avahi-discover

Beispielkonfiguration:

[server]
use-ipv4=yes
use-ipv6=no

[reflector]
enable-reflector=yes
reflect-ipv=no

Dienste für den Heimserver des Heimnetzes

Git Repository (ohne Gitlab)

Git ist ein verteiltes Versionskontrollsystem, das sich zum weltweiten Standard für die Versionskontrolle entwickelt hat. Es wird verwendet, um Änderungen in Dateien – insbesondere Quellcode von Softwareprojekten – intelligent nachzuverfolgen und zu verwalten.

Die folgenden Befehle erstellen ein neues Git-Repository ohne Oberfläche. Als Versionskontrollsystem macht Git insbesondere Sinn für alle menschenlesbaren Dateien.

Git Repository (mit Gitlab)

Gitlab ist eine Weboberfläche für Git, die viele Vorteile bietet, wenn intensiv und vielleicht zu Mehreren mit Git gearbeitet wird. Gitlab kann bequem im Docker betrieben werden. Das folgende Shellskript gitlab.sh ist ein Kontrollskript für ein gedockertes Gitlab:

#!/bin/bash
# gitlab.sh control script

tag="latest"
if [ "${2}" != "" ]; then
    tag="${2}"
fi
name=$(basename ${0} |cut -d "." -f1)
img="gitlab/gitlab-ce" # URL zu Repository
options="--detach \
  --hostname $(hostname) \
  --publish 2443:443 --publish 2080:80 --publish 2022:22 \
  --name gitlab \
  --restart always \
  --volume /srv/gitlab/config:/etc/gitlab \
  --volume /srv/gitlab/logs:/var/log/gitlab \
  --volume /srv/gitlab/data:/var/opt/gitlab \
  --shm-size 256m"

#########################
echo "Container: ${name}"

menu () {
        while true; do
                cmd=(dialog --clear --backtitle "Gitlab menu" --title "Gitlab menu" --menu "Choice:" 22 120 12)
                options=(
                        1 "Start container"
                        2 "Stop container"
                        3 "Restart container"
                )
                choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
                case "$choice" in
                  1) clear; ${0} start; echo "Press any key."; read ;;
                  2) clear; ${0} stop; echo "Press any key."; read ;;
                  3) clear; ${0} restart; echo "Press any key."; read ;;
                  *) clear; return ;;
                esac
        done
}

if [ "${1}" == "" ]; then
        menu
elif [ "${1}" == "start" ]; then
    echo "Starting"
    docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "stop" ]; then 
    echo "Stopping"
    docker rm -f ${name}
elif [ "${1}" == "restart" ]; then
    docker rm -f ${name} && docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "login" ]; then
    docker exec -it ${name} /bin/bash
elif [ "${1}" == "pull" ]; then
    docker pull ${img}:${tag}
elif [ "${1}" == "commit" ]; then
    docker commit ${name} ${img}:${tag}
elif [ "${1}" == "load" ]; then
    echo "Loading"
    docker load < ${name}.tar.gz
elif [ "${1}" == "save" ]; then
    echo "Saving"
    docker save ${img}:${tag} | gzip > ${name}.tar.gz
else
    echo "Unknown : ${1}"
    exit 1
fi

copyparty

Copyparty ist ein in 2019 entstandener Open-Source-Portabler Python-Dateiserver (von 9001 auf GitHub, FOSS), der alles kann: HTTP/Web-UI, WebDAV, FTP/FTPS, TFTP, Zeroconf, Medien-Indexing, Deduplizierung und unterbrechungsfreie Uploads – in nur einer einzigen Datei. Hier ist das Kontrollskript copyparty.sh

#!/bin/bash
# copyparty.sh docker control script

tag="latest"
if [ "${2}" != "" ]; then
    tag="${2}"
fi
name=$(basename ${0} |cut -d "." -f1)
img="copyparty/ac"
options="--restart unless-stopped \
    -d \
    -p 3923:3923 \
    -v /dein-medienverzeichnis:/media \
    -v /opt/copyparty/config:/cfg/config.conf:ro \
    -v /opt/copyparty/database:/cfg/hists \
    -m 1g"

#########################

menu () {
        while true; do
                cmd=(dialog --clear --backtitle "Owncloud menu" --title "Owncloud menu" --menu "Choice:" 22 120 12)
                options=(
                        1 "Start container"
                        2 "Stop container"
                        3 "Restart container"
                )
                choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
                case "$choice" in
                  1) clear; ${0} start; echo "Press any key."; read ;;
                  2) clear; ${0} stop; echo "Press any key."; read ;;
                  3) clear; ${0} restart; echo "Press any key."; read ;;
                  *) clear; return ;;
                esac
        done
}


echo "Container: ${name}"
if [ "${1}" == "" ]; then
    menu
elif [ "${1}" == "init" ]; then
    mkdir -p /opt/copyparty/config
    mkdir -p /opy/copyparty/database
    cat > /opt/copyparty/config/copyparty.conf << 'EOF'
[accounts]
benuzuer: passwort
[/]
/media
accs:
rwda: benutzer
EOF
elif [ "${1}" == "start" ]; then
    echo "Starting"
    docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "stop" ]; then 
    echo "Stopping"
    docker rm -f ${name}
elif [ "${1}" == "restart" ]; then
    docker rm -f ${name} && docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "pull" ]; then
        docker pull ${img}:${tag}
elif [ "${1}" == "login" ]; then
    docker exec -it ${name} /bin/bash
elif [ "${1}" == "commit" ]; then
    docker commit ${name} ${img}:${tag}
elif [ "${1}" == "load" ]; then
    echo "Loading"
    docker load < ${name}.tar.gz
elif [ "${1}" == "save" ]; then
    echo "Saving"
    docker save ${img}:${tag} | gzip > ${name}.tar.gz
else
    echo "Unknown : ${1}"
    exit 1
fi

filebrowser

filebrowser ist ein Open-Source-Web-Filemanager unter MIT-Lizenz, der seit 2015 als einfaches, schnelles One-Binary-Tool existiert und über reine HTTP/Web-UI nur Dateien hoch- und herunterladen kann, aber kein WebDAV beherrscht. Hier ist das Kontrollskript filebrowser.sh

#!/bin/bash
#filebrowser.sh

tag="latest"
if [ "${2}" != "" ]; then
    tag="${2}"
fi
name=$(basename ${0} |cut -d "." -f1)
img="filebrowser/filebrowser"
options="--restart unless-stopped \
    -d \
    -p 3000:80 \
    -v /media/nas:/srv \
    -v /opt/filebrowser/config:/config \
    -v /opt/filebrowser/database:/database \
    -m 1g"

#########################

mkdir -p /opt/filebrowser/config
mkdir -p /opt/filebrowser/database

menu () {
        while true; do
                cmd=(dialog --clear --backtitle "Owncloud menu" --title "Owncloud menu" --menu "Choice:" 22 120 12)
                options=(
                        1 "Start container"
                        2 "Stop container"
                        3 "Restart container"
                )
                choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
                case "$choice" in
                  1) clear; ${0} start; echo "Press any key."; read ;;
                  2) clear; ${0} stop; echo "Press any key."; read ;;
                  3) clear; ${0} restart; echo "Press any key."; read ;;
                  *) clear; return ;;
                esac
        done
}


echo "Container: ${name}"
if [ "${1}" == "" ]; then
    menu
elif [ "${1}" == "init" ]; then
    docker run --rm filebrowser/filebrowser fb --init # Create container
    docker run --rm -v $HOME/.filebrowser:/config filebrowser/filebrowser \
        fb --baseurl /admin \
        --username admin \
        --password admin \
        --create
elif [ "${1}" == "start" ]; then
    echo "Starting"
    docker run --name ${name} ${options} ${img}:${tag} #sleep infinity
elif [ "${1}" == "stop" ]; then 
    echo "Stopping"
    docker rm -f ${name}
elif [ "${1}" == "restart" ]; then
    docker rm -f ${name} && docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "pull" ]; then
        docker pull ${img}:${tag}
elif [ "${1}" == "login" ]; then
    docker exec -it ${name} /bin/bash
elif [ "${1}" == "commit" ]; then
    docker commit ${name} ${img}:${tag}
elif [ "${1}" == "load" ]; then
    echo "Loading"
    docker load < ${name}.tar.gz
elif [ "${1}" == "save" ]; then
    echo "Saving"
    docker save ${img}:${tag} | gzip > ${name}.tar.gz
else
    echo "Unknown : ${1}"
    exit 1
fi

Jellyfin Medienserver

Jellyfin ist, wie kodi oder Plex, ein kostenloser Open-Source-Medien-Server, der eine Reihe von Multimedia-Anwendungen zum Organisieren, Verwalten und Freigeben digitaler Mediendateien bietet. Auch ein Jellyfin lässt sich problemlos dockern. Hier ist das Kontrollskript jellyfin.sh

#!/bin/bash
# jellyfin.sh
#
tag="latest"
if [ "${2}" != "" ]; then
    tag="${2}"
fi
name=$(basename ${0} |cut -d "." -f1)
img="jellyfin/jellyfin"

mkdir -p /opt/jellyfin/cache
mkdir -p /opt/jellyfin/config

options="-d \
    --name jellyfin \
    -p 8096:8096/tcp \
    -p 7359:7359/udp \
    -p 1900:1900/udp \
    -e MALLOC_TRIM_THRESHOLD_=100000 \
    --user 1000:1000 \
    --net=host \
    --volume /opt/jellyfin/config:/config \
    --volume /opt/jellyfin/cache:/cache \
    --mount type=bind,source=/media/nas,target=/media \
    --restart=unless-stopped \
    -m 1g"

menu () {
        while true; do
                cmd=(dialog --clear --backtitle "Jellyfin menu" --title "Jellyfin menu" --menu "Choice:" 22 120 12)
                options=(
                        1 "Start container"
                        2 "Stop container"
                        3 "Restart container"
                )
                choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
                case "$choice" in
                  1) clear; ${0} start; echo "Press any key."; read ;;
                  2) clear; ${0} stop; echo "Press any key."; read ;;
                  3) clear; ${0} restart; echo "Press any key."; read ;;
                  *) clear; return ;;
                esac
        done
}


echo "Container: ${name}"
if [ "${1}" == "" ]; then
    menu
elif [ "${1}" == "start" ]; then
    echo "Starting"
    docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "stop" ]; then 
    echo "Stopping"
    docker rm -f ${name}
elif [ "${1}" == "restart" ]; then
    docker rm -f ${name} && docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "login" ]; then
    docker exec -it ${name} /bin/bash
elif [ "${1}" == "pull" ]; then
        docker pull ${img}:${tag}
elif [ "${1}" == "commit" ]; then
    docker commit ${name} ${img}:${tag}
elif [ "${1}" == "load" ]; then
    echo "Loading"
    docker load < ${name}.tar.gz
elif [ "${1}" == "save" ]; then
    echo "Saving"
    docker save ${img}:${tag} | gzip > ${name}.tar.gz
else
    echo "Unknown : ${1}"
    exit 1
fi

Navidrome ist ein selbst gehosteter, Open-Source-Musikserver und Streamer, mit dem die eigene Musiksammlung von überall streambar ist, ähnlich wie Spotify oder Apple Music, aber privat. Navidrome indiziert die Musik und macht sie verfügbar über Web-Player im Browser, Mobile Apps (iOS, Android) und Subsonic-kompatible Clients. Mit Jellyfin nicht unbedingt notwendig, dafür aber sehr leichtgewichtig. Hier das Kontrollskript navidrome.sh für ein gedockertes Navitrome:

#!/bin/bash
# navidrome.sh
#
tag="latest"
if [ "${2}" != "" ]; then
    tag="${2}"
fi
name=$(basename ${0} |cut -d "." -f1)
img="deluan/navidrome"

mkdir -p /opt/navidrome/data
options="-d \
    -p 4533:4533 \
    --user $(id -u):$(id -g) \
    --volume /media/ordner-mit-deiner-musik:/music:ro \
    --volume /opt/navidrome/data:/data \
    --mount type=bind,source=/media/nas,target=/media \
    --restart=unless-stopped \
    -m 1g"

menu () {
        while true; do
                cmd=(dialog --clear --backtitle "Navidrome menu" --title "Jellyfin menu" --menu "Choice:" 22 120 12)
                options=(
                        1 "Start container"
                        2 "Stop container"
                        3 "Restart container"
                )
                choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
                case "$choice" in
                  1) clear; ${0} start; echo "Press any key."; read ;;
                  2) clear; ${0} stop; echo "Press any key."; read ;;
                  3) clear; ${0} restart; echo "Press any key."; read ;;
                  *) clear; return ;;
                esac
        done
}
echo "Container: ${name}"
if [ "${1}" == "" ]; then
    menu
elif [ "${1}" == "start" ]; then
    echo "Starting"
    docker run --name ${name} ${options} ${img}:${tag} #sleep infinity
elif [ "${1}" == "stop" ]; then 
    echo "Stopping"
    docker rm -f ${name}
elif [ "${1}" == "restart" ]; then
    docker rm -f ${name} && docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "login" ]; then
    docker exec -it ${name} /bin/bash
elif [ "${1}" == "pull" ]; then
        docker pull ${img}:${tag}
elif [ "${1}" == "commit" ]; then
    docker commit ${name} ${img}:${tag}
elif [ "${1}" == "load" ]; then
    echo "Loading"
    docker load < ${name}.tar.gz
elif [ "${1}" == "save" ]; then
    echo "Saving"
    docker save ${img}:${tag} | gzip > ${name}.tar.gz
else
    echo "Unknown : ${1}"
    exit 1
fi

Zurück zur Hauptseite