Skip to content

Οδηγός Εγκατάστασης Jellyfin & Tailscale σε Contabo VPS (Secure Setup)

Αυτός ο οδηγός περιγράφει την εγκατάσταση ενός απόλυτα ασφαλούς Media Server. Ο Jellyfin είναι προσβάσιμος μόνο μέσω του ιδιωτικού δικτύου Tailscale (VPN), καθιστώντας τον αόρατο σε scanners και hackers στο δημόσιο ίντερνετ.

1. Ασφάλιση του VPS (SSH)

Πριν ξεκινήσετε με το Docker, θωρακίστε την πρόσβαση στον ίδιο τον server.

  • Χρήση SSH Keys: Βεβαιωθείτε ότι συνδέεστε με κλειδιά.
  • Απενεργοποίηση Password Login:
    • Εκτελέστε: sudo nano /etc/ssh/sshd_config
    • Αλλάξτε τη γραμμή PasswordAuthentication σε no.
  • Επανεκκίνηση SSH:
    • Εκτελέστε: sudo systemctl restart ssh

2. Εγκατάσταση Docker & Compose

Εκτελέστε τις παρακάτω εντολές:

sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

Σημείωση: Κάντε logout και login για να ενεργοποιηθεί η συμμετοχή σας στο group docker.

sudo apt install docker-compose-plugin

3. Προετοιμασία Φακέλων

Εκτελέστε:

mkdir -p ~/docker/jellyfin/config ~/docker/jellyfin/cache ~/docker/jellyfin/tailscale_state
sudo chown -R $USER:$USER ~/docker/jellyfin


4. Ρύθμιση Docker Compose (Secure Sidecar Pattern)

Δημιουργήστε το αρχείο ~/docker/jellyfin/docker-compose.yml με το εξής περιεχόμενο. Η συγκεκριμένη διάταξη αναγκάζει το Jellyfin να χρησιμοποιεί αποκλειστικά το δίκτυο του Tailscale container (Sidecar pattern), κλείνοντας την "τρύπα" της δημόσιας IP.

services:
  tailscale:
    image: tailscale/tailscale:latest
    container_name: tailscale
    hostname: contabo-jellyfin
    network_mode: bridge
    privileged: true
    environment:
      - TS_AUTHKEY=tskey-auth-xxxx # Αντικαταστήστε με το δικό σας Auth Key από το Tailscale Admin Console
      - TS_STATE_DIR=/var/lib/tailscale
    volumes:
      - ./tailscale_state:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - NET_ADMIN
      - NET_RAW
    restart: unless-stopped

  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    network_mode: "service:tailscale" # Σημαντικό: Το Jellyfin χρησιμοποιεί το δίκτυο του Tailscale
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /home/media/movies:/data/movies:rw
      - /home/media/tvshows:/data/tvshows:rw
    restart: unless-stopped

5. Ρύθμιση Firewall (UFW)

Επιτρέπουμε μόνο το SSH και την απαραίτητη κίνηση για το Tailscale. Η θύρα 8096 δεν εκτίθεται στο δημόσιο ίντερνετ.

Βήμα 1: Έλεγχος Κατάστασης Πριν εφαρμόσετε κανόνες, ελέγξτε αν το firewall είναι ήδη ενεργό για να αποφύγετε το κλείδωμα:

sudo ufw status
Αν είναι inactive, προχωρήστε άφοβα. Αν είναι active, βεβαιωθείτε ότι έχετε ήδη ανοιχτή την πόρτα SSH.

Βήμα 2: Εφαρμογή Κανόνων Εκτελέστε τις εντολές με την εξής σειρά (η εντολή limit ssh εξασφαλίζει ότι δεν θα κλειδωθείτε έξω):

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit ssh
sudo ufw allow 41641/udp
sudo ufw enable

6. Εκκίνηση και Αρχική Ρύθμιση

  • Εκκίνηση:
    cd ~/docker/jellyfin
    docker compose up -d
    
  • Σύνδεση για πρώτη φορά: Επειδή ο server δεν είναι ακόμα προσβάσιμος εξ αποστάσεως, χρησιμοποιήστε SSH Tunnel από το PC σας: ssh -L 8096:127.0.0.1:8096 root@IP-of-Contabo Ανοίξτε το http://127.0.0.1:8096 στον browser σας.
  • Στον Wizard επιλέξτε "Allow remote connections".

7. Σύνδεση Συσκευών (Mint / Chromecast / Mobile)

  • Tailscale IP: Βρείτε την IP της μορφής 100.x.y.z από το Tailscale Admin Panel.
  • Σύνδεση: Χρησιμοποιήστε τη διεύθυνση http://100.x.y.z:8096 στις εφαρμογές Jellyfin.
  • Επαλήθευση Ασφαλείας: Με το Tailscale κλειστό στη συσκευή σας, η διεύθυνση http://IP-of-Contabo:8096 δεν πρέπει να φορτώνει.

8. Πρόσθετες Ρυθμίσεις

  • Transcoding: Dashboard > Users > Media Playback > Απενεργοποίηση (για μείωση φόρτου CPU στο VPS).
  • Plugins: Dashboard > Plugins > OpenSubtitles, Trakt, Playback Reporting.
  • Library: Dashboard > Libraries > Manage Library > Subtitles > Download languages: Greek.

Σημείωση: Με αυτό το setup, η κίνηση των δεδομένων σας είναι πλήρως κρυπτογραφημένη και ο server παραμένει αόρατος σε οποιονδήποτε τρίτο στο διαδίκτυο.


9. Λίστα Ελέγχου Μετά την Εγκατάσταση (Post-Installation Checklist)

Αφού επιβεβαιώσατε ότι η θύρα 8096 είναι κλειστή, ακολουθήστε τα παρακάτω βήματα για τη μέγιστη θωράκιση του VPS σας.

a. Διαχείριση Κλειδιών Tailscale (Key Expiry)

Από προεπιλογή, το Tailscale λήγει τα κλειδιά των συσκευών κάθε 6 μήνες. Αν λήξει το κλειδί του VPS, ο server θα αποσυνδεθεί από το VPN και το Jellyfin θα σταματήσει να παίζει στις συσκευές σας μέχρι να ξανακάνετε login χειροκίνητα.

Βήματα για απενεργοποίηση:

  • Συνδεθείτε στο Tailscale Admin Console.
  • Μεταβείτε στην καρτέλα Machines.
  • Βρείτε στη λίστα το μηχάνημα με το όνομα contabo-jellyfin.
  • Στη δεξιά πλευρά της γραμμής, κάντε κλικ στις τρεις τελείες (...).
  • Επιλέξτε το Disable key expiry.
  • Θα εμφανιστεί μια μικρή ένδειξη "Expiry disabled" δίπλα ή κάτω από το όνομα του server, επιβεβαιώνοντας ότι η σύνδεση είναι πλέον μόνιμη.

10. Cloud Media Server

Σύνδεση του VPS με το Google Drive.

Εγκατάσταση του rclone στον VPS

Στον VPS εκτελείτε τον σύνδεσμο sudo apt-get install rclone. Αποσυνδέεστε και στην συνέχεια δημιουργείτε ένα SSH Tunnel ανάμεσα στον υπολογιστή μου και στον VPS:

ssh -L 53682:localhost:53682 root@your_vps_ip
για να μπορέσετε να κάνετε αυθεντικοποίηση στον λογαριασμό Google Drive. Στο ίδιο τερματικό και ενόσω είστε συνδεδεμένος στον VPS, εκτελέστε rclone config και επιλέξτε n για να δημιουργήσετε έναν νέο λογαριασμό. Αποθηκεύστε τον λογαριασμό με το όνομα gdrive και επιλέξτε τον τύπο Google Drive.

Όταν φτάσετε στο σημείο της αυθεντικοποίησης, αντιγράψτε τον σύνδεσμο και ανοίξτε τον στον browser σας ο οποίος είναι συνδεδεμένος στον επιλεγμένο λογαριασμό Google.

Mounting

Δημιουργία script για τον mount των φακέλων:

sudo nano /usr/bin/mount-media.sh

Μέσα στο αρχείο προσθέτουμε το εξής περιεχόμενο:

#!/bin/bash

# Καθαρισμός τυχόν κολλημένων mounts
/usr/bin/fusermount -uz /home/media/movies
/usr/bin/fusermount -uz /home/media/tvshows

# Mount Movies (Με βελτιωμένο cache για streaming)
/usr/bin/rclone mount gdrive:movies /home/media/movies \
--allow-other \
--vfs-cache-mode full \
--vfs-cache-max-size 20G \
--vfs-read-chunk-size 32M \
--vfs-read-chunk-size-limit off \
--buffer-size 32M \
--dir-cache-time 1000h \
--log-level INFO &

# Mount TVShows
/usr/bin/rclone mount gdrive:tvshows /home/media/tvshows \
--allow-other \
--vfs-cache-mode full \
--vfs-cache-max-size 20G \
--vfs-read-chunk-size 32M \
--vfs-read-chunk-size-limit off \
--buffer-size 32M \
--dir-cache-time 1000h \
--log-level INFO &

wait

Το & στο τέλος δηλώνει ότι η κάθε εντολή θα εκτελεί ανεξάρτητα από την άλλη στο παρασκήνιο. Το wait σημαίνει ότι η εκτέλεση του script θα σταματήσει όταν οι δύο εντολές θα έχουν τελειώσει.

Στην συνέχεια κάνουμε το αρχείο εκτελέσιμο με τον σύνδεσμο sudo chmod +x /usr/bin/mount-media.sh.

Για να τρέχει απρόσκοπτα, θα δημιουργήσουμε έναν systemd service.

sudo nano /etc/systemd/system/rclone-media.service

Μέσα στο αρχείο προσθέτουμε το εξής περιεχόμενο:

[Unit]
Description=Rclone Mount Media (Movies and TV)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/mount-media.sh
Restart=on-failure
RestartSec=10
User=root
# Σημαντικό: KillMode=mixed για να μην "σκοτώνει" βίαια το rclone
KillMode=mixed

[Install]
WantedBy=multi-user.target

Στην συνέχεια τρέχουμε:

# Ενημέρωση του systemd για το νέο αρχείο
sudo systemctl daemon-reload

# Ενεργοποίηση ώστε να ξεκινάει μόνο του στο reboot
sudo systemctl enable rclone-media

# Άμεση εκκίνηση
sudo systemctl start rclone-media

Τέλος, κάνουμε επανεκκίνηση του Jellyfin server:

docker restart jellyfin
και έπειτα "Scan Media Library".