pyrodactyl-installer.muspelheim.host

Source
https://raw.githubusercontent.com/Muspelheim-Hosting/pyrodactyl-installer/main/install.sh

All this url does is fetch the script directly from the URL above. What you see below is the live version of the install script hosted on GitHub.

Install Command
bash <(curl -sSL "https://pyrodactyl-installer.muspelheim.host")

View source: github.com/Muspelheim-Hosting/pyrodactyl-installer

install.sh

#!/bin/bash

# Clean up any cached files from previous runs
rm -f /tmp/pyrodactyl-lib.sh /tmp/pyrodactyl-*.sh 2>/dev/null || true

set -e

# ------------------ Command Line Arguments ----------------- #

# Parse command line arguments
while [[ $# -gt 0 ]]; do
  case $1 in
    --help|-h)
      echo "Pyrodactyl Installer"
      echo ""
      echo "Usage: install.sh [OPTIONS]"
      echo ""
      echo "Options:"
      echo "  --help, -h    Show this help message"
      echo ""
      echo "Examples:"
      echo "  # Standard install (downloads from GitHub)"
      echo "  bash <(curl -sSL https://pyrodactyl-installer.muspelheim.host)"
      echo ""
      exit 0
      ;;
    *)
      echo "Unknown option: $1"
      echo "Use --help for usage information"
      exit 1
      ;;
  esac
done

######################################################################################
#                                                                                    #
# Pyrodactyl Installer                                                               #
#                                                                                    #
# One-command installer for Pyrodactyl Panel and Elytra Daemon                       #
#                                                                                    #
# Copyright (C) 2025, Muspelheim Hosting                                             #
#                                                                                    #
# https://github.com/Muspelheim-Hosting/pyrodactyl-installer                         #
#                                                                                    #
######################################################################################

export GITHUB_SOURCE="${GITHUB_SOURCE:-main}"
export SCRIPT_RELEASE="${SCRIPT_RELEASE:-v1.2.0}"
export GITHUB_BASE_URL="${GITHUB_BASE_URL:-https://raw.githubusercontent.com/Muspelheim-Hosting/pyrodactyl-installer}"

LOG_PATH="/var/log/pyrodactyl-installer.log"

# ------------------ Utility Functions ----------------- #

# Color definitions - Orange gradient for flame effect
export COLOR_DARK_ORANGE='\033[38;5;208m'
export COLOR_ORANGE='\033[38;5;214m'
export COLOR_LIGHT_ORANGE='\033[38;5;220m'
export COLOR_YELLOW='\033[1;33m'
export COLOR_GREEN='\033[0;32m'
export COLOR_RED='\033[0;31m'
export COLOR_BLUE='\033[0;34m'
export COLOR_CYAN='\033[0;36m'
export COLOR_NC='\033[0m'

# Smooth flame gradient colors (top to bottom) - red to gold
export GRADIENT_1='\033[38;5;196m'   # Deep red
export GRADIENT_2='\033[38;5;202m'   # Red-orange
export GRADIENT_3='\033[38;5;208m'   # Dark orange
export GRADIENT_4='\033[38;5;214m'   # Orange
export GRADIENT_5='\033[38;5;220m'   # Light orange
export GRADIENT_6='\033[38;5;221m'   # Gold-orange
export GRADIENT_7='\033[38;5;222m'   # Gold
export GRADIENT_8='\033[38;5;226m'   # Yellow-gold
export GRADIENT_9='\033[38;5;227m'   # Bright gold
export GRADIENT_10='\033[38;5;228m'  # Light gold
export GRADIENT_11='\033[38;5;229m'  # Pale gold

output() {
  echo -e "* $1"
}

success() {
  echo ""
  echo -e "* ${COLOR_GREEN}SUCCESS${COLOR_NC}: $1"
  echo ""
}

error() {
  echo ""
  echo -e "* ${COLOR_RED}ERROR${COLOR_NC}: $1" 1>&2
  echo ""
}

warning() {
  echo ""
  echo -e "* ${COLOR_YELLOW}WARNING${COLOR_NC}: $1"
  echo ""
}

# Error handler - called when script exits with error
error_handler() {
  local exit_code=$?
  local line_no=$1

  if [ $exit_code -ne 0 ]; then
    echo ""
    echo -e "* ${COLOR_RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${COLOR_NC}"
    echo -e "* ${COLOR_RED}INSTALLATION FAILED${COLOR_NC}"
    echo -e "* ${COLOR_RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${COLOR_NC}"
    echo ""
    echo -e "* ${COLOR_YELLOW}Exit code:${COLOR_NC} $exit_code"
    [ -n "$line_no" ] && echo -e "* ${COLOR_YELLOW}Failed at line:${COLOR_NC} $line_no"
    echo ""
    echo -e "* ${COLOR_CYAN}Troubleshooting tips:${COLOR_NC}"
    echo -e "  1. Check the log file: ${COLOR_ORANGE}$LOG_PATH${COLOR_NC}"
    echo -e "  2. Ensure you have a stable internet connection"
    echo -e "  3. Verify your GitHub token has 'repo' scope"
    echo -e "  4. Check that your OS is supported"
    echo ""
    echo -e "* ${COLOR_CYAN}For help, visit:${COLOR_NC} https://github.com/Muspelheim-Hosting/pyrodactyl-installer/issues"
    echo ""
    echo -e "* ${COLOR_RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${COLOR_NC}"
    echo ""
  fi
}

# Set up error trap
trap 'error_handler $LINENO' ERR

# Cleanup function for temporary files
print_brake() {
  local char="${2:-─}"
  for ((n = 0; n < $1; n++)); do
    echo -n "$char"
  done
  echo ""
}

print_header() {
  clear 2>/dev/null || true
  echo ""

  # Flame gradient header - smooth color transition from top to bottom
  echo -e "${GRADIENT_1}    ╔══════════════════════════════════════════════════════════════════════════════════════╗"
  echo -e "${GRADIENT_2}    ║                                                                                      ║"
  echo -e "${GRADIENT_3}    ║  ███╗   ███╗██╗   ██╗███████╗██████╗ ███████╗██╗     ██╗  ██╗███████╗██╗███╗   ███╗  ║"
  echo -e "${GRADIENT_4}    ║  ████╗ ████║██║   ██║██╔════╝██╔══██╗██╔════╝██║     ██║  ██║██╔════╝██║████╗ ████║  ║"
  echo -e "${GRADIENT_5}    ║  ██╔████╔██║██║   ██║███████╗██████╔╝█████╗  ██║     ███████║█████╗  ██║██╔████╔██║  ║"
  echo -e "${GRADIENT_6}    ║  ██║╚██╔╝██║██║   ██║╚════██║██╔═══╝ ██╔══╝  ██║     ██╔══██║██╔══╝  ██║██║╚██╔╝██║  ║"
  echo -e "${GRADIENT_7}    ║  ██║ ╚═╝ ██║╚██████╔╝███████║██║     ███████╗███████╗██║  ██║███████╗██║██║ ╚═╝ ██║  ║"
  echo -e "${GRADIENT_8}    ║  ╚═╝     ╚═╝ ╚═════╝ ╚══════╝╚═╝     ╚══════╝╚══════╝╚═╝  ╚═╝╚══════╝╚═╝╚═╝     ╚═╝  ║"
  echo -e "${GRADIENT_9}    ║                                                                                      ║"
  echo -e "${GRADIENT_10}    ║                            Pyrodactyl Installation Manager                           ║"
  echo -e "${GRADIENT_11}    ╚══════════════════════════════════════════════════════════════════════════════════════╝"
  echo -e "${COLOR_NC}"
  echo -e "    ${COLOR_ORANGE}Version:${COLOR_NC} ${SCRIPT_RELEASE}  ${COLOR_ORANGE}|${COLOR_NC}  ${COLOR_ORANGE}By:${COLOR_NC} Muspelheim Hosting"
  echo ""
}

print_flame() {
  local message="$1"

  echo ""
  echo -e "${COLOR_ORANGE}  $message${COLOR_NC}"
  echo ""
}

# Cleanup function for temporary files
cleanup() {
  rm -f /tmp/pyrodactyl-lib.sh 2>/dev/null || true
  rm -f /tmp/lib.sh 2>/dev/null || true
}

# Set trap to cleanup on exit
trap cleanup EXIT INT TERM

# Check for root
check_root() {
  if [[ $EUID -ne 0 ]]; then
    error "This script must be executed with root privileges."
    exit 1
  fi
}

# Check for curl
check_curl() {
  if ! [ -x "$(command -v curl)" ]; then
    error "curl is required in order for this script to work."
    error "Install using: apt install curl (Debian/Ubuntu) or dnf install curl (RHEL)"
    exit 1
  fi
}

# Download and source library
load_library() {
  # Download lib.sh from GitHub
  [ -f /tmp/pyrodactyl-lib.sh ] && rm -rf /tmp/pyrodactyl-lib.sh

  output "Loading installer library..."

  if ! curl -sSL -o /tmp/pyrodactyl-lib.sh "$GITHUB_BASE_URL/$GITHUB_SOURCE/lib/lib.sh"; then
    error "Failed to download installer library."
    error "Please check your internet connection and try again."
    exit 1
  fi

  # shellcheck source=/dev/null
  if ! source /tmp/pyrodactyl-lib.sh; then
    error "Failed to load installer library."
    exit 1
  fi
}

# Log execution
log_execution() {
  echo -e "\n\n* pyrodactyl-installer $(date) \n\n" >> "$LOG_PATH" 2>/dev/null || true
}

# Execute UI script
execute_ui() {
  local script_name="$1"
  local next_script="${2:-}"

  # Download and run from GitHub
  run_ui "$script_name" 2>&1 | tee -a "$LOG_PATH"
  local exit_code=${PIPESTATUS[0]}

  # Exit if the installation failed
  if [ $exit_code -ne 0 ]; then
    exit $exit_code
  fi

  # Wait for user to acknowledge before returning to menu
  # (unless there's a next script to run)
  if [[ -z "$next_script" ]]; then
    echo ""
    output "Press Enter to return to the menu..."
    read -r
  fi

  if [[ -n "$next_script" ]]; then
    echo ""
    local CONFIRM=""
    while [[ "$CONFIRM" != "y" && "$CONFIRM" != "n" ]]; do
      echo -n "* Installation of $script_name completed. Do you want to proceed to $next_script installation? [y/N]: "
      read -r CONFIRM
      CONFIRM=$(echo "$CONFIRM" | tr '[:upper:]' '[:lower:]')
      [ -z "$CONFIRM" ] && CONFIRM="n"
      if [[ "$CONFIRM" != "y" && "$CONFIRM" != "n" ]]; then
        error "Invalid input. Please enter 'y' or 'n'."
      fi
    done
    if [[ "$CONFIRM" == "y" ]]; then
      execute_ui "$next_script"
    else
      warning "Installation of $next_script aborted."
      exit 1
    fi
  fi
}

# Show welcome screen
# Check installations and set state variables
check_installations() {
  PANEL_INSTALLED=false
  ELYTRA_INSTALLED=false
  PANEL_VERSION=""
  ELYTRA_VERSION=""
  PANEL_UPDATER_INSTALLED=false
  ELYTRA_UPDATER_INSTALLED=false

  # Check for Pyrodactyl
  if [ -d "/var/www/pyrodactyl" ]; then
    PANEL_INSTALLED=true
    if [ -f "/var/www/pyrodactyl/config/app.php" ]; then
      PANEL_VERSION=$(grep "'version'" "/var/www/pyrodactyl/config/app.php" 2>/dev/null | head -1 | cut -d"'" -f4 || echo "")
    fi
  fi

  # Check for Elytra
  if [ -f "/usr/local/bin/elytra" ]; then
    ELYTRA_INSTALLED=true
    if [ -f "/etc/pyrodactyl/elytra-version" ]; then
      ELYTRA_VERSION=$(cat "/etc/pyrodactyl/elytra-version" 2>/dev/null || echo "")
    fi
  fi

  if systemctl is-enabled --quiet pyrodactyl-panel-auto-update.timer 2>/dev/null; then
    PANEL_UPDATER_INSTALLED=true
  fi

  if systemctl is-enabled --quiet pyrodactyl-elytra-auto-update.timer 2>/dev/null; then
    ELYTRA_UPDATER_INSTALLED=true
  fi
}

show_welcome() {
  print_header

  # Detect OS if possible
  local os_info="Unknown"
  if [ -f /etc/os-release ]; then
    # shellcheck source=/dev/null
    source /etc/os-release
    os_info="$NAME $VERSION_ID"
  fi

  echo -e "  ${COLOR_ORANGE}Operating System:${COLOR_NC} $os_info"
  echo ""

  # Check and display installed components
  check_installations

  if [ "$PANEL_INSTALLED" == true ]; then
    echo -e "  ${COLOR_GREEN}✓${COLOR_NC} Panel installed${PANEL_VERSION:+ ($PANEL_VERSION)}"
  else
    echo -e "  ${COLOR_RED}✗${COLOR_NC} Panel not installed"
  fi

  if [ "$ELYTRA_INSTALLED" == true ]; then
    echo -e "  ${COLOR_GREEN}✓${COLOR_NC} Elytra installed${ELYTRA_VERSION:+ ($ELYTRA_VERSION)}"
  else
    echo -e "  ${COLOR_RED}✗${COLOR_NC} Elytra not installed"
  fi

  if [ "$PANEL_UPDATER_INSTALLED" == true ]; then
    echo -e "  ${COLOR_GREEN}✓${COLOR_NC} Panel auto-updater enabled"
  else
    echo -e "  ${COLOR_RED}✗${COLOR_NC} Panel auto-updater not installed"
  fi

  if [ "$ELYTRA_UPDATER_INSTALLED" == true ]; then
    echo -e "  ${COLOR_GREEN}✓${COLOR_NC} Elytra auto-updater enabled"
  else
    echo -e "  ${COLOR_RED}✗${COLOR_NC} Elytra auto-updater not installed"
  fi

  echo ""
  print_brake 70
  echo ""
}

# ------------------ Direct Update Functions ----------------- #

run_panel_update() {
  print_header
  print_flame "Update Pyrodactyl Panel"

  if [ ! -d "/var/www/pyrodactyl" ]; then
    error "Panel is not installed at /var/www/pyrodactyl"
    return 1
  fi

  # Check if auto-updater env file exists
  if [ -f "/etc/pyrodactyl/auto-update-panel.env" ]; then
    output "Using existing auto-updater configuration..."
  else
    # Create temporary env file with defaults
    mkdir -p /etc/pyrodactyl
    echo "PANEL_REPO=\"pyrodactyl-oss/pyrodactyl\"" > /etc/pyrodactyl/auto-update-panel.env
    echo "GITHUB_TOKEN=\"\"" >> /etc/pyrodactyl/auto-update-panel.env
    chmod 600 /etc/pyrodactyl/auto-update-panel.env
  fi

  output "Getting and running panel auto-updater..."
  echo ""

  # Get and run the auto-update script
  if ! get_script "installers" "auto-update-panel"; then
    error "Update failed"
    return 1
  fi
  echo ""
  output "Press Enter to continue..."
  read -r
}

run_elytra_update() {
  print_header
  print_flame "Update Elytra Daemon"

  if [ ! -f "/usr/local/bin/elytra" ]; then
    error "Elytra is not installed at /usr/local/bin/elytra"
    return 1
  fi

  # Check if auto-updater env file exists
  if [ -f "/etc/pyrodactyl/auto-update-elytra.env" ]; then
    output "Using existing auto-updater configuration..."
  else
    # Create temporary env file with defaults
    mkdir -p /etc/pyrodactyl
    echo "ELYTRA_REPO=\"pyrohost/elytra\"" > /etc/pyrodactyl/auto-update-elytra.env
    echo "GITHUB_TOKEN=\"\"" >> /etc/pyrodactyl/auto-update-elytra.env
    chmod 600 /etc/pyrodactyl/auto-update-elytra.env
  fi

  output "Getting and running Elytra auto-updater..."
  echo ""

  # Get and run the auto-update script
  if ! get_script "installers" "auto-update-elytra"; then
    error "Update failed"
    return 1
  fi
  echo ""
  output "Press Enter to continue..."
  read -r
}

run_both_updates() {
  print_header
  print_flame "Update Both Panel and Elytra"

  run_panel_update
  echo ""
  run_elytra_update
}



# Show main menu
show_menu() {
  local choice=""

  while true; do
    show_welcome

    echo ""
    output "${COLOR_ORANGE}What would you like to do?${COLOR_NC}"
    echo ""
    output "[${COLOR_ORANGE}0${COLOR_NC}] Install Pyrodactyl Panel"
    output "[${COLOR_ORANGE}1${COLOR_NC}] Install Elytra Daemon"
    output "[${COLOR_ORANGE}2${COLOR_NC}] Install both Panel and Elytra (same machine)"
    echo ""

    # Update options - gray out if not installed
    local COLOR_DARK_GRAY='\033[90m'
    if [ "$PANEL_INSTALLED" == true ]; then
      output "[${COLOR_ORANGE}3${COLOR_NC}] Update Pyrodactyl Panel"
    else
      echo -e "* [3] ${COLOR_DARK_GRAY}Update Pyrodactyl Panel (not installed)${COLOR_NC}"
    fi

    if [ "$ELYTRA_INSTALLED" == true ]; then
      output "[${COLOR_ORANGE}4${COLOR_NC}] Update Elytra Daemon"
    else
      echo -e "* [4] ${COLOR_DARK_GRAY}Update Elytra Daemon (not installed)${COLOR_NC}"
    fi

    if [ "$PANEL_INSTALLED" == true ] && [ "$ELYTRA_INSTALLED" == true ]; then
      output "[${COLOR_ORANGE}5${COLOR_NC}] Update both Panel and Elytra"
    else
      echo -e "* [5] ${COLOR_DARK_GRAY}Update both Panel and Elytra (not available)${COLOR_NC}"
    fi

    echo ""
    output "[${COLOR_ORANGE}6${COLOR_NC}] Auto Updater Management"
    echo ""
    output "[${COLOR_ORANGE}7${COLOR_NC}] Repair / Fix Common Issues"
    echo ""
    output "[${COLOR_ORANGE}8${COLOR_NC}] Health Check"
    echo ""
    output "[${COLOR_ORANGE}9${COLOR_NC}] Uninstall Pyrodactyl / Elytra"
    echo ""
    output "[${COLOR_ORANGE}10${COLOR_NC}] View Installation Information"
    echo ""
    output "[${COLOR_ORANGE}11${COLOR_NC}] Exit"
    echo ""

    echo -n "* Select an option [0-11]: "
    read -r choice

    case "$choice" in
      0)
        execute_ui "panel"
        continue
        ;;
      1)
        execute_ui "elytra"
        continue
        ;;
      2)
        execute_ui "both"
        continue
        ;;
      3)
        if [ "$PANEL_INSTALLED" == false ]; then
          error "Pyrodactyl Panel is not installed"
          sleep 2
          continue
        fi
        run_panel_update
        continue
        ;;
      4)
        if [ "$ELYTRA_INSTALLED" == false ]; then
          error "Elytra Daemon is not installed"
          sleep 2
          continue
        fi
        run_elytra_update
        continue
        ;;
      5)
        if [ "$PANEL_INSTALLED" == false ] || [ "$ELYTRA_INSTALLED" == false ]; then
          error "Both Panel and Elytra must be installed to use this option"
          sleep 2
          continue
        fi
        run_both_updates
        continue
        ;;
      6)
        execute_ui "auto-updater-menu"
        continue
        ;;
      7)
        execute_ui "repair"
        continue
        ;;
      8)
        # Health Check - runs based on what's installed
        if [ "$PANEL_INSTALLED" == true ] && [ "$ELYTRA_INSTALLED" == true ]; then
          check_both_health
        elif [ "$PANEL_INSTALLED" == true ]; then
          check_panel_health
        elif [ "$ELYTRA_INSTALLED" == true ]; then
          check_elytra_health
        else
          error "Nothing installed to check. Install Pyrodactyl or Elytra first."
          sleep 2
          continue
        fi
        output "Press Enter to return to the menu..."
        read -r
        continue
        ;;
      9)
        execute_ui "uninstall"
        continue
        ;;
      10)
        execute_ui "view-info"
        continue
        ;;
      11)
        output "Exiting..."
        exit 0
        ;;
      *)
        error "Invalid option. Please select 0-11."
        ;;
    esac
  done
}

# Main function
main() {
  check_root
  check_curl

  load_library
  log_execution
  show_welcome

  # Pre-flight system resource check
  echo ""
  output "${COLOR_ORANGE}Running system requirements check...${COLOR_NC}"
  if ! check_system_resources; then
    echo ""
    warning "Your system is below minimum requirements!"
    output "You may experience performance issues or installation failures."
    echo ""
    local continue_anyway=""
    while [[ "$continue_anyway" != "y" && "$continue_anyway" != "n" ]]; do
      echo -n "* Continue anyway? [y/N]: "
      read -r continue_anyway
      continue_anyway=$(echo "$continue_anyway" | tr '[:upper:]' '[:lower:]')
      [ -z "$continue_anyway" ] && continue_anyway="n"

      if [[ "$continue_anyway" != "y" && "$continue_anyway" != "n" ]]; then
        error "Invalid input. Please enter 'y' or 'n'."
      fi
    done

    if [[ "$continue_anyway" == "n" ]]; then
      exit 1
    fi
  fi

  # Check Docker compatibility for Elytra installations
  echo ""
  output "${COLOR_ORANGE}Checking Docker compatibility...${COLOR_NC}"
  check_docker_compatibility || true

  # Run menu/installation
  if show_menu; then
    echo ""
    print_flame "Thank you for using Pyrodactyl Installer!"
  fi

  # Always show log location at the end
  echo ""
  output "Installation log saved to: ${COLOR_ORANGE}$LOG_PATH${COLOR_NC}"
  echo ""
}

# Run main
main "$@"