#!/bin/bash # Setup Hetzner Storage Box via SSHFS on Netcup RS 8000 # Storage Box: u521871 (BX21 - 5-10TB) set -e # Configuration HETZNER_USER="u521871" HETZNER_HOST="${HETZNER_USER}.your-storagebox.de" HETZNER_PORT="23" SSH_KEY="/root/.ssh/hetzner_storagebox" MOUNT_POINT="/mnt/hetzner-media" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' echo -e "${GREEN}Hetzner Storage Box SSHFS Setup${NC}" echo "==================================" echo "User: $HETZNER_USER" echo "Host: $HETZNER_HOST" echo "Mount: $MOUNT_POINT" echo "" # Check if running as root if [ "$EUID" -ne 0 ]; then echo -e "${RED}Please run as root (sudo)${NC}" exit 1 fi # Check SSH key exists if [ ! -f "$SSH_KEY" ]; then echo -e "${RED}SSH key not found at $SSH_KEY${NC}" echo "Generate one with: ssh-keygen -t ed25519 -f $SSH_KEY -C 'storagebox@netcup'" echo "Then upload with: cat ${SSH_KEY}.pub | ssh -p23 ${HETZNER_USER}@${HETZNER_HOST} install-ssh-key" exit 1 fi # Install sshfs echo -e "${GREEN}Installing SSHFS...${NC}" apt-get update -qq apt-get install -y sshfs # Create mount point echo -e "${GREEN}Creating mount point...${NC}" mkdir -p "$MOUNT_POINT" # Test SSH connection (use 'ls' as Hetzner has restricted shell) echo -e "${GREEN}Testing SSH connection...${NC}" if ! ssh -p "$HETZNER_PORT" -i "$SSH_KEY" -o BatchMode=yes -o ConnectTimeout=10 \ "${HETZNER_USER}@${HETZNER_HOST}" "ls" &>/dev/null; then echo -e "${RED}SSH connection failed!${NC}" echo "Make sure:" echo " 1. SSH is enabled in Hetzner Console" echo " 2. Your key is uploaded: cat ${SSH_KEY}.pub | ssh -p23 ${HETZNER_USER}@${HETZNER_HOST} install-ssh-key" exit 1 fi echo -e "${GREEN}SSH connection successful${NC}" # Create directory structure on Hetzner echo -e "${GREEN}Creating directory structure on Hetzner...${NC}" ssh -p "$HETZNER_PORT" -i "$SSH_KEY" "${HETZNER_USER}@${HETZNER_HOST}" "mkdir -p media/movies" 2>/dev/null || true ssh -p "$HETZNER_PORT" -i "$SSH_KEY" "${HETZNER_USER}@${HETZNER_HOST}" "mkdir -p media/shows" 2>/dev/null || true ssh -p "$HETZNER_PORT" -i "$SSH_KEY" "${HETZNER_USER}@${HETZNER_HOST}" "mkdir -p media/music" 2>/dev/null || true ssh -p "$HETZNER_PORT" -i "$SSH_KEY" "${HETZNER_USER}@${HETZNER_HOST}" "mkdir -p downloads/complete/movies" 2>/dev/null || true ssh -p "$HETZNER_PORT" -i "$SSH_KEY" "${HETZNER_USER}@${HETZNER_HOST}" "mkdir -p downloads/complete/tv" 2>/dev/null || true ssh -p "$HETZNER_PORT" -i "$SSH_KEY" "${HETZNER_USER}@${HETZNER_HOST}" "mkdir -p downloads/complete/music" 2>/dev/null || true ssh -p "$HETZNER_PORT" -i "$SSH_KEY" "${HETZNER_USER}@${HETZNER_HOST}" "mkdir -p downloads/incomplete" 2>/dev/null || true echo -e "${GREEN}Directories created${NC}" # Create systemd mount unit echo -e "${GREEN}Creating systemd mount unit...${NC}" cat > /etc/systemd/system/mnt-hetzner\\x2dmedia.mount << EOF [Unit] Description=Hetzner Storage Box (u521871 - SSHFS) After=network-online.target Wants=network-online.target [Mount] What=${HETZNER_USER}@${HETZNER_HOST}:/ Where=${MOUNT_POINT} Type=fuse.sshfs Options=port=${HETZNER_PORT},IdentityFile=${SSH_KEY},allow_other,default_permissions,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,_netdev,uid=1000,gid=1000 [Install] WantedBy=multi-user.target EOF # Create automount unit for on-demand mounting cat > /etc/systemd/system/mnt-hetzner\\x2dmedia.automount << EOF [Unit] Description=Automount Hetzner Storage Box After=network-online.target Wants=network-online.target [Automount] Where=${MOUNT_POINT} TimeoutIdleSec=0 [Install] WantedBy=multi-user.target EOF # Enable user_allow_other in fuse.conf if ! grep -q "^user_allow_other" /etc/fuse.conf 2>/dev/null; then echo "user_allow_other" >> /etc/fuse.conf fi # Reload systemd and start mount echo -e "${GREEN}Enabling and starting mount...${NC}" systemctl daemon-reload systemctl enable mnt-hetzner\\x2dmedia.mount systemctl start mnt-hetzner\\x2dmedia.mount # Verify mount sleep 2 if mountpoint -q "$MOUNT_POINT"; then echo -e "${GREEN}Mount successful!${NC}" echo "" df -h "$MOUNT_POINT" echo "" echo "Directory structure:" ls -la "$MOUNT_POINT" else echo -e "${RED}Mount may have failed. Checking status...${NC}" systemctl status mnt-hetzner\\x2dmedia.mount exit 1 fi # Save config reference cat > /opt/media-server/.hetzner-config << EOF HETZNER_USER=$HETZNER_USER HETZNER_HOST=$HETZNER_HOST MOUNT_POINT=$MOUNT_POINT SSH_KEY=$SSH_KEY MOUNT_TYPE=sshfs SETUP_DATE=$(date -Iseconds) EOF chmod 600 /opt/media-server/.hetzner-config echo "" echo -e "${GREEN}Setup complete!${NC}" echo "" echo "Storage mounted at: $MOUNT_POINT" echo "" echo "Directory structure:" echo " $MOUNT_POINT/media/movies - Movie library" echo " $MOUNT_POINT/media/shows - TV show library" echo " $MOUNT_POINT/media/music - Music library" echo " $MOUNT_POINT/downloads/ - qBittorrent downloads" echo "" echo "Next steps:" echo " 1. Deploy updated docker-compose: docker compose up -d" echo " 2. Configure Jellyfin library paths" echo " 3. Verify qBittorrent download path" echo ""