#!/usr/bin/env bash # -------------------------------------------------------------- # Pterodactyl Panel – LAN‑only installer for Raspberry Pi OS # -------------------------------------------------------------- # What it does: # • Installs Nginx, MariaDB, Redis, PHP‑8.2, Composer, Git, … # • Creates a local MySQL database (no remote access) # • Downloads the latest panel release, configures .env # • Runs migrations, seeds, creates an admin user (no prompts) # • Configures Nginx to listen on the Pi's LAN IP (or 0.0.0.0) # • Sets up a tiny ufw firewall that only allows HTTP from the LAN # • Installs a systemd service for the queue worker (pteroq) # • Prints a short “install summary” # # Requirements: # • Raspberry Pi OS (Debian‑based) – tested on 64‑bit Bullseye & Bookworm # • At least 1 GB RAM (2 GB+ recommended) # • Run the script as root (or with sudo) # # -------------------------------------------------------------- set -euo pipefail # abort on error, treat unset vars as errors # ------------------------------------------------------------------------- # 1️⃣ USER‑CONFIGURABLE SETTINGS – change them before you run the script # ------------------------------------------------------------------------- # If you want a custom domain (e.g. panel.local) you can set APP_DOMAIN # to that value. The script will still bind to the LAN IP. APP_DOMAIN="panel.local" APP_DIR="/var/www/pterodactyl" DB_NAME="panel" DB_USER="pterodactyl" DB_PASS="$(tr -dc 'A-Za-z0-9' > .env fi } # ------------------------------------------------------------------------- # 4️⃣ PRE‑FLIGHT CHECKS # ------------------------------------------------------------------------- if [[ $EUID -ne 0 ]]; then echo "❌ This script must be run as root. Use: sudo $0" exit 1 fi if [[ -d "$APP_DIR" ]]; then echo "❌ Directory $APP_DIR already exists – aborting to avoid overwriting." exit 1 fi if ! command -v apt-get >/dev/null 2>&1; then echo "❌ apt-get not found – this script only works on Debian‑based systems." exit 1 fi # ------------------------------------------------------------------------- # 5️⃣ DETERMINE LAN IP (the address that other Wi‑Fi devices will use) # ------------------------------------------------------------------------- # We look for the first non‑loopback, non‑docker, IPv4 address. LAN_IP=$(ip -4 addr show scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n1 || true) if [[ -z "$LAN_IP" ]]; then echo "⚠️ Could not auto‑detect a LAN IP. Falling back to 0.0.0.0 (listen on all interfaces)." LAN_IP="0.0.0.0" fi APP_URL="http://${LAN_IP}" echo "🔎 Detected LAN IP: $LAN_IP → APP_URL will be $APP_URL" # ------------------------------------------------------------------------- # 6️⃣ UPDATE & INSTALL DEPENDENCIES # ------------------------------------------------------------------------- echo "🔧 [1/10] Updating package list and installing required packages…" apt-get update -y apt-get upgrade -y apt-get install -y \ nginx \ mariadb-server \ redis-server \ php${PHP_VERSION}-fpm php${PHP_VERSION}-cli php${PHP_VERSION}-mysql php${PHP_VERSION}-gd \ php${PHP_VERSION}-zip php${PHP_VERSION}-mbstring php${PHP_VERSION}-bcmath php${PHP_VERSION}-xml \ php${PHP_VERSION}-curl php${PHP_VERSION}-intl php${PHP_VERSION}-redis \ curl unzip git ca-certificates gnupg lsb-release software-properties-common ufw # Enable & start services systemctl enable --now mariadb systemctl enable --now redis-server systemctl enable --now nginx systemctl enable --now "${PHP_FPM_SERVICE}" # ------------------------------------------------------------------------- # 7️⃣ INSTALL COMPOSER (global) # ------------------------------------------------------------------------- if ! command -v composer >/dev/null 2>&1; then echo "🔧 [2/10] Installing Composer…" EXPECTED_CHECKSUM="$(curl -s https://composer.github.io/installer.sig)" php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then echo "❌ Composer installer corrupt – aborting." rm composer-setup.php exit 1 fi php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer rm composer-setup.php else echo "✅ Composer already installed." fi # ------------------------------------------------------------------------- # 8️⃣ DATABASE SETUP (local only) # ------------------------------------------------------------------------- echo "🔧 [3/10] Creating MySQL database and user…" # MariaDB on Pi OS uses unix_socket auth for root, so we can run as root without a password. mysql -u root < "${NGINX_CONF}" < /etc/systemd/system/pteroq.service <