Dateien teilen auf die smarte Art: Plik selbst hosten mit Docker

82 % der Menschen verwenden unsichere File-Sharing-Tools.
Dabei geht’s auch anders – schnell, modern, selbstbestimmt.
Wenn du Plik nutzt, behältst du die Kontrolle – ohne auf Komfort verzichten zu müssen.

Ich zeige dir heute, wie du Plik ganz einfach mit Docker selbst betreibst – inklusive Web-Upload, curl-Support und sogar Streaming ohne Zwischenspeicherung.
Ob für dich selbst, dein Team oder im Internet.

🔍 Was ist Plik – und warum solltest du es nutzen?

Plik ist ein Open-Source-Dateiübertragungsdienst, den du selbst hosten kannst.
Er bietet eine schöne Web-Oberfläche, aber auch eine einfache API und curl-Support. Perfekt also für Power-User und Endanwender zugleich.

Was Plik besonders macht:

  • Keine Anmeldung nötig (optional möglich)
  • Dateien laufen über deinen eigenen Server
  • Lebensdauer, Passwortschutz, Streaming – alles mit an Bord
  • Der Dienst kann Dateien auch direkt von A nach B streamen, ohne sie zu speichern!

Wenn du bisher auf Tools wie WeTransfer oder File.io angewiesen warst, dann ist Plik eine super Alternative.

🐳 Schritt 1: Plik via Docker bereitstellen

Du brauchst nichts weiter als eine funktionierende Docker-Umgebung.
Erstelle dir z. B. folgende docker-compose.yaml:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
services:
plik:
image: rootgg/plik:latest
container_name: plik-app
hostname: plik-app
user: "1000:1000"
ports:
- "3000:3000"
volumes:
- ./data/files:/home/plik/server/files
- ./data/plikd.cfg:/home/plik/server/plikd.cfg:ro
- ./data/background1.jpg:/home/plik/webapp/dist/img/background.jpg:ro
environment:
- PLAK_DISABLE_AUTHENTICATION=false
- PLAK_DEBUG=true
- PLAK_DEFAULT_TTL=30d
restart: unless-stopped
services: plik: image: rootgg/plik:latest container_name: plik-app hostname: plik-app user: "1000:1000" ports: - "3000:3000" volumes: - ./data/files:/home/plik/server/files - ./data/plikd.cfg:/home/plik/server/plikd.cfg:ro - ./data/background1.jpg:/home/plik/webapp/dist/img/background.jpg:ro environment: - PLAK_DISABLE_AUTHENTICATION=false - PLAK_DEBUG=true - PLAK_DEFAULT_TTL=30d restart: unless-stopped
services:
  plik:
    image: rootgg/plik:latest
    container_name: plik-app
    hostname: plik-app
    user: "1000:1000"
    ports:
      - "3000:3000"
    volumes:
      - ./data/files:/home/plik/server/files
      - ./data/plikd.cfg:/home/plik/server/plikd.cfg:ro
      - ./data/background1.jpg:/home/plik/webapp/dist/img/background.jpg:ro
    environment:
      - PLAK_DISABLE_AUTHENTICATION=false
      - PLAK_DEBUG=true
      - PLAK_DEFAULT_TTL=30d
    restart: unless-stopped
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
- ./data/background1.jpg:/home/plik/webapp/dist/img/background.jpg:ro
- ./data/background1.jpg:/home/plik/webapp/dist/img/background.jpg:ro
  - ./data/background1.jpg:/home/plik/webapp/dist/img/background.jpg:ro

Optional: Mit dieser Zeile bindest du ein eigenes Hintergrundbild für das Webinterface von Plik ein.
Das Bild (background1.jpg) ersetzt den Standardhintergrund und sorgt für einen individuellen Look deiner File-Sharing-Seite.
So kannst du z. B. dein Logo, CI-Farben oder ein dezentes Design hinterlegen.

🔧 Tipp: Das Bild sollte im Format JPG oder PNG vorliegen und ca. 1920×1080 px groß sein.

Wenn du das nicht brauchst, kannst du diese Zeile einfach weglassen – Plik verwendet dann den Standardhintergrund.

⚙️ Schritt 2: Konfiguration

Die Konfigurationsdatei (plikd.cfg) ist das Herzstück.
Hier legst du Dinge wie Logging, Features, Download-Domain und Limits fest.

Erstelle die Konfigurationsdatei unter ./data/plikd.cfg und bearbeite sie:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# ─── Logging ───────────────────────────────────────────
Debug = true
DebugRequests = true
LogLevel = "INFO"
# ─── Netzwerk ──────────────────────────────────────────
ListenPort = 3000
ListenAddress = "0.0.0.0"
MetricsPort = 0
MetricsAddress = "0.0.0.0"
Path = ""
# SSL im Reverse Proxy, daher hier aus
SslEnabled = false
EnhancedWebSecurity = true
TlsVersion = "tlsv12"
# ─── Web Interface ─────────────────────────────────────
NoWebInterface = false
DownloadDomain = "https://share.domain.com"
DownloadDomainAlias = ["https://share.domain.com"]
WebappDirectory = "../webapp/dist"
AbuseContact = "abuse@domain.com"
SessionTimeout = "365d"
# ─── Upload Einschränkungen ───────────────────────────
UploadWhitelist = []
MaxFileSizeStr = "10GB"
MaxUserSizeStr = "unlimited"
MaxFilePerUpload = 100
DefaultTTLStr = "30d"
MaxTTLStr = "90d"
# ─── Feature Flags ─────────────────────────────────────
FeatureAuthentication = "disabled"
FeatureOneShot = "enabled"
FeatureRemovable = "enabled"
FeatureStream = "enabled"
FeaturePassword = "enabled"
FeatureComments = "enabled"
FeatureSetTTL = "enabled"
FeatureExtendTTL = "disabled"
FeatureClients = "enabled"
FeatureGithub = "enabled"
FeatureText = "enabled"
# ─── Daten-Backend ─────────────────────────────────────
DataBackend = "file"
[DataBackendConfig]
Directory = "files"
# ─── Metadaten-Backend (lokal, ohne Server-DB) ────────
[MetadataBackendConfig]
Driver = "sqlite3"
ConnectionString = "plik.db"
Debug = false
# ─── Logging ─────────────────────────────────────────── Debug = true DebugRequests = true LogLevel = "INFO" # ─── Netzwerk ────────────────────────────────────────── ListenPort = 3000 ListenAddress = "0.0.0.0" MetricsPort = 0 MetricsAddress = "0.0.0.0" Path = "" # SSL im Reverse Proxy, daher hier aus SslEnabled = false EnhancedWebSecurity = true TlsVersion = "tlsv12" # ─── Web Interface ───────────────────────────────────── NoWebInterface = false DownloadDomain = "https://share.domain.com" DownloadDomainAlias = ["https://share.domain.com"] WebappDirectory = "../webapp/dist" AbuseContact = "abuse@domain.com" SessionTimeout = "365d" # ─── Upload Einschränkungen ─────────────────────────── UploadWhitelist = [] MaxFileSizeStr = "10GB" MaxUserSizeStr = "unlimited" MaxFilePerUpload = 100 DefaultTTLStr = "30d" MaxTTLStr = "90d" # ─── Feature Flags ───────────────────────────────────── FeatureAuthentication = "disabled" FeatureOneShot = "enabled" FeatureRemovable = "enabled" FeatureStream = "enabled" FeaturePassword = "enabled" FeatureComments = "enabled" FeatureSetTTL = "enabled" FeatureExtendTTL = "disabled" FeatureClients = "enabled" FeatureGithub = "enabled" FeatureText = "enabled" # ─── Daten-Backend ───────────────────────────────────── DataBackend = "file" [DataBackendConfig] Directory = "files" # ─── Metadaten-Backend (lokal, ohne Server-DB) ──────── [MetadataBackendConfig] Driver = "sqlite3" ConnectionString = "plik.db" Debug = false
# ─── Logging ───────────────────────────────────────────
Debug               = true
DebugRequests       = true
LogLevel            = "INFO"

# ─── Netzwerk ──────────────────────────────────────────
ListenPort          = 3000
ListenAddress       = "0.0.0.0"
MetricsPort         = 0
MetricsAddress      = "0.0.0.0"
Path                = ""

# SSL im Reverse Proxy, daher hier aus
SslEnabled          = false
EnhancedWebSecurity = true
TlsVersion          = "tlsv12"

# ─── Web Interface ─────────────────────────────────────
NoWebInterface      = false
DownloadDomain      = "https://share.domain.com"
DownloadDomainAlias = ["https://share.domain.com"]
WebappDirectory     = "../webapp/dist"
AbuseContact        = "abuse@domain.com"
SessionTimeout      = "365d"

# ─── Upload Einschränkungen ───────────────────────────
UploadWhitelist     = []
MaxFileSizeStr      = "10GB"
MaxUserSizeStr      = "unlimited"
MaxFilePerUpload    = 100
DefaultTTLStr       = "30d"
MaxTTLStr           = "90d"

# ─── Feature Flags ─────────────────────────────────────
FeatureAuthentication = "disabled"
FeatureOneShot        = "enabled"
FeatureRemovable      = "enabled"
FeatureStream         = "enabled"
FeaturePassword       = "enabled"
FeatureComments       = "enabled"
FeatureSetTTL         = "enabled"
FeatureExtendTTL      = "disabled"
FeatureClients        = "enabled"
FeatureGithub         = "enabled"
FeatureText           = "enabled"

# ─── Daten-Backend ─────────────────────────────────────
DataBackend = "file"
[DataBackendConfig]
    Directory = "files"

# ─── Metadaten-Backend (lokal, ohne Server-DB) ────────
[MetadataBackendConfig]
    Driver = "sqlite3"
    ConnectionString = "plik.db"
    Debug = false

Die Datei landet im Container unter /home/plik/server/plikd.cfg.
Du kannst sie einfach im Volume mounten.

🌐 Schritt 3: Reverse Proxy mit NGINX – auch für Streaming

Damit alles sauber über https://share.domain.com läuft, brauchst du einen NGINX als Reverse Proxy.
Wichtig ist hier: Der Streaming-Endpunkt muss eigene Parameter bekommen!

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
location / {
proxy_pass http://plik-app:3000;
proxy_http_version 1.1;
proxy_request_buffering on;
client_max_body_size 10G;
proxy_read_timeout 300s;
send_timeout 300s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /stream/ {
proxy_pass http://plik-app:3000;
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off;
client_max_body_size 0;
proxy_read_timeout 600s;
send_timeout 600s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / { proxy_pass http://plik-app:3000; proxy_http_version 1.1; proxy_request_buffering on; client_max_body_size 10G; proxy_read_timeout 300s; send_timeout 300s; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /stream/ { proxy_pass http://plik-app:3000; proxy_http_version 1.1; proxy_request_buffering off; proxy_buffering off; client_max_body_size 0; proxy_read_timeout 600s; send_timeout 600s; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
location / {
    proxy_pass http://plik-app:3000;
    proxy_http_version 1.1;
    proxy_request_buffering on;
    client_max_body_size 10G;
    proxy_read_timeout 300s;
    send_timeout 300s;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /stream/ {
    proxy_pass http://plik-app:3000;
    proxy_http_version 1.1;
    proxy_request_buffering off;
    proxy_buffering off;
    client_max_body_size 0;
    proxy_read_timeout 600s;
    send_timeout 600s;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Mit dieser Konfiguration funktioniert das Webinterface perfekt, und Streaming-Downloads laufen reibungslos – selbst bei schwankender Verbindung.

🟢 Plik starten und loslegen

Wenn deine Konfiguration steht, startest du deinen Container ganz einfach mit:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
docker-compose up -d
docker-compose up -d
docker-compose up -d

Der Parameter -d sorgt dafür, dass der Container im Hintergrund läuft.

Falls du Änderungen an deiner docker-compose.yaml oder an plikd.cfg vorgenommen hast, kannst du den Container auch wie folgt neu starten:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
docker-compose down && docker-compose up -d
docker-compose down && docker-compose up -d
docker-compose down && docker-compose up -d

Nach dem Start erreichst du dein Webinterface unter der von dir konfigurierten Adresse – z. B.:

https://share.domain.com

💻 Das Webinterface im Überblick

Das Webinterface von Plik ist bewusst einfach und übersichtlich gehalten. Du kannst direkt loslegen, ohne dich anmelden zu müssen.

Das kannst du tun:

  • Dateien hochladen – per Drag & Drop oder Dateiauswahl
  • ⚙️ Optionen pro Upload setzen, z. B.:
    • Einmal-Download („Destruct after first download“)
    • Streaming-Modus
    • Passwortschutz
    • Löschrechte („Removable“)
    • Kommentar (Markdown-fähig)
    • Ablaufdatum ändern
  • 🔗 Freigabelinks generieren
  • 📱 QR-Code für schnellen Zugriff von mobilen Geräten
  • 📦 Nach dem Upload:
    • Direkt einzelne Dateien herunterladen
    • ZIP-Download für alles
    • Admin-Link für die nachträgliche Administration

Optional kannst du auch leere Uploads erstellen, um anderen Personen zu erlauben, selbst Dateien hochzuladen.

🚀 Bonus: Datei-Upload per Curl

Wer keine Lust aufs Webinterface hat, kann einfach curl nutzen:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
curl --form 'file=@/pfad/zur/deiner_datei.txt' https://share.domain.com
curl --form 'file=@/pfad/zur/deiner_datei.txt' https://share.domain.com
curl --form 'file=@/pfad/zur/deiner_datei.txt' https://share.domain.com

Plik gibt dir sofort den Download-Link zurück – ganz ohne Login oder Passwort.
Einfacher geht’s nicht!

📡 Streaming

Der Streaming-Modus ist ein echtes Highlight.
Du bereitest den Upload vor, bekommst deinen Freigabe-Link, und erst wenn der Empfänger ihn aufruft, startet der Upload automatisch.

Das heißt:

  • Der Sender hält die Datei bereit
  • Der Empfänger klickt → Upload und Download beginnen gleichzeitig
  • Kein Speicherplatzverbrauch

Ideal für einmalige Übertragungen – z. B. große ISO-Dateien oder sensible Inhalte.

✅ Fazit: Plik macht’s einfach

Plik ist schnell, elegant und verdammt effizient.
Mit ein paar Zeilen YAML und einer durchdachten Konfiguration hast du in kürzester Zeit einen eigenen File-Sharing-Dienst, der sich nicht hinter kommerziellen Plattformen verstecken muss.

Ob für dich selbst, dein Team oder dein gesamtes Netzwerk – Plik ist die unkomplizierte Lösung, wenn du die Kontrolle behalten möchtest.

Plik wird auf GitHub zu Verfügung gestellt – ein Open-Source-Projekt von root-gg, das mit durchdachten Features und klarer Ausrichtung auf Selbsthosting überzeugt. Ein echtes Tool von Admins – für Admins.

👥 Techniverse Community

Matrix, Selfhosting, smarte IT-Lösungen und jede Menge Nerd-Talk – das findest du in der Techniverse Community.
Komm vorbei, tausch dich aus und werde ein Teil von uns.
👉 Unsere Gruppe auf Matrix: #community:techniverse.net
Wir freuen uns auf dich!

Vielen Dank fürs Teilen!

3 gefällt das.