297 lines
8.5 KiB
Bash
297 lines
8.5 KiB
Bash
#!/bin/bash
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# GitHub repository information
|
|
REPO_URL="https://raw.githubusercontent.com/yourusername/jellyfin-docker/main"
|
|
|
|
echo -e "${GREEN}Jellyfin Docker Setup Script${NC}"
|
|
echo "--------------------------------"
|
|
|
|
# Function to detect GPU
|
|
detect_gpu() {
|
|
# Check for NVIDIA
|
|
if command -v nvidia-smi &> /dev/null; then
|
|
echo "nvidia"
|
|
return
|
|
fi
|
|
|
|
# Check for AMD GPU
|
|
if lspci | grep -i "vga.*amd" &> /dev/null; then
|
|
if lspci | grep -i "vga.*radeon" &> /dev/null; then
|
|
echo "amd-gpu"
|
|
else
|
|
echo "amd-apu"
|
|
fi
|
|
return
|
|
fi
|
|
|
|
# Check for Intel
|
|
if lspci | grep -i "vga.*intel" &> /dev/null; then
|
|
if [ -d "/sys/class/drm/card0/device/driver/module/drivers/pci:intel_arc" ]; then
|
|
echo "intel-arc"
|
|
else
|
|
echo "intel-igpu"
|
|
fi
|
|
return
|
|
fi
|
|
|
|
echo "none"
|
|
}
|
|
|
|
# Function to download file
|
|
download_file() {
|
|
local file=$1
|
|
echo -e "${YELLOW}Downloading ${file}...${NC}"
|
|
curl -sSL "${REPO_URL}/${file}" -o "${INSTALL_DIR}/${file}"
|
|
}
|
|
|
|
# Set installation directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
DEFAULT_INSTALL_DIR="$SCRIPT_DIR"
|
|
|
|
# Ask for installation directory with better validation
|
|
setup_install_directory() {
|
|
echo -e "${YELLOW}Where would you like to install Jellyfin?${NC}"
|
|
echo -e "Default: ${GREEN}${DEFAULT_INSTALL_DIR}${NC}"
|
|
read -p "Install directory [$DEFAULT_INSTALL_DIR]: " INSTALL_DIR
|
|
INSTALL_DIR=${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}
|
|
|
|
# Check if directory exists and has existing configuration
|
|
if [ -f "${INSTALL_DIR}/docker-compose.yml" ] || \
|
|
[ -f "${INSTALL_DIR}/docker-compose.override.yml" ] || \
|
|
[ -f "${INSTALL_DIR}/.env" ]; then
|
|
echo -e "${RED}Warning: Jellyfin files already exist in ${INSTALL_DIR}${NC}"
|
|
read -p "Do you want to proceed and potentially overwrite? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo "Aborting installation"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Create install directory if it doesn't exist
|
|
mkdir -p "$INSTALL_DIR"
|
|
|
|
# Check if directory is writable
|
|
if [ ! -w "$INSTALL_DIR" ]; then
|
|
echo -e "${RED}Error: Directory ${INSTALL_DIR} is not writable${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
setup_install_directory
|
|
|
|
# Check for existing docker-compose.yml
|
|
if [ -f "${INSTALL_DIR}/docker-compose.yml" ]; then
|
|
echo -e "${RED}Warning: docker-compose.yml already exists in ${INSTALL_DIR}${NC}"
|
|
read -p "Do you want to overwrite it? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo "Aborting installation"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Set up transcode cache
|
|
echo -e "${YELLOW}Where would you like to store the transcode cache?${NC}"
|
|
read -p "Transcode cache directory [/mnt/transcode]: " TRANSCODE_DIR
|
|
TRANSCODE_DIR=${TRANSCODE_DIR:-/mnt/transcode}
|
|
|
|
# Create transcode directory
|
|
sudo mkdir -p "$TRANSCODE_DIR"
|
|
sudo chown -R $USER:$USER "$TRANSCODE_DIR"
|
|
|
|
# Detect GPU
|
|
echo -e "${YELLOW}Detecting GPU...${NC}"
|
|
GPU_TYPE=$(detect_gpu)
|
|
|
|
case $GPU_TYPE in
|
|
"nvidia")
|
|
echo -e "${GREEN}NVIDIA GPU detected${NC}"
|
|
TRANSCODE_FILE="nvidia-transcoding.yml"
|
|
;;
|
|
"amd-gpu")
|
|
echo -e "${GREEN}AMD dedicated GPU detected${NC}"
|
|
TRANSCODE_FILE="amd-gpu.transcoding.yml"
|
|
;;
|
|
"amd-apu")
|
|
echo -e "${GREEN}AMD APU detected${NC}"
|
|
TRANSCODE_FILE="amd-apu.transcoding.yml"
|
|
;;
|
|
"intel-arc")
|
|
echo -e "${GREEN}Intel ARC detected${NC}"
|
|
TRANSCODE_FILE="intel-arc.transcoding.yml"
|
|
;;
|
|
"intel-igpu")
|
|
echo -e "${GREEN}Intel integrated GPU detected${NC}"
|
|
TRANSCODE_FILE="intel-igpu.transcoding.yml"
|
|
;;
|
|
*)
|
|
echo -e "${RED}No supported GPU detected${NC}"
|
|
echo "CPU transcoding will be used"
|
|
TRANSCODE_FILE="intel-igpu.transcoding.yml" # Default fallback
|
|
;;
|
|
esac
|
|
|
|
# Download required files
|
|
download_file "docker-compose.yml"
|
|
download_file "sample.env"
|
|
download_file "$TRANSCODE_FILE"
|
|
download_file "tonemapping.md"
|
|
|
|
# Create .env file from sample
|
|
cp "${INSTALL_DIR}/sample.env" "${INSTALL_DIR}/.env"
|
|
|
|
# Update .env file with transcode path
|
|
sed -i "s|TRANSCODE_CACHE=.*|TRANSCODE_CACHE=${TRANSCODE_DIR}|g" "${INSTALL_DIR}/.env"
|
|
|
|
# Get render group ID
|
|
RENDER_GID=$(getent group render | cut -d: -f3)
|
|
if [ ! -z "$RENDER_GID" ]; then
|
|
sed -i "s|RENDER_GID=.*|RENDER_GID=${RENDER_GID}|g" "${INSTALL_DIR}/.env"
|
|
fi
|
|
|
|
# Check for Docker and Docker Compose
|
|
check_prerequisites() {
|
|
echo -e "${YELLOW}Checking prerequisites...${NC}"
|
|
|
|
if ! command -v docker &> /dev/null; then
|
|
echo -e "${RED}Docker is not installed${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
if ! docker compose version &> /dev/null; then
|
|
echo -e "${RED}Docker Compose is not installed${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Run prerequisite checks
|
|
check_prerequisites
|
|
|
|
# Network configuration function
|
|
configure_network() {
|
|
echo -e "${YELLOW}Configuring network...${NC}"
|
|
|
|
# Ask about host network mode
|
|
read -p "Use host network mode? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
USE_HOST_NETWORK=true
|
|
else
|
|
# Check for port conflicts
|
|
check_port_conflict 8096
|
|
check_port_conflict 8920
|
|
check_port_conflict 1900 "DLNA"
|
|
fi
|
|
|
|
# List available networks
|
|
echo -e "${YELLOW}Available Docker networks:${NC}"
|
|
docker network ls
|
|
|
|
read -p "Use specific Docker network? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
select_docker_network
|
|
fi
|
|
}
|
|
|
|
# Function to list available volumes
|
|
list_volumes() {
|
|
echo "Available volumes:"
|
|
docker volume ls | grep -v "^local.*[0-9a-f]\{64\}$"
|
|
}
|
|
|
|
# Function to select media volume
|
|
select_media_volume() {
|
|
local volumes=$(docker volume ls --format "{{.Name}}" | grep -v "^[0-9a-f]\{64\}$")
|
|
if [ -z "$volumes" ]; then
|
|
echo -e "${RED}No named volumes found${NC}"
|
|
return 1
|
|
fi
|
|
|
|
echo "Available volumes:"
|
|
select volume in $volumes "Create new" "Skip"; do
|
|
case $volume in
|
|
"Create new")
|
|
configure_new_volume
|
|
break
|
|
;;
|
|
"Skip")
|
|
break
|
|
;;
|
|
*)
|
|
if [ -n "$volume" ]; then
|
|
echo "Selected volume: $volume"
|
|
add_volume_to_override "$volume"
|
|
break
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Function to add volume to override file
|
|
add_volume_to_override() {
|
|
local volume=$1
|
|
if [ ! -f "${INSTALL_DIR}/docker-compose.override.yml" ]; then
|
|
cp "${INSTALL_DIR}/docker-compose.override.yml.sample" "${INSTALL_DIR}/docker-compose.override.yml"
|
|
fi
|
|
|
|
# Add volume if not already present
|
|
if ! grep -q " $volume:" "${INSTALL_DIR}/docker-compose.override.yml"; then
|
|
sed -i "/volumes:/a\ $volume:\n external: true" "${INSTALL_DIR}/docker-compose.override.yml"
|
|
fi
|
|
}
|
|
|
|
# Configure volumes
|
|
configure_volumes() {
|
|
echo -e "${YELLOW}Checking available volumes...${NC}"
|
|
list_volumes
|
|
|
|
read -p "Would you like to use existing volumes? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
select_media_volume
|
|
fi
|
|
}
|
|
|
|
# Run volume configuration
|
|
configure_volumes
|
|
|
|
# Collect required environment variables
|
|
collect_env_variables() {
|
|
echo -e "${YELLOW}Configuring environment variables...${NC}"
|
|
|
|
# Only ask if not already set in .env
|
|
if [ ! -f "${INSTALL_DIR}/.env" ] || ! grep -q "DOMAIN=" "${INSTALL_DIR}/.env"; then
|
|
read -p "Domain name for Jellyfin: " DOMAIN
|
|
fi
|
|
|
|
if [ ! -f "${INSTALL_DIR}/.env" ] || ! grep -q "JELLYFIN_ADMIN_USER=" "${INSTALL_DIR}/.env"; then
|
|
read -p "Jellyfin admin username: " ADMIN_USER
|
|
fi
|
|
|
|
# Add password collection with masking
|
|
if [ ! -f "${INSTALL_DIR}/.env" ] || ! grep -q "JELLYFIN_ADMIN_PASSWORD=" "${INSTALL_DIR}/.env"; then
|
|
read -s -p "Jellyfin admin password: " ADMIN_PASSWORD
|
|
echo
|
|
fi
|
|
}
|
|
|
|
echo -e "${GREEN}Installation complete!${NC}"
|
|
echo "--------------------------------"
|
|
echo -e "Files installed in: ${YELLOW}${INSTALL_DIR}${NC}"
|
|
echo -e "Transcode cache: ${YELLOW}${TRANSCODE_DIR}${NC}"
|
|
echo -e "GPU detected: ${YELLOW}${GPU_TYPE}${NC}"
|
|
echo
|
|
echo "Next steps:"
|
|
echo "1. Edit ${INSTALL_DIR}/.env to configure your settings"
|
|
echo "2. Start Jellyfin with:"
|
|
echo -e "${YELLOW} cd ${INSTALL_DIR}${NC}"
|
|
echo -e "${YELLOW} docker compose -f docker-compose.yml -f ${TRANSCODE_FILE} up -d${NC}"
|