Datenschutz-freundliche Website
Inhaltsverzeichnis:
- 🛡️ Eigener datensparsamer Webserver mit Caddy, Docker und OpenSSH (ohne Plesk, ohne Logs)
- Sichere SSH Verbindung (Linux Desktop)
- 🔧 V-Server vorbereiten (Debian 13)
- 🔐 OpenSSH mit SFTP einrichten (statt FTP oder SFTPGo)
- 📦 Docker und Docker Compose installieren
- 🌐 Website per Docker + Caddy bereitstellen (ohne Logs, mit HTTPS)
- 🧱 Hinweis für Publii: Remote-Pfad korrekt einstellen
- 🔐 Datenschutz & rechtlicher Hinweis
🛡️ Eigener datensparsamer Webserver mit Caddy, Docker und OpenSSH (ohne Plesk, ohne Logs)
Du möchtest eine Website hosten, aber ohne unnötige Server-Logs, ohne Drittanbieter, ohne FTP und ohne Plesk? Dann bist du hier richtig.
Wenn du in Richtung Hoster etwas suchst, dann bist du falsch, da ChrootDirectory bei sFTP nicht dafür angelegt ist / wurde, da sind Änderungen nötig, da jeder User sieht, welche User angelegt sind. anders wäre das viel mehr Aufwand.
In dieser Anleitung erfährst du Schritt für Schritt, wie du:
- einen eigenen V-Server aufsetzt,
- SFTP-Zugriff mit OpenSSH einrichtest,
- Docker und Caddy verwendest, um eine statische Website bereitzustellen,
- alle Logs deaktivierst,
- und automatische Updates per Watchtower einrichtest.
🔁 Hinweis: Überall, wo example.com oder examplecom steht, musst du deinenr kommagetren echten Domainnamen einsetzen (z. B. simon99.de oder simon99de).
Wir legen für jede Website einen eigenen User an, damit man die Webseiten dann einfacher ist, für verschiedene Webseiten zu nutzen.
Überall wo webadmin steht, kann man es lassen oder überall auch ändern in etwas anderes. das ist ein 2. Benutzer für die Docker user Umgebung, da Docker keinChrootDirectory root mag.
Sichere SSH Verbindung (Linux Desktop)
Für dein Linux-Setup (z. B. Publii-Upload, SSH-Zugang, SFTP) ist es am besten, wenn du einen ganz normalen OpenSSH-Schlüssel nutzt anstatt ein Passwort:
ssh-keygen -t ed25519 -C "user@deine.server.ip.adresse"Das erstellt automatisch:
~/.ssh/id_ed25519(privater Schlüssel)~/.ssh/id_ed25519.pub(öffentlicher Schlüssel)
Dann einfach den Public Key auf dem Server in ~/.ssh/authorized_keys eintragen.
Abschließend SSH / Server neu starten (Auf dem Server):
sudo systemctl restart ssh🔧 SSH-Konfiguration (empfohlen):
Bearbeite (Linux Desktop):
nano ~/.ssh/configTrage z. B. ein:
Host vserver1
HostName deine.server.ip.adresse
User root
IdentityFile ~/.ssh/private-schlüssel-datei
Port 22Dann kannst du dich ganz einfach verbinden mit:
ssh vserver1🔐 Vergiss nicht (wenn nicht bereits so erstellt wurde):
chmod 600 ~/.ssh/private-schlüssel-datei🔧 V-Server vorbereiten (Debian 13)
Installiere ein frisches Debian 13-Image auf deinem V-Server. Dadurch wird sichergestellt, dass keinerlei Altlasten oder Logdateien vorhanden sind.
Als Root-Nutzer einmal updaten und Werkzeuge installieren:
apt update && apt upgrade -yapt install -y curl nano ufw gnupg2 ca-certificates lsb-release apt-transport-https unattended-upgrades needrestart
Firewall konfigurieren:
Firewall absichern (nur 22, 80, 443):
Nur nötig, wenn du deine Ports schützen willst. Kann optional übersprungen werden.
ufw default deny incomingufw default allow outgoingufw allow 22/tcpufw allow 80/tcpufw allow 443/tcpufw enable
🧰 Sicherheitsupdates aktivieren:
sudo dpkg-reconfigure --priority=low unattended-upgradesWähle „Yes“, um automatische Sicherheitsupdates zu aktivieren.
Updates anpassen:
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades🧹 Automatische Bereinigung (optional)
Damit bleiben keine alten Kernel oder Bibliotheken übrig.
// entfernen:Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";Unattended-Upgrade::Remove-Unused-Dependencies "true";
Suche und ersetze die zeile für automatische neustarts (etwar mittig in der datei):
// entfernen und auf true setzen:Unattended-Upgrade::Automatic-Reboot "true";
Hier stellt man ein, wann der neustart gemacht werden soll:
// entfernen und eine Uhrzeit deiner Wahl wählen:Unattended-Upgrade::Automatic-Reboot-Time "03:30";
und das noch ganz am ende einfügen:// Das sorgt dafür, dass Sicherheitsupdates erst nach 14 Tagen Wartezeit installiert werden // damit sie nicht sofort eingespielt werden, falls sie fehlerhaft sind.Unattended-Upgrade::MinimumAge "14";
Update häufigkeit anpassen:
sudo nano /etc/apt/apt.conf.d/10periodichier kommt der Inhalt rein:
APT::Periodic::Update-Package-Lists "1";APT::Periodic::Download-Upgradeable-Packages "1";APT::Periodic::Unattended-Upgrade "1";APT::Periodic::AutocleanInterval "7";
🧪 Testen: (optional)
Zum Test, ob alles funktioniert:
sudo unattended-upgrades --dry-run --debugohne sie wirklich zu installieren.
🔐 OpenSSH mit SFTP einrichten (statt FTP oder SFTPGo)
Benutzer Anlegen:
Erstelle einen Benutzer für z. B. Publii, deine Website zum hochladen – z. B. examplecom:
sudo adduser examplecomsshd_config anpassen:
Dann mit sudo nano /etc/ssh/sshd_config folgende Zeilen am Ende einfügen:
das bewirkt, dass der User nur die SFTP Verbindung ohne SSH nutzen kann.
Match User examplecom
ChrootDirectory /home
ForceCommand internal-sftp -d /%u
AllowTcpForwarding no
X11Forwarding no
Mit STRG + O und dann Enter Speichert man dann die Datei.
Mit STRG + X verlässt man die Datei / den nano Editor dann
Kann mehrere user aufnehmen mit zb.:
Match User examplecom,examplede,exampleorg
...
Abschließend SSH neu starten:
sudo systemctl restart sshJetzt kann Publii via SFTP (OpenSSH) direkt in /home/ bzw. in /home/examplecom/ Webseiten hochladen.
📦 Docker und Docker Compose installieren
Jetzt erstelle einen Benutzer für deine Website / Docker-Umgebung, wenn du als root user eingeloggt bist. da gebe ich dir 2 Möglichkeiten. einmal ohne ssh + passwort und einmal mit (A und B)
A: ohne Passwort / Login – z. B.
webadmin:adduser --disabled-password --gecos "" webadminLogin über den befehl möglich als zb. root oder ein anderer Nutzer:
su - webadminB: mit Passwort / Login – z. B.
webadmin:adduser webadmin
Den aktuellen Benutzer der Docker-Gruppe hinzufügen:
getent group docker || sudo groupadd dockersudo usermod -aG docker webadmin
(Danach ggf. einmal neu einloggen)
Docker-Repository hinzufügen:
docs.docker.com (Offizielle Anleitung)
1. Docker einrichten aptRepository.
# Add Docker's official GPG key:sudo apt-get updatesudo apt-get install ca-certificates curlsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.asc# Add the repository to Apt sources: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/nullsudo apt-get update
Docker installieren & starten:
2. Installieren Sie die Docker-Pakete.
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginDocker starten & prüfen:
Docker beim Boot starten
Meist schon aktiv, aber sicherheitshalber:sudo systemctl enable --now dockerDer Docker-Dienst startet nach der Installation automatisch. Um zu überprüfen, ob Docker läuft, verwenden Sie:
sudo systemctl status dockerBei einigen Systemen ist dieses Verhalten möglicherweise deaktiviert und erfordert einen manuellen Start:
sudo systemctl start docker
3. Überprüfen Sie, ob die Installation erfolgreich war, indem Sie den hello-world Bild:
sudo docker run hello-world
🌐 Website per Docker + Caddy bereitstellen (ohne Logs, mit HTTPS)
Login über den befehl möglich als zb. root oder als Nutzer einloggen:
su - webadminErstelle ein Arbeitsverzeichnis (z. B. /home/webadmin/docker) und wechsle hinein:
mkdir -p ~/docker
cd ~/docker📄 Caddyfile anlegen
Erstelle eine Datei namens Caddyfile mit folgendem Inhalt – angepasst an deinen Domainnamen:
nano Caddyfile# Catch-All fuer unbekannte Domains oder direkte IP-Aufrufe. Nur http / 80 moeglich, https funktioniert nicht.
:80 {
redir https://example.com/
log {
output discard
}
}
# www Redirect, Weiterleitung an "redir ..."
www.example.com,
wwww.example.com,
ww.example.com,
w.example.com {
redir https://example.com{uri}
log {
output discard
}
}
# Hauptdomain
example.com {
root * /srv/www/examplecom
file_server
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.html
file_server
}
log {
output discard
}
} Diese Konfiguration sorgt für:
- 📦 HTTPS + automatische Zertifikate über Let's Encrypt
- 🔁 Weiterleitung von www.example.com → example.com
- ❌ Keine Logs durch
output discard - 🧭 Eine eigene
404.html-Seite bei Fehlern
Mit STRG + O und dann Enter Speichert man dann die Datei.
Mit STRG + X verlässt man die Datei / den nano Editor dann
🛠️ Docker Compose-Datei erstellen
Lege die Datei docker-compose.yml im selben Verzeichnis an:
nano docker-compose.ymlservices:
caddy:
image: caddy:alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:///etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
- /home/examplecom:/srv/www/examplecom
labels:
- "com.centurylinklabs.watchtower.enable=true"
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_LABEL_ENABLE=true
- WATCHTOWER_POLL_INTERVAL=1209600 # 14 Tage in Sekunden
volumes:
caddy_data:
caddy_config:hier muss man etwas ändern und zwar darf hier keine 3 /// sondern nur eines stehen!: - ./Caddyfile:///etc/caddy/Caddyfile also: ...:/etc/caddy/Caddyfile
(ist ein Bug bei der Website bei mir)
- 📂 Caddyfile: definiert alle Domains, Weiterleitungen, Dateipfade und Einstellungen.
- 📁 /home/examplecom/: dort liegen die von Publii erzeugten Website-Dateien.
- 🔁 Watchtower: aktualisiert automatisch alle Container alle 14 Tage (
1209600 Sekunden).
🚀 Container starten
Starte jetzt Caddy + Watchtower:
docker compose up -dDie Website ist danach per https://example.com erreichbar – mit automatischem HTTPS und ohne jegliche Logs.
🧱 Hinweis für Publii: Remote-Pfad korrekt einstellen
Publii lädt standardmäßig in einen Ordner namens examplecom/ hoch. Genau dieser Ordner wird im Container als Website-Wurzel verwendet.
Wichtig: Da du dich per SFTP direkt in /home/examplecom/ befindest, trägst du bei Publii einfach nur ein:
- Remote-Pfad:
/examplecom/(vor und nach Domain ein "/") - (wird normalerweise nicht benötigt, dank
d /%uin sshd config/ sFTP, aber kann zu Probleme kommen, wenn nichts eingetragen ist, muss es aber nicht)
Die Dateien landen dann exakt dort, wo Caddy sie erwartet.
🔐 Datenschutz & rechtlicher Hinweis
Mit der hier beschriebenen Konfiguration ist deine Website besonders datenschutzfreundlich:
- Es werden keinerlei Besucher-Logs oder IP-Adressen gespeichert (
output discardin Caddy). - Es gibt keine Cookies, da keine Benutzerdaten verarbeitet werden.
- Keine externen Tracker oder Skripte eingebunden.
- Keine Fonts von Google oder anderen Anbietern eingebunden.
Datenschutzfreundliche Konfiguration:
Achtung: Wenn du externe Inhalte wie YouTube-Videos, Karten (z. B. Google Maps) oder andere eingebettete Dienste verwendest, musst du diese ggf. blockieren, bis der Besucher zugestimmt hat (Cookiebanner / Consent-Tool). Zudem musst du sie im Datenschutz erwähnen und anpassen.
Die hier bereitgestellten Informationen stellen keine Rechtsberatung dar. Datenschutzgesetze (wie die DSGVO) ändern sich, daher übernehme ich keine Haftung für die rechtliche Vollständigkeit oder Aktualität. Im Zweifel solltest du rechtlichen Rat einholen.
📄 Beispielabschnitt für deine Datenschutzerklärung
3. Hosting und Server-Log-Dateien
Der Webserver dieser Website wird vollständig selbst betrieben (Selfhosting). Dabei kommen keine externen Hostingdienste, Content Delivery Networks (CDNs) oder Drittanbieter-Tools zum Einsatz. Es erfolgt keine Auswertung des Nutzerverhaltens, keine Speicherung von IP-Adressen und keine Erstellung von Server-Log-Dateien auf dem Server selbst. Auch auf das Setzen von Cookies wird verzichtet.
Zur Auslieferung der Inhalte wird der Webserver „Caddy“ verwendet. Dieser wurde so konfiguriert, dass keine Protokolle gespeichert werden („output discard“).
Die Datenübertragung erfolgt ausschließlich über verschlüsselte HTTPS-Verbindungen (TLS/SSL), um die Vertraulichkeit und Integrität der übertragenen Daten zu gewährleisten.
Hinweis: Bei einigen Hosting-Anbietern (z. B. V-Server oder Root-Server) kann es sein, dass im Rahmen der Infrastrukturüberwachung – etwa bei Angriffen wie DDoS – bestimmte Verbindungsdaten wie IP-Adresse und Port temporär und automatisiert erfasst und geloggt werden. Diese Vorgänge erfolgen außerhalb des eigenen Servers und liegen in der Verantwortung des Hosting-Anbieters. In der Regel werden diese Daten nur im Angriffsfall analysiert und anschließend gelöscht.Hier wurde Teilweise bei der Anleitung mit KI Zusammengearbeitet und teilweise aus eigener Hand geschrieben, da KI die Anleitung () nicht gut genug geschrieben hat, habe ich sie verändert / neu geschrieben und aktualisiert auf Debian 13
