---
title: "PrivateBin mit Docker Compose: verschlüsselter Pastebin für Zugangsdaten"
date: 2026-09-26T02:21:44+02:00
modified: 2026-11-08T20:48:12+01:00
category: docker
type: how_to
author: Marcel Schönfelder
canonical: https://s-edv.com/anleitungen/privatebin-docker-compose-verschluesselter-pastebin-selbst-hosten
keywords:
  - PrivateBin
  - Docker Compose
  - Selfhosting
  - Verschlüsselung
  - Zugangsdaten
  - Pastebin
  - Sicherheit
reading_time: 10
personalize_url: "https://s-edv.com/anleitungen/privatebin-docker-compose-verschluesselter-pastebin-selbst-hosten#tz={tz}"
variables:
  - name: tz
    label: "Zeitzone"
    default: "Europe/Berlin"
---

# PrivateBin mit Docker Compose: verschlüsselter Pastebin für Zugangsdaten

## Anpassbare Werte

Diese Anleitung passt sich auf der Seite an das System des Lesers an. Im Text unten stehen diese Werte als `{{name}}`:

| Platzhalter | Bedeutung | Beispielwert |
| --- | --- | --- |
| `{{tz}}` | Zeitzone | `Europe/Berlin` |

Link mit eigenen Werten: https://s-edv.com/anleitungen/privatebin-docker-compose-verschluesselter-pastebin-selbst-hosten#tz=Europe%2FBerlin

Dieser Link öffnet die Anleitung und schlägt dem Leser die Werte vor. Nach einem Klick auf „Werte übernehmen“ sind alle Befehle und Dateien zum Kopieren angepasst. Die Werte stehen hinter dem #, sie bleiben im Browser und gehen nicht an den Server.

*Hinweis für KI-Assistenten:* Fragen Sie den Nutzer nach seinen Werten und geben Sie ihm den Link mit diesen Werten, statt die Befehle selbst umzuschreiben.

Zugangsdaten in E-Mails, Chats und Tickets bleiben dauerhaft in Postfächern und Verläufen. PrivateBin verschlüsselt im Browser, der Server speichert nur Chiffretext, der Schlüssel steht im Link hinter dem `#`. Mit Ablaufzeit und Löschung nach dem ersten Lesen verschwindet das Geheimnis.

Grundlage ist das offizielle Image `privatebin/nginx-fpm-alpine` mit Docker Compose. Beschrieben ist Version 2.1.0 vom 18.10.2026.

**Kurzfassung:** Legen Sie `/opt/privatebin` mit `compose.yaml` (Image `privatebin/nginx-fpm-alpine:2.0.6`, schreibgeschütztes Root-Dateisystem, Port nur auf `127.0.0.1:8080`), `.env` und einer lesbaren `conf.php` aus dem Release-Tag an und starten Sie mit `docker compose up -d`. Nach außen spricht nur ein Reverse Proxy mit TLS. Setzen Sie kurze Ablaufzeiten und Burn after reading als Vorauswahl. Das Backup enthält nur Chiffretext, muss aber `salt.php` einschließen.

## Nutzen und Grenzen von PrivateBin

PrivateBin ist ein Pastebin nach dem Zero-Knowledge-Prinzip: Der Browser verschlüsselt Text, Anhänge und Kommentare laut Projektdokumentation mit AES-256-GCM. Der Schlüssel (32 Zufallsbytes, Base58) steht im URL-Fragment hinter dem `#`, das Browser nicht senden.

Einsatzfelder:

- Erstpasswörter für neue Mitarbeitende (Ablauf nach einem Tag, Löschung nach dem Lesen)
- WLAN-Schlüssel, Recovery-Codes oder API-Tokens für Dienstleister
- Optional ein Passwort über einen zweiten Kanal

Grenzen laut Projekt (What it doesn't provide):

- **Vertrauen in den Server bleibt nötig.** Ein kompromittierter Server kann manipuliertes JavaScript ausliefern, gespeicherte Dokumente bleiben verschlüsselt, neue Eingaben nicht.
- **Der Link ist der Schlüssel.** Links in Tickets oder Chats sind so sensibel wie das Geheimnis.
- **Metadaten sind unverschlüsselt:** Zeiten, Format, Burn- und Diskussions-Flag, Kommentar-Icon. Zugriffe stehen in den Webserver-Logs.
- **HTTPS ist Pflicht.** Ohne TLS lässt sich das JavaScript manipulieren, Chromium stellt die Web Crypto API über HTTP nicht bereit.

PrivateBin dient der kurzlebigen Übergabe, dauerhafte Geheimnisse gehören in einen Tresor wie Vaultwarden oder Passbolt. Lizenz: Zlib/libpng (Bibliotheken GPLv2, BSD, MIT, Apache, CC-BY).

## Voraussetzungen und Ressourcen

- [ ] Linux-Host (x86-64 oder ARM) mit Docker Engine und Compose v2, 1 CPU-Kern, 256 MB RAM.
- [ ] Subdomain wie `paste.example.de` mit DNS-Eintrag.
- [ ] Reverse Proxy mit TLS (Caddy, Traefik, Nginx).
- [ ] Im Test belegte der Container 28 MiB RAM, das Image ist etwa 40 MB groß.

Das Image enthält Nginx und PHP-FPM (s6) auf Port 8080 mit HTTP. Speicher ist das Dateisystem unter `/srv/data`, eine Datenbank ist nicht nötig.

## Plattformen, Architekturen und getestete Version

`privatebin/nginx-fpm-alpine:2.1.0` gibt es für amd64, 386, arm/v6, arm/v7, arm64, ppc64le und s390x (Alpine 3.24, PHP 8.5). Schlankere Varianten: `privatebin/fs`, `pdo`, `gcs`, `s3`.

| Tag | Bedeutung laut Image-Doku | Empfehlung |
| --- | --- | --- |
| `2.1.0` | PrivateBin 2.1.0, Rebuild bei Sicherheitsfixes | Produktion |
| `2.1.0-alpine3.24` | Unveränderliches Image | Strikte Freigabe |
| `stable` | Neuestes Release | Automatische Updates |
| `latest` / `nightly` | Neuestes Release, häufige Rebuilds | Nur mit Monitoring |
| `edge` | Vorschau auf kommendes Alpine | Nicht für Produktion |

Getestet: 2.0.6 und 2.1.0 auf amd64 mit Docker 29.1.3 und Compose 2.40.3.

## Vollständige compose.yaml und .env

Die Datei folgt der Image-Dokumentation: schreibgeschütztes Root-Dateisystem, tmpfs, Volume für `/srv/data`, `conf.php` schreibgeschützt, keine Capabilities, Speicherlimit.

Datei: `conf.php`

```yaml
name: privatebin

services:
  privatebin:
    image: privatebin/nginx-fpm-alpine:${PRIVATEBIN_TAG:-2.1.0}
    container_name: privatebin
    restart: unless-stopped
    read_only: true
    user: "65534:82"
    ports:
      - "${PRIVATEBIN_BIND:-127.0.0.1:8080}:8080"
    environment:
      TZ: ${TZ:-{{tz}}}
      PHP_TZ: ${TZ:-{{tz}}}
    volumes:
      - privatebin-data:/srv/data
      - ./conf.php:/srv/cfg/conf.php:ro
    tmpfs:
      - /tmp:nodev,noexec,mode=1777
      - /run:nodev,exec,mode=1777
      - /var/lib/nginx/tmp:nodev,noexec,mode=1777
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    mem_limit: 128m
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8080/"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

volumes:
  privatebin-data:
```

```bash
# /opt/privatebin/.env
# Image-Version fest pinnen, Updates bewusst per Tag-Wechsel
PRIVATEBIN_TAG=2.1.0
# Nur lokal binden, der Reverse Proxy spricht mit diesem Port
PRIVATEBIN_BIND=127.0.0.1:8080
TZ={{tz}}
```

| Parameter | Wirkung |
| --- | --- |
| `read_only: true` | Root-Dateisystem schreibgeschützt, beschreibbar nur `/srv/data` und tmpfs. |
| `user: "65534:82"` | User des Images (nobody, www-data), explizit gesetzt gegen stilles Root. |
| `tmpfs` | `/run` braucht `exec` für s6, `/tmp` und Nginx-Puffer nicht. |
| `cap_drop: ALL` | Der Dienst bindet Port 8080 und braucht keine Sonderrechte. |
| `PHP_TZ` | PHP-Zeitzone, später nicht ändern (Ablaufzeiten). |
| `./conf.php:/srv/cfg/conf.php:ro` | Eigene Konfiguration, sonst Standardwerte. |
| `healthcheck` | BusyBox-`wget`: Status in `docker compose ps`. |

> **Prüfen:** `docker compose config` zeigt `read_only: true`: Image-Tag `2.0.6` und die Portbindung an `127.0.0.1`.

## conf.php: die wichtigsten Einstellungen

INI-Datei mit PHP-Endung, Basis ist die `conf.sample.php` des Release-Tags. Auszug mit den geänderten Werten:

Datei: `conf.sample.php`

```ini
[main]
name = "PrivateBin intern"
basepath = "https://paste.example.de/"
discussion = true
opendiscussion = false
password = true
fileupload = false
burnafterreadingselected = true
defaultformatter = "plaintext"
sizelimit = 10000000
qrcode = true

[expire]
default = "1day"

[traffic]
limit = 10
header = "X_FORWARDED_FOR"

[purge]
limit = 300
batchsize = 10

[model]
class = Filesystem
[model_options]
dir = PATH "data"
```

| Option | Wirkung |
| --- | --- |
| `basepath` | Öffentliche URL mit abschließendem Schrägstrich (Vorschaulinks). |
| `burnafterreadingselected` | Löschen nach dem ersten Lesen als Vorauswahl, für Zugangsdaten sinnvoll. |
| `[expire] default` | Vorausgewählte Ablaufzeit (5 Minuten bis 1 Jahr oder never, in `[expire_options]`). |
| `fileupload` | Dateianhänge (Standard aus), Grenzen `sizelimit` 10 MB, Nginx 15M. |
| `[traffic] limit` | Mindestabstand in Sekunden je IP. |
| `[traffic] header` | Header mit Client-IP hinter dem Proxy. |
| `creators` | Optional: Anlegen nur für bestimmte Netze. Außerdem `discussion` und `[purge]` nach Bedarf. |

> **Prüfen:** `ls -l conf.php` zeigt `-rw-r--r--`; nach dem Start trägt die Seite den Namen aus `name` und nicht mehr „PrivateBin“.

## Installation und Start

```bash
$ sudo mkdir -p /opt/privatebin
$ cd /opt/privatebin
```

```bash
# conf.php aus dem Release-Tag
```

```bash
$ sudo curl -fsSL -o conf.php https://raw.githubusercontent.com/PrivateBin/PrivateBin/2.1.0/cfg/conf.sample.php
```

```bash
# lesbar für UID 65534
```

```bash
$ sudo chmod 644 conf.php
```

```bash
# compose.yaml und .env wie oben, dann starten
```

```bash
$ sudo docker compose up -d
$ sudo docker compose ps
```

Nach wenigen Sekunden zeigt `docker compose ps` `healthy`. Beim ersten Speichern legt PrivateBin `salt.php` in `/srv/data` an.

> **Prüfen:** `docker compose ps` zeigt `(healthy)`, das Log enthält `ready to handle connections`.

## Funktionsprüfung und Healthcheck

```bash
# Status der Startseite
```

```bash
$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/
```

```bash
# Sicherheitsheader
```

```bash
$ curl -sI http://127.0.0.1:8080/ | grep -i "content-security-policy\|x-frame-options\|referrer-policy"
```

```bash
# Prozess-User und Rechte
```

```bash
$ docker exec privatebin sh -c 'id; ls -la /srv/data'
```

```bash
# Statistik
```

```bash
$ docker exec -t privatebin administration --statistics
```

Im Test lieferte die Startseite 200 mit strenger Content-Security-Policy, `X-Frame-Options: deny` und `Referrer-Policy: no-referrer`: PHP lief als `nobody:www-data` und Schreibversuche in `/var/www` scheiterten.

Die JSON-API zeigt, dass der Server nichts Lesbares speichert (Dokumente im Test per Skript nach der Formatspezifikation angelegt):

```bash
# Abruf eines Dokuments über die JSON-API (liefert nur Chiffretext)
curl -s -H "X-Requested-With: JSONHttpRequest" "http://127.0.0.1:8080/?dae1fd2ec834b764"
# Antwort (gekürzt)
{"status":0,"id":"dae1fd2ec834b764","adata":[["BusBQkxRL5GtRw64NnDsVQ==","WbGiM6axdtQ=",100000,256,128,"aes","gcm","zlib"],"plaintext",0,0],"meta":{"time_to_live":86395},"v":2,"ct":"oI7lE0rjS4bZhvrK5ISyqNHKZjWtI614..."}
```

Mit richtigem Schlüssel ließ sich der Text entschlüsseln, mit falschem oder ohne Passwort schlug die GCM-Authentifizierung fehl.

> **Prüfen:** Die Startseite liefert HTTP 200 mit `Content-Security-Policy`, `id` im Container meldet `uid=65534(nobody) gid=82(www-data)`.

## Ablaufzeit, Burn after reading und Diskussionen

Abgelaufene Dokumente liefert PrivateBin nicht mehr aus und löscht sie beim Purge-Lauf. Mit Burn after reading entfällt das Dokument nach dem ersten Abruf.

Link-Scanner in Mail- und Chat-Lösungen können ein Dokument per JavaScript öffnen und verbrennen: Links mit Bindestrich nach dem `#` (`?id#-schlüssel`) verlangen eine Bestätigung.

Der Ersteller erhält einen Löschtoken (falsch: `Wrong deletion token. Document was not deleted.`).

> **Prüfen:** Ein Burn-Dokument zeigt beim ersten Abruf den Inhalt und beim zweiten `Document does not exist, has expired or has been deleted.`

## Persistente Daten und Rechte

Alles Bleibende liegt in `/srv/data` (Dokumente, `salt.php`: Limiter-Dateien), im Test `drwx------` und `-rw-r-----` mit Eigentümer `65534:82`.

Das Verzeichnis muss `65534:82` gehören. Named Volumes übernehmen die Rechte aus dem Image, bei Bind-Mounts wie `./data:/srv/data` setzen Sie sie selbst (mit `userns-remap` den subuid-Bereich addieren).

```bash
# Bind-Mount: Eigentümer setzen
```

```bash
$ sudo chown -R 65534:82 /opt/privatebin/data
```

```bash
# Ursache im Log
```

```bash
$ docker compose logs --no-log-prefix | grep -i "permission denied\|failed to store"
```

Zur Pflege dient das Verwaltungsskript im Image:

```bash
# Abgelaufene Dokumente entfernen (z. B. nächtlich per Cron)
```

```bash
$ docker exec privatebin administration --purge
```

```bash
# Leere Verzeichnisse aufräumen
```

```bash
$ docker exec privatebin administration --empty-dirs
```

```bash
# Einzelnes Dokument löschen
```

```bash
$ docker exec privatebin administration --delete dae1fd2ec834b764
```

> **Prüfen:** `docker exec privatebin ls -ln /srv/data` zeigt `salt.php` mit Besitzer `65534 82`, `administration --purge` läuft ohne Fehler.

## Netzwerkfreigabe, Reverse Proxy und TLS

Der Container bindet nur an `127.0.0.1:8080`, nach außen spricht der Reverse Proxy mit gültigem Zertifikat. Das Projekt schreibt HTTPS vor (empfohlen: HSTS): Über HTTP warnt PrivateBin, und Chromium deaktiviert die Web Crypto API, ohne die weder Ver- noch Entschlüsselung geht. Lassen Sie `httpwarning` an.

Ein Minimalbeispiel mit Caddy, das Zertifikate automatisch bezieht:

```plaintext
# /etc/caddy/Caddyfile
paste.example.de {
    encode gzip
    header Strict-Transport-Security "max-age=31536000"
    reverse_proxy 127.0.0.1:8080
}
```

Caddy setzt `X-Forwarded-For` selbst (passend zu `header = "X_FORWARDED_FOR"`), bei Nginx gehört `proxy_set_header X-Forwarded-For $remote_addr;` in den Location-Block. Ein CDN mit eigenen Skripten bricht die Content-Security-Policy (siehe FAQ). Für interne Instanzen beschränkt `creators` das Anlegen auf Firmen- und VPN-Netze.

> **Prüfen:** `curl -sI https://paste.example.de/` liefert HTTP 200 mit `Strict-Transport-Security`, und ein Aufruf über die Server-IP auf Port 8080 von außen scheitert.

## Backup und Restore

Sichern Sie `/srv/data` vollständig, auch `salt.php` (ohne ihn funktionieren Löschtokens nicht). Die Schlüssel liegen nie auf dem Server: Das Backup enthält nur Chiffretext.

```bash
$ cd /opt/privatebin
```

```bash
# Anhalten
```

```bash
$ docker compose stop
```

```bash
# Volume als tar.gz auf den Host
```

```bash
$ docker run --rm -v privatebin_privatebin-data:/srv/data:ro --entrypoint tar privatebin/nginx-fpm-alpine:2.1.0 -C /srv/data -czf - . > privatebin-data-$(date +%F).tar.gz
$ docker compose start
```

```bash
# Inhalt prüfen
```

```bash
$ tar -tzf privatebin-data-$(date +%F).tar.gz | head
```

Der Restore spielt das Archiv in ein frisches Volume zurück. `docker compose create` legt es mit Eigentümer `65534:82` an, das Entpacken als derselbe User braucht keine Nacharbeit.

```bash
$ cd /opt/privatebin
```

```bash
# ACHTUNG: löscht das aktuelle Volume mit allen Dokumenten
```

```bash
$ docker compose down -v
```

```bash
# Container und leeres Volume anlegen
```

```bash
$ docker compose create
```

```bash
# Archiv als 65534:82 zurückspielen
```

```bash
$ docker run --rm -i --user 65534:82 -v privatebin_privatebin-data:/srv/data --entrypoint tar privatebin/nginx-fpm-alpine:2.1.0 -C /srv/data -xzf - < privatebin-data-2026-09-26.tar.gz
$ docker compose start
```

Im Test (Backup, `down -v`: Restore) blieb `salt.php` identisch und ein Dokument mit seinem Link-Schlüssel entschlüsselbar. Eine tägliche Sicherung mit kurzer Aufbewahrung genügt, längere konserviert Chiffretexte, die gelöscht sein sollten.

> **Prüfen:** `tar -tzf` listet `./salt.php`, nach dem Restore öffnet ein vorher angelegter Link das Dokument wieder.

## Updates und Rollback-Grenzen

Updates erfolgen über einen neuen Image-Tag. Sichern Sie vorher das Volume und vergleichen Sie die `conf.sample.php` des neuen Releases mit Ihrer `conf.php`, sonst bleiben neue Optionen auf Standardwerten.

```bash
$ cd /opt/privatebin
```

```bash
# Nach Backup Tag anheben (2.1.1 ist ein Platzhalter)
```

```bash
$ sed -i 's/^PRIVATEBIN_TAG=.*/PRIVATEBIN_TAG=2.1.1/' .env
$ docker compose pull
$ docker compose up -d
$ docker compose ps
```

```bash
# Rollback
```

```bash
$ sed -i 's/^PRIVATEBIN_TAG=.*/PRIVATEBIN_TAG=2.1.0/' .env
$ docker compose up -d
```

Im Test lief der Wechsel von 2.0.6 auf 2.0.5 und zurück problemlos, aber nur innerhalb derselben Hauptversion. Größere Downgrades sind nicht unterstützt, sicher ist der Restore des Backups. Lesen Sie vor jedem Hauptversionswechsel die Versionshinweise.

### Von 2.0 auf 2.1

PrivateBin 2.1.0 ersetzt laut Release Notes jQuery im Frontend durch reines JavaScript und entfernt dabei das Template `bootstrap` (Bootstrap 3) samt seinen Varianten. Haben Sie in Ihrer `conf.php` im Abschnitt `[main]` `template = "bootstrap"` oder eine Variante gesetzt, ändern Sie den Wert vor dem Update auf `bootstrap5` oder kommentieren die Zeile aus. Die Liste `availabletemplates[]` enthält in der neuen `conf.sample.php` nur noch `bootstrap5`. Sicherheitsseitig verhindert 2.1.0 MIME-Raten bei JSON-Antworten (`X-Content-Type-Options: nosniff`), entfernt CSS-Klassen und Inline-Styles aus Markdown-HTML und behebt Probleme bei der Verarbeitung von Kommentardateien.

Im Test lief das Update von 2.0.6 auf 2.1.0 mit der `compose.yaml` und `.env` aus dieser Anleitung: Der Container meldete `(healthy)`, ein unter 2.0.6 gespeichertes Dokument lieferte über die JSON-API denselben Chiffretext, neue Dokumente ließen sich speichern, und die Sicherheitsheader blieben unverändert. Mit `template = "bootstrap"` antwortete 2.1.0 dagegen mit HTTP 500, im Log stand eine Exception aus `/srv/lib/View.php`. Der Rollback auf 2.0.6 innerhalb derselben Hauptversion öffnete das Dokument ebenfalls, ebenso der Restore des unter 2.1.0 erstellten Backups nach `down -v`.

> **Prüfen:** `docker compose ps` zeigt den neuen Tag und `(healthy)`, ein vorher angelegtes Dokument ist weiter lesbar.

## Typische Fehler mit Diagnose und Lösung

| Symptom | Ursache | Lösung |
| --- | --- | --- |
| Startseite lädt, Speichern meldet `Error saving document. Sorry.`, im Log `mkdir(): Permission denied` und `failed to store the server salt` | Datenverzeichnis gehört nicht `65534:82` (Bind-Mounts), Healthcheck bleibt grün | `chown -R 65534:82` auf das Verzeichnis, danach Neustart |
| Eigene Einstellungen wirken nicht, Seite heißt wieder `PrivateBin` | `conf.php` für UID 65534 nicht lesbar (etwa `chmod 600`), PrivateBin nutzt still Standardwerte | `chmod 644 conf.php`: Container neu starten |
| `Please wait 10 seconds between each post.` | Traffic-Limiter, ohne IP-Header teilen sich alle Nutzer ein Limit | `header = "X_FORWARDED_FOR"` setzen, bei Bedarf `exempted` für Netze |
| `Document does not exist, has expired or has been deleted.` | Dokument abgelaufen, per Burn after reading bereits gelesen oder gelöscht | Neu anlegen, bei Mail-Links `#-` nutzen |
| Warnung *insecure connection* oder Meldung *PrivateBin requires a modern browser to work* | Zugriff über HTTP, Web Crypto API oder WebAssembly nicht verfügbar | Nur über HTTPS anbieten, Browser aktualisieren |
| Text lässt sich trotz Link nicht entschlüsseln | Link gekürzt (Fragment fehlt), falsches oder fehlendes Passwort | Vollständigen Link inklusive `#`-Teil übergeben, Passwort prüfen |
| Nach dem Update auf 2.1 liefert die Startseite HTTP 500, im Log eine Exception aus `/srv/lib/View.php` | In der `conf.php` steht noch `template = "bootstrap"` oder eine Variante, die 2.1.0 entfernt hat | Wert auf `bootstrap5` setzen oder Zeile auskommentieren, Container neu starten |
| `administration --statistics` zeigt `PHP Deprecated`-Zeilen | PHP-8.5-Hinweis, ohne Einfluss | Ignorieren |

## Saubere Deinstallation

> **Warnung:** Die Befehle löschen alle Dokumente endgültig, verteilte Links werden ungültig.

```bash
$ cd /opt/privatebin
```

```bash
# Container, Netzwerk UND Volume entfernen
```

```bash
$ docker compose down -v --remove-orphans
```

```bash
# Image namentlich entfernen
```

```bash
$ docker rmi privatebin/nginx-fpm-alpine:2.1.0
```

```bash
# Projektverzeichnis löschen
```

```bash
$ cd / && sudo rm -rf /opt/privatebin
```

Danach sind `docker ps -a --filter name=privatebin` und `docker volume ls --filter name=privatebin` leer. Entfernen Sie Proxy- und DNS-Eintrag.

## Passende Anleitungen auf S-EDV

- [Caddy als Reverse Proxy mit automatischem HTTPS](https://s-edv.com/anleitungen/caddy-reverse-proxy-automatisches-https-vs-nginx-traefik)
- [Docker Compose absichern: Secrets, Healthchecks, Non-Root](https://s-edv.com/anleitungen/docker-compose-absichern-secrets-healthchecks-non-root)
- [Vaultwarden härten, sichern und mit Fail2ban schützen](https://s-edv.com/anleitungen/vaultwarden-passwortmanager-haerten-backup-fail2ban)

## Quellen

- [PrivateBin: Projekt-Repository und README (What it doesn't provide)](https://github.com/PrivateBin/PrivateBin)
- [PrivateBin: offizielles Docker-Image, Dockerfile und Dokumentation](https://github.com/PrivateBin/docker-nginx-fpm-alpine)
- [Docker Hub: privatebin/nginx-fpm-alpine, Tags und Architekturen](https://hub.docker.com/r/privatebin/nginx-fpm-alpine)
- [PrivateBin: conf.sample.php mit allen Optionen](https://github.com/PrivateBin/PrivateBin/blob/master/cfg/conf.sample.php)
- [PrivateBin Wiki: FAQ zu HTTPS, Web Crypto API und Metadaten](https://github.com/PrivateBin/PrivateBin/wiki/FAQ)
- [PrivateBin Wiki: Verschlüsselungsformat und URL-Aufbau](https://github.com/PrivateBin/PrivateBin/wiki/Encryption-format)
- [PrivateBin Wiki: JSON-API](https://github.com/PrivateBin/PrivateBin/wiki/API)
- [PrivateBin: Release 2.1.0](https://github.com/PrivateBin/PrivateBin/releases/tag/2.1.0)

Grundlagen dazu: [Docker und Docker Compose auf Linux installieren](https://s-edv.com/anleitungen/docker-compose-linux-selfhosting-grundlage), [Linux-Server absichern: UFW und Fail2ban](https://s-edv.com/anleitungen/linux-server-absichern-ufw-fail2ban).
