From 39177e6495db5633a04e4561477545141ee02f33 Mon Sep 17 00:00:00 2001 From: Zak Bearman Date: Tue, 13 Jan 2026 23:22:26 +0000 Subject: [PATCH] Add install.sh --- install.sh | 329 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 install.sh diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..bb2be46 --- /dev/null +++ b/install.sh @@ -0,0 +1,329 @@ +#!/usr/bin/env bash +set -euo pipefail + +####################################### +# STATE TRACKING +####################################### +STATE_FILE="/var/log/pterodactyl_node_state" +mkdir -p $(dirname "$STATE_FILE") +touch "$STATE_FILE" + +mark_done() { + echo "$1" >> "$STATE_FILE" +} + +is_done() { + grep -qx "$1" "$STATE_FILE" || false +} + +save_var() { + echo "$1=$2" >> "$STATE_FILE" +} + +load_var() { + grep "^$1=" "$STATE_FILE" | cut -d= -f2 +} + +####################################### +# CONFIG +####################################### +PANEL_URL="https://panel.amslabs.net" +PTERO_API_KEY="ptla_1qpEnNZxXFAPAvjJrtRdlX5oRaDWYBImKuizXMzYne1" +PTERO_LOCATION_ID=1 + +CLOUDFLARE_API_TOKEN="tIrFGHOC40BuhlAsRKJYWLm-k0SH9fsnGFoKEqI4" +CLOUDFLARE_ZONE_ID="902bc1958422630ff8ce974e84af3a05" +DOMAIN="amslabs.net" +PUBLIC_IP="121.99.242.84" + +DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/1460095439930916915/PJiafXkssc4NyLXdCAGGdvGxwpo93z4Gso_LBSGKKX_E9k0CDm8Uq2dbTtYXNJzXcJHN" + +HOSTS_TEMPLATE="/etc/cloud/templates/hosts.debian.tmpl" +HOSTS_FILE="/etc/hosts" +WINGS_BIN="/usr/local/bin/wings" +WINGS_DIR="/etc/pterodactyl" + +####################################### +# INPUTS +####################################### +if ! is_done "input_hostname"; then + read -rp "Enter host name (e.g. node03): " HOSTNAME + save_var "HOSTNAME" "$HOSTNAME" +else + HOSTNAME=$(load_var HOSTNAME) +fi + +FQDN="${HOSTNAME}.${DOMAIN}" + +if ! is_done "daemon_ports"; then + read -rp "Enter Wings daemon listen port (e.g. 8082): " DAEMON_LISTEN + read -rp "Enter Wings daemon SFTP port (e.g. 2024): " DAEMON_SFTP + save_var "DAEMON_LISTEN" "$DAEMON_LISTEN" + save_var "DAEMON_SFTP" "$DAEMON_SFTP" +else + DAEMON_LISTEN=$(load_var DAEMON_LISTEN) + DAEMON_SFTP=$(load_var DAEMON_SFTP) +fi + +if ! is_done "resources"; then + echo "Select memory option:" + echo "1) 32768 MB" + echo "2) 65536 MB" + echo "3) 92160 MB" + read -rp "Choice [1-3]: " MEM_CHOICE + case "$MEM_CHOICE" in + 1) MEMORY=32768 ;; + 2) MEMORY=65536 ;; + 3) MEMORY=92160 ;; + *) MEMORY=65536 ;; + esac + + echo "Select disk option:" + echo "1) 32768 MB" + echo "2) 65536 MB" + echo "3) 92160 MB" + read -rp "Choice [1-3]: " DISK_CHOICE + case "$DISK_CHOICE" in + 1) DISK=32768 ;; + 2) DISK=65536 ;; + 3) DISK=92160 ;; + *) DISK=65536 ;; + esac + + save_var "MEMORY" "$MEMORY" + save_var "DISK" "$DISK" +else + MEMORY=$(load_var MEMORY) + DISK=$(load_var DISK) +fi + +echo "🚀 Bootstrapping ${FQDN}" + +####################################### +# HOSTS TEMPLATE +####################################### +if ! is_done "hosts_template"; then + sudo tee "${HOSTS_TEMPLATE}" >/dev/null </dev/null + else + curl -s -X POST \ + -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "$DNS_PAYLOAD" \ + "https://api.cloudflare.com/client/v4/zones/${CLOUDFLARE_ZONE_ID}/dns_records" >/dev/null + fi + mark_done "cloudflare_dns" +fi + +####################################### +# PACKAGES +####################################### +if ! is_done "packages"; then + sudo apt update + sudo apt install -y curl jq docker.io certbot python3-certbot-dns-cloudflare + sudo systemctl enable docker --now + mark_done "packages" +fi + +####################################### +# CREATE NODE +####################################### +if ! is_done "node_created"; then + echo "📦 Creating node in panel" + + NODE_PAYLOAD=$(jq -n \ + --arg name "$HOSTNAME" \ + --arg fqdn "$FQDN" \ + --argjson location "$PTERO_LOCATION_ID" \ + --argjson memory "$MEMORY" \ + --argjson disk "$DISK" \ + --argjson daemon_listen "$DAEMON_LISTEN" \ + --argjson daemon_sftp "$DAEMON_SFTP" \ + '{ + name: $fqdn, + location_id: $location, + fqdn: $fqdn, + scheme: "https", + memory: $memory, + memory_overallocate: 0, + disk: $disk, + disk_overallocate: 0, + daemon_listen: $daemon_listen, + daemon_sftp: $daemon_sftp, + daemon_base: "/var/lib/pterodactyl/volumes", + upload_size: 100 + }') + + NODE_RESPONSE=$(curl -s -X POST \ + "${PANEL_URL}/api/application/nodes" \ + -H "Authorization: Bearer ${PTERO_API_KEY}" \ + -H "Accept: Application/vnd.pterodactyl.v1+json" \ + -H "Content-Type: application/json" \ + --data "$NODE_PAYLOAD") + + echo "📄 Node creation response:" + echo "$NODE_RESPONSE" | jq + + NODE_ID=$(echo "$NODE_RESPONSE" | jq -r '.attributes.id // empty') + if [[ -z "$NODE_ID" ]]; then + echo "❌ Node creation failed, check API key, permissions, and values." + exit 1 + fi + + save_var "NODE_ID" "$NODE_ID" + mark_done "node_created" +fi + +####################################### +# INSTALL WINGS +####################################### +if ! is_done "wings_installed"; then + sudo mkdir -p "${WINGS_DIR}" + curl -Lo "${WINGS_BIN}" https://github.com/pterodactyl/wings/releases/latest/download/wings_linux_amd64 + sudo chmod +x "${WINGS_BIN}" + + sudo tee /etc/systemd/system/wings.service >/dev/null </dev/null + sudo chmod 600 "${WINGS_DIR}/config.yml" + mark_done "node_deployed" + echo "✅ Fetched config.yml successfully" + break + else + echo "❌ Failed to fetch config, attempt $i/3" + sleep 5 + fi + done + + if [[ ! -f "${WINGS_DIR}/config.yml" ]]; then + echo "❌ Could not fetch config.yml from Panel" + echo "$CONFIG_RESPONSE" | jq + exit 1 + fi +fi + +####################################### +# CERTBOT +####################################### +if ! is_done "certbot_done"; then + sudo mkdir -p /root/.secrets/certbot + sudo tee /root/.secrets/certbot/cloudflare.ini >/dev/null </dev/null <