{ "_comment": "Forge AIO — The Ultimate All-in-One Egg", "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-05-19T00:00:00+00:00", "name": "Forge AIO", "author": "admin@forged.james.gg", "description": "The ultimate all-in-one egg. Interactive setup wizard on first boot lets you pick exactly what to run — game servers (SteamCMD), bots, websites, databases, language runtimes, or fully custom apps. Auto-installs everything. Reconfigure anytime with 'forgeaio setup'.", "features": null, "docker_images": { "Forge AIO (Debian)": "ghcr.io/parkervcp/yolks:debian" }, "file_denylist": [], "startup": "bash /home/container/.forge-aio/entrypoint.sh", "config": { "files": "{}", "startup": "{\r\n \"done\": [\r\n \"[Forge AIO] Service is running\",\r\n \"[Forge AIO] Ready\"\r\n ]\r\n}", "logs": "{}", "stop": "^^C" }, "scripts": { "installation": { "script": "#!/bin/bash\n## Forge AIO — Install Script\n## This runs ONCE inside the installer container at /mnt/server\n\nset -e\napt update -y\napt install -y curl wget git jq unzip tar xz-utils ca-certificates gnupg lsb-release \\\n build-essential gcc g++ make cmake python3 python3-pip python3-venv \\\n lib32gcc-s1 lib32stdc++6 software-properties-common file procps\n\nmkdir -p /mnt/server/.forge-aio\n\n## ─── Entrypoint Script ───────────────────────────────────────────────────────\ncat > /mnt/server/.forge-aio/entrypoint.sh << 'ENTRYPOINT_EOF'\n#!/bin/bash\n# ______ _ _____ ____\n# | ____| / \\ |_ _|/ __ \\\n# | |__ ___ _ __ __ _ ___ / _ \\ | | | | | |\n# | __/ _ \\| '__/ _` |/ _ \\ / ___ \\ | | | | | |\n# | | | (_) | | | (_| | __/ /_/ \\_\\_|_| \\____/\n# |_| \\___/|_| \\__, |\\___|\n# |___/\n# The Ultimate All-In-One Server Egg\n\nCONFIG_FILE=\"/home/container/.forge-aio/config.json\"\nLOG_PREFIX=\"[Forge AIO]\"\nVERSION=\"2.0.0\"\n\nC_RESET=\"\\033[0m\"\nC_BOLD=\"\\033[1m\"\nC_DIM=\"\\033[2m\"\nC_RED=\"\\033[31m\"\nC_GREEN=\"\\033[32m\"\nC_YELLOW=\"\\033[33m\"\nC_BLUE=\"\\033[34m\"\nC_MAGENTA=\"\\033[35m\"\nC_CYAN=\"\\033[36m\"\nC_WHITE=\"\\033[37m\"\nC_BG_BLUE=\"\\033[44m\"\n\nprint_banner() {\n echo -e \"${C_CYAN}${C_BOLD}\"\n echo \" ╔══════════════════════════════════════════════════════╗\"\n echo \" ║ ⚒️ FORGE AIO v${VERSION} ║\"\n echo \" ║ The Ultimate All-In-One Server Egg ║\"\n echo \" ╚══════════════════════════════════════════════════════╝\"\n echo -e \"${C_RESET}\"\n}\n\nprint_line() {\n echo -e \"${C_DIM} ──────────────────────────────────────────────────────${C_RESET}\"\n}\n\nprint_info() { echo -e \" ${C_BLUE}ℹ${C_RESET} $1\"; }\nprint_success() { echo -e \" ${C_GREEN}✓${C_RESET} $1\"; }\nprint_warn() { echo -e \" ${C_YELLOW}⚠${C_RESET} $1\"; }\nprint_error() { echo -e \" ${C_RED}✗${C_RESET} $1\"; }\nprint_step() { echo -e \"\\n ${C_MAGENTA}▸${C_RESET} ${C_BOLD}$1${C_RESET}\"; }\n\nprompt_choice() {\n local prompt=\"$1\"\n local result_var=\"$2\"\n echo -en \" ${C_CYAN}▸${C_RESET} ${prompt}: \"\n read -r choice\n eval \"$result_var=\\\"$choice\\\"\"\n}\n\nprompt_default() {\n local prompt=\"$1\"\n local default=\"$2\"\n local result_var=\"$3\"\n echo -en \" ${C_CYAN}▸${C_RESET} ${prompt} ${C_DIM}[${default}]${C_RESET}: \"\n read -r input\n if [ -z \"$input\" ]; then\n eval \"$result_var=\\\"$default\\\"\"\n else\n eval \"$result_var=\\\"$input\\\"\"\n fi\n}\n\nconfirm_yn() {\n local prompt=\"$1\"\n local default=\"${2:-y}\"\n echo -en \" ${C_CYAN}▸${C_RESET} ${prompt} ${C_DIM}[${default}]${C_RESET}: \"\n read -r yn\n yn=${yn:-$default}\n [[ \"$yn\" =~ ^[Yy] ]]\n}\n\nsave_config() {\n cat > \"$CONFIG_FILE\" << EOF\n{\n \"version\": \"${VERSION}\",\n \"type\": \"${AIO_TYPE}\",\n \"category\": \"${AIO_CATEGORY}\",\n \"software\": \"${AIO_SOFTWARE}\",\n \"startup_cmd\": \"${AIO_STARTUP_CMD}\",\n \"install_cmd\": \"${AIO_INSTALL_CMD}\",\n \"configured\": true,\n \"configured_at\": \"$(date -Iseconds)\"\n}\nEOF\n print_success \"Configuration saved!\"\n}\n\nload_config() {\n if [ -f \"$CONFIG_FILE\" ]; then\n AIO_TYPE=$(jq -r '.type // empty' \"$CONFIG_FILE\" 2>/dev/null)\n AIO_CATEGORY=$(jq -r '.category // empty' \"$CONFIG_FILE\" 2>/dev/null)\n AIO_SOFTWARE=$(jq -r '.software // empty' \"$CONFIG_FILE\" 2>/dev/null)\n AIO_STARTUP_CMD=$(jq -r '.startup_cmd // empty' \"$CONFIG_FILE\" 2>/dev/null)\n AIO_INSTALL_CMD=$(jq -r '.install_cmd // empty' \"$CONFIG_FILE\" 2>/dev/null)\n return 0\n fi\n return 1\n}\n\n## ─── Installation Functions ──────────────────────────────────────────────────\n\ninstall_nvm_node() {\n local ver=\"${1:-20}\"\n print_info \"Installing Node.js v${ver} via nvm...\"\n export NVM_DIR=\"/home/container/.nvm\"\n if [ ! -d \"$NVM_DIR\" ]; then\n curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash\n fi\n source \"$NVM_DIR/nvm.sh\"\n nvm install \"$ver\" && nvm use \"$ver\"\n print_success \"Node.js $(node -v) + npm $(npm -v) installed\"\n}\n\ninstall_python() {\n local ver=\"${1:-3}\"\n print_info \"Setting up Python ${ver}...\"\n if ! command -v python3 &>/dev/null; then\n apt-get update -qq && apt-get install -y -qq python3 python3-pip python3-venv\n fi\n # Create venv if not exists\n if [ ! -d \"/home/container/.venv\" ]; then\n python3 -m venv /home/container/.venv\n fi\n source /home/container/.venv/bin/activate\n print_success \"Python $(python3 --version) ready\"\n}\n\ninstall_java() {\n local ver=\"${1:-17}\"\n print_info \"Installing Java ${ver}...\"\n # Use adoptium or existing java\n if ! command -v java &>/dev/null; then\n apt-get update -qq\n apt-get install -y -qq openjdk-${ver}-jre-headless 2>/dev/null || {\n curl -fsSL https://api.adoptium.net/v3/binary/latest/${ver}/ga/linux/x64/jre/hotspot/normal/eclipse -o /tmp/java.tar.gz\n mkdir -p /home/container/.java\n tar xzf /tmp/java.tar.gz -C /home/container/.java --strip-components=1\n export PATH=\"/home/container/.java/bin:$PATH\"\n rm -f /tmp/java.tar.gz\n }\n fi\n print_success \"Java $(java -version 2>&1 | head -1) installed\"\n}\n\ninstall_go() {\n print_info \"Installing Go...\"\n local GO_VER=$(curl -fsSL 'https://go.dev/VERSION?m=text' | head -1)\n curl -fsSL \"https://go.dev/dl/${GO_VER}.linux-amd64.tar.gz\" -o /tmp/go.tar.gz\n mkdir -p /home/container/.go\n tar xzf /tmp/go.tar.gz -C /home/container/.go --strip-components=1\n export PATH=\"/home/container/.go/bin:$PATH\"\n export GOPATH=\"/home/container/go\"\n rm -f /tmp/go.tar.gz\n print_success \"Go $(go version) installed\"\n}\n\ninstall_rust() {\n print_info \"Installing Rust...\"\n export RUSTUP_HOME=\"/home/container/.rustup\"\n export CARGO_HOME=\"/home/container/.cargo\"\n curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path\n source \"/home/container/.cargo/env\"\n print_success \"Rust $(rustc --version) installed\"\n}\n\ninstall_steamcmd() {\n print_info \"Installing SteamCMD...\"\n mkdir -p /home/container/.steamcmd\n cd /home/container/.steamcmd\n if [ ! -f \"steamcmd.sh\" ]; then\n curl -fsSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xzf -\n fi\n chmod +x steamcmd.sh\n print_success \"SteamCMD installed\"\n}\n\ninstall_mongodb() {\n print_info \"Installing MongoDB...\"\n curl -fsSL https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2204-7.0.11.tgz -o /tmp/mongo.tgz\n mkdir -p /home/container/.mongodb/bin /home/container/.mongodb/data\n tar xzf /tmp/mongo.tgz -C /home/container/.mongodb/bin --strip-components=2 --wildcards '*/bin/*'\n rm -f /tmp/mongo.tgz\n export PATH=\"/home/container/.mongodb/bin:$PATH\"\n print_success \"MongoDB installed\"\n}\n\ninstall_redis() {\n print_info \"Installing Redis...\"\n cd /tmp\n curl -fsSL https://download.redis.io/redis-stable.tar.gz | tar xzf -\n cd redis-stable && make -j$(nproc) PREFIX=/home/container/.redis install\n cd /home/container && rm -rf /tmp/redis-stable\n export PATH=\"/home/container/.redis/bin:$PATH\"\n print_success \"Redis installed\"\n}\n\ninstall_mariadb() {\n print_info \"Installing MariaDB...\"\n apt-get update -qq && apt-get install -y -qq mariadb-server 2>/dev/null || {\n print_warn \"Using manual MariaDB install...\"\n curl -fsSL https://downloads.mariadb.com/MariaDB/mariadb-11.4.0/bintar-linux-systemd-x86_64/mariadb-11.4.0-linux-systemd-x86_64.tar.gz -o /tmp/maria.tar.gz\n mkdir -p /home/container/.mariadb\n tar xzf /tmp/maria.tar.gz -C /home/container/.mariadb --strip-components=1\n rm -f /tmp/maria.tar.gz\n }\n print_success \"MariaDB installed\"\n}\n\ninstall_postgres() {\n print_info \"Installing PostgreSQL...\"\n apt-get update -qq && apt-get install -y -qq postgresql postgresql-client 2>/dev/null || {\n print_warn \"PostgreSQL install via apt failed, trying manual...\"\n }\n print_success \"PostgreSQL installed\"\n}\n\ninstall_nginx() {\n print_info \"Installing Nginx...\"\n apt-get update -qq && apt-get install -y -qq nginx 2>/dev/null || {\n print_warn \"Nginx apt install failed, using static binary...\"\n }\n print_success \"Nginx installed\"\n}\n\ninstall_php() {\n local ver=\"${1:-8.3}\"\n print_info \"Installing PHP ${ver}...\"\n apt-get update -qq && apt-get install -y -qq php php-cli php-fpm php-mysql php-zip php-gd php-mbstring php-curl php-xml 2>/dev/null\n print_success \"PHP installed\"\n}\n\n## ─── Game Server Helper ──────────────────────────────────────────────────────\n\nsetup_game_steamcmd() {\n local app_id=\"$1\"\n local game_name=\"$2\"\n local extra_args=\"${3:-}\"\n \n install_steamcmd\n \n print_info \"Downloading ${game_name} (App ID: ${app_id})...\"\n /home/container/.steamcmd/steamcmd.sh \\\n +force_install_dir /home/container/server \\\n +login anonymous \\\n +app_update \"${app_id}\" ${extra_args} validate \\\n +quit\n \n print_success \"${game_name} downloaded!\"\n}\n\n## ─── Setup Wizard ────────────────────────────────────────────────────────────\n\nwizard_game_server() {\n print_step \"Game Server Setup\"\n echo \"\"\n echo -e \" ${C_WHITE}${C_BOLD}Pick your game:${C_RESET}\"\n echo \"\"\n echo -e \" ${C_YELLOW} 1)${C_RESET} Minecraft (Paper) ${C_YELLOW}14)${C_RESET} Palworld\"\n echo -e \" ${C_YELLOW} 2)${C_RESET} Minecraft (Forge) ${C_YELLOW}15)${C_RESET} Satisfactory\"\n echo -e \" ${C_YELLOW} 3)${C_RESET} Minecraft (Fabric) ${C_YELLOW}16)${C_RESET} V Rising\"\n echo -e \" ${C_YELLOW} 4)${C_RESET} Minecraft (Bedrock) ${C_YELLOW}17)${C_RESET} Enshrouded\"\n echo -e \" ${C_YELLOW} 5)${C_RESET} Minecraft (Purpur) ${C_YELLOW}18)${C_RESET} Terraria (tShock)\"\n echo -e \" ${C_YELLOW} 6)${C_RESET} Minecraft (Spigot) ${C_YELLOW}19)${C_RESET} 7 Days to Die\"\n echo -e \" ${C_YELLOW} 7)${C_RESET} CS2 / CSGO ${C_YELLOW}20)${C_RESET} Unturned\"\n echo -e \" ${C_YELLOW} 8)${C_RESET} Garry's Mod ${C_YELLOW}21)${C_RESET} Barotrauma\"\n echo -e \" ${C_YELLOW} 9)${C_RESET} Rust ${C_YELLOW}22)${C_RESET} SCP: Secret Lab\"\n echo -e \" ${C_YELLOW}10)${C_RESET} ARK: Survival Evolved ${C_YELLOW}23)${C_RESET} Project Zomboid\"\n echo -e \" ${C_YELLOW}11)${C_RESET} ARK: Survival Ascended ${C_YELLOW}24)${C_RESET} Valheim\"\n echo -e \" ${C_YELLOW}12)${C_RESET} DayZ ${C_YELLOW}25)${C_RESET} The Forest\"\n echo -e \" ${C_YELLOW}13)${C_RESET} Conan Exiles ${C_YELLOW}26)${C_RESET} Custom SteamCMD App\"\n echo \"\"\n prompt_choice \"Enter number\" game_pick\n \n AIO_CATEGORY=\"Game Server\"\n \n case $game_pick in\n 1) AIO_SOFTWARE=\"Minecraft Paper\"\n install_java 21\n print_info \"Downloading Paper...\"\n local mc_ver\n prompt_default \"Minecraft version\" \"1.21.4\" mc_ver\n local build=$(curl -fsSL \"https://api.papermc.io/v2/projects/paper/versions/${mc_ver}/builds\" | jq '.builds[-1].build')\n curl -fsSL \"https://api.papermc.io/v2/projects/paper/versions/${mc_ver}/builds/${build}/downloads/paper-${mc_ver}-${build}.jar\" -o /home/container/server.jar\n AIO_STARTUP_CMD=\"java -Xms128M -Xmx\\${SERVER_MEMORY}M -jar server.jar nogui\"\n AIO_INSTALL_CMD=\"echo eula=true > eula.txt\"\n ;;\n 2) AIO_SOFTWARE=\"Minecraft Forge\"\n install_java 17\n print_info \"Downloading Forge installer...\"\n local forge_ver\n prompt_default \"Forge version (e.g. 1.20.1-47.2.0)\" \"1.20.1-47.2.0\" forge_ver\n curl -fsSL \"https://maven.minecraftforge.net/net/minecraftforge/forge/${forge_ver}/forge-${forge_ver}-installer.jar\" -o /home/container/forge-installer.jar\n cd /home/container && java -jar forge-installer.jar --installServer\n rm -f forge-installer.jar\n AIO_STARTUP_CMD=\"java -Xms128M -Xmx\\${SERVER_MEMORY}M @libraries/net/minecraftforge/forge/${forge_ver}/unix_args.txt nogui\"\n AIO_INSTALL_CMD=\"echo eula=true > eula.txt\"\n ;;\n 3) AIO_SOFTWARE=\"Minecraft Fabric\"\n install_java 21\n print_info \"Downloading Fabric...\"\n curl -fsSL \"https://meta.fabricmc.net/v2/versions/installer\" -o /tmp/fab.json\n local fab_url=$(jq -r '.[0].url' /tmp/fab.json)\n curl -fsSL \"$fab_url\" -o /home/container/fabric-installer.jar\n cd /home/container\n local mc_ver\n prompt_default \"Minecraft version\" \"1.21.4\" mc_ver\n java -jar fabric-installer.jar server -mcversion \"$mc_ver\" -downloadMinecraft\n rm -f fabric-installer.jar\n AIO_STARTUP_CMD=\"java -Xms128M -Xmx\\${SERVER_MEMORY}M -jar fabric-server-launch.jar nogui\"\n AIO_INSTALL_CMD=\"echo eula=true > eula.txt\"\n ;;\n 4) AIO_SOFTWARE=\"Minecraft Bedrock\"\n print_info \"Downloading Bedrock Dedicated Server...\"\n local bds_url=$(curl -fsSL \"https://raw.githubusercontent.com/nicholasgasior/bds-downloads/main/versions.json\" | jq -r '.linux | to_entries | sort_by(.key) | last | .value')\n curl -fsSL \"$bds_url\" -o /tmp/bedrock.zip\n cd /home/container && unzip -o /tmp/bedrock.zip\n chmod +x bedrock_server\n rm -f /tmp/bedrock.zip\n AIO_STARTUP_CMD=\"LD_LIBRARY_PATH=. ./bedrock_server\"\n ;;\n 5) AIO_SOFTWARE=\"Minecraft Purpur\"\n install_java 21\n local mc_ver\n prompt_default \"Minecraft version\" \"1.21.4\" mc_ver\n curl -fsSL \"https://api.purpurmc.org/v2/purpur/${mc_ver}/latest/download\" -o /home/container/server.jar\n AIO_STARTUP_CMD=\"java -Xms128M -Xmx\\${SERVER_MEMORY}M -jar server.jar nogui\"\n AIO_INSTALL_CMD=\"echo eula=true > eula.txt\"\n ;;\n 6) AIO_SOFTWARE=\"Minecraft Spigot\"\n install_java 17\n curl -fsSL \"https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar\" -o /home/container/BuildTools.jar\n cd /home/container && java -jar BuildTools.jar --rev latest\n mv spigot-*.jar server.jar\n rm -f BuildTools.jar\n AIO_STARTUP_CMD=\"java -Xms128M -Xmx\\${SERVER_MEMORY}M -jar server.jar nogui\"\n AIO_INSTALL_CMD=\"echo eula=true > eula.txt\"\n ;;\n 7) AIO_SOFTWARE=\"CS2\"; setup_game_steamcmd 730 \"Counter-Strike 2\"\n AIO_STARTUP_CMD=\"cd server && ./game/bin/linuxsteamrt64/cs2 -dedicated -port \\${SERVER_PORT} +game_type 0 +game_mode 0 +map de_dust2\"\n ;;\n 8) AIO_SOFTWARE=\"Garry's Mod\"; setup_game_steamcmd 4020 \"Garry's Mod\"\n AIO_STARTUP_CMD=\"cd server && ./srcds_run -game garrysmod -port \\${SERVER_PORT} +maxplayers 16 +map gm_flatgrass\"\n ;;\n 9) AIO_SOFTWARE=\"Rust\"; setup_game_steamcmd 258550 \"Rust Dedicated Server\"\n AIO_STARTUP_CMD=\"cd server && ./RustDedicated -batchmode +server.port \\${SERVER_PORT} +server.level Procedural Map +server.maxplayers 50\"\n ;;\n 10) AIO_SOFTWARE=\"ARK SE\"; setup_game_steamcmd 376030 \"ARK: Survival Evolved Server\"\n AIO_STARTUP_CMD=\"cd server/ShooterGame/Binaries/Linux && ./ShooterGameServer TheIsland?listen -server -log\"\n ;;\n 11) AIO_SOFTWARE=\"ARK SA\"; setup_game_steamcmd 2430930 \"ARK: Survival Ascended Server\"\n AIO_STARTUP_CMD=\"cd server && ./ShooterGame/Binaries/Win64/ArkAscendedServer.exe TheIsland_WP?listen -server -log\"\n ;;\n 12) AIO_SOFTWARE=\"DayZ\"; setup_game_steamcmd 223350 \"DayZ Server\"\n AIO_STARTUP_CMD=\"cd server && ./DayZServer -config=serverDZ.cfg -port=\\${SERVER_PORT}\"\n ;;\n 13) AIO_SOFTWARE=\"Conan Exiles\"; setup_game_steamcmd 443030 \"Conan Exiles Server\"\n AIO_STARTUP_CMD=\"cd server && ./ConanSandboxServer -log\"\n ;;\n 14) AIO_SOFTWARE=\"Palworld\"; setup_game_steamcmd 2394010 \"Palworld Server\"\n AIO_STARTUP_CMD=\"cd server && ./PalServer.sh -port=\\${SERVER_PORT}\"\n ;;\n 15) AIO_SOFTWARE=\"Satisfactory\"; setup_game_steamcmd 1690800 \"Satisfactory Server\"\n AIO_STARTUP_CMD=\"cd server && ./FactoryServer.sh -Port=\\${SERVER_PORT}\"\n ;;\n 16) AIO_SOFTWARE=\"V Rising\"; setup_game_steamcmd 1829350 \"V Rising Server\"\n AIO_STARTUP_CMD=\"cd server && ./VRisingServer -persistentDataPath ./save-data -logFile ./logs/VRisingServer.log\"\n ;;\n 17) AIO_SOFTWARE=\"Enshrouded\"; setup_game_steamcmd 2278520 \"Enshrouded Server\"\n AIO_STARTUP_CMD=\"cd server && ./enshrouded_server\"\n ;;\n 18) AIO_SOFTWARE=\"Terraria\"; \n print_info \"Downloading tShock...\"\n local tshock_url=$(curl -fsSL \"https://api.github.com/repos/Pryaxis/TShock/releases/latest\" | jq -r '.assets[0].browser_download_url')\n mkdir -p /home/container/server\n curl -fsSL \"$tshock_url\" -o /tmp/tshock.zip\n cd /home/container/server && unzip -o /tmp/tshock.zip && rm /tmp/tshock.zip\n chmod +x TShock.Server\n AIO_STARTUP_CMD=\"cd server && ./TShock.Server -port \\${SERVER_PORT} -maxplayers 8 -world /home/container/server/worlds/world.wld -autocreate 3\"\n ;;\n 19) AIO_SOFTWARE=\"7 Days to Die\"; setup_game_steamcmd 294420 \"7 Days to Die Server\"\n AIO_STARTUP_CMD=\"cd server && ./7DaysToDieServer.x86_64 -logfile /dev/stdout -configfile=serverconfig.xml\"\n ;;\n 20) AIO_SOFTWARE=\"Unturned\"; setup_game_steamcmd 1110390 \"Unturned Server\"\n AIO_STARTUP_CMD=\"cd server && ./Unturned -batchmode -nographics +InternetServer/\\${SERVER_PORT}\"\n ;;\n 21) AIO_SOFTWARE=\"Barotrauma\"; setup_game_steamcmd 1026340 \"Barotrauma Server\"\n AIO_STARTUP_CMD=\"cd server && ./DedicatedServer\"\n ;;\n 22) AIO_SOFTWARE=\"SCP: Secret Lab\"; setup_game_steamcmd 996560 \"SCP:SL Server\"\n AIO_STARTUP_CMD=\"cd server && ./LocalAdmin \\${SERVER_PORT}\"\n ;;\n 23) AIO_SOFTWARE=\"Project Zomboid\"; setup_game_steamcmd 380870 \"Project Zomboid Server\"\n AIO_STARTUP_CMD=\"cd server && ./start-server.sh\"\n ;;\n 24) AIO_SOFTWARE=\"Valheim\"; setup_game_steamcmd 896660 \"Valheim Server\"\n local sv_name\n prompt_default \"Server name\" \"Forge Valheim\" sv_name\n AIO_STARTUP_CMD=\"cd server && ./valheim_server.x86_64 -name \\\"${sv_name}\\\" -port \\${SERVER_PORT} -world Dedicated -password secret -public 1\"\n ;;\n 25) AIO_SOFTWARE=\"The Forest\"; setup_game_steamcmd 556450 \"The Forest Server\"\n AIO_STARTUP_CMD=\"cd server && wine64 TheForestDedicatedServer.exe -serverip 0.0.0.0 -serversteamport \\${SERVER_PORT}\"\n ;;\n 26) AIO_SOFTWARE=\"Custom SteamCMD\"\n local app_id\n prompt_choice \"Enter Steam App ID\" app_id\n local custom_name\n prompt_default \"Game name\" \"Custom Game\" custom_name\n setup_game_steamcmd \"$app_id\" \"$custom_name\"\n local custom_cmd\n prompt_choice \"Enter startup command (relative to server/)\" custom_cmd\n AIO_STARTUP_CMD=\"cd server && ${custom_cmd}\"\n ;;\n *) print_error \"Invalid choice\"; return 1 ;;\n esac\n AIO_TYPE=\"game_server\"\n}\n\nwizard_bot_app() {\n print_step \"Bot / Application Setup\"\n echo \"\"\n echo -e \" ${C_WHITE}${C_BOLD}What are you building?${C_RESET}\"\n echo \"\"\n echo -e \" ${C_YELLOW} 1)${C_RESET} Node.js Bot/App (Discord.js, etc.)\"\n echo -e \" ${C_YELLOW} 2)${C_RESET} Python Bot/App (discord.py, etc.)\"\n echo -e \" ${C_YELLOW} 3)${C_RESET} Java Application\"\n echo -e \" ${C_YELLOW} 4)${C_RESET} Bun Application\"\n echo -e \" ${C_YELLOW} 5)${C_RESET} Go Application\"\n echo -e \" ${C_YELLOW} 6)${C_RESET} Rust Application\"\n echo -e \" ${C_YELLOW} 7)${C_RESET} C# / .NET Application\"\n echo -e \" ${C_YELLOW} 8)${C_RESET} Red Discord Bot (Redbot)\"\n echo -e \" ${C_YELLOW} 9)${C_RESET} Custom (specify runtime)\"\n echo \"\"\n prompt_choice \"Enter number\" bot_pick\n \n AIO_CATEGORY=\"Bot / Application\"\n AIO_TYPE=\"bot_app\"\n \n case $bot_pick in\n 1) AIO_SOFTWARE=\"Node.js\"\n local node_ver\n prompt_default \"Node.js version\" \"20\" node_ver\n install_nvm_node \"$node_ver\"\n local entry\n prompt_default \"Entry file\" \"index.js\" entry\n if confirm_yn \"Clone from Git repo?\"; then\n local git_url\n prompt_choice \"Git URL\" git_url\n git clone \"$git_url\" /home/container/app 2>/dev/null || git pull\n AIO_STARTUP_CMD=\"source /home/container/.nvm/nvm.sh && cd app && npm install && node ${entry}\"\n else\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"source /home/container/.nvm/nvm.sh && cd app && npm install 2>/dev/null; node ${entry}\"\n fi\n AIO_INSTALL_CMD=\"cd app && npm init -y 2>/dev/null\"\n ;;\n 2) AIO_SOFTWARE=\"Python\"\n install_python\n local entry\n prompt_default \"Main Python file\" \"main.py\" entry\n if confirm_yn \"Clone from Git repo?\"; then\n local git_url\n prompt_choice \"Git URL\" git_url\n git clone \"$git_url\" /home/container/app 2>/dev/null || git pull\n AIO_STARTUP_CMD=\"source /home/container/.venv/bin/activate && cd app && pip install -r requirements.txt 2>/dev/null; python3 ${entry}\"\n else\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"source /home/container/.venv/bin/activate && cd app && pip install -r requirements.txt 2>/dev/null; python3 ${entry}\"\n fi\n ;;\n 3) AIO_SOFTWARE=\"Java\"\n local jver\n prompt_default \"Java version\" \"17\" jver\n install_java \"$jver\"\n local jar\n prompt_default \"JAR file\" \"app.jar\" jar\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"cd app && java -jar ${jar}\"\n ;;\n 4) AIO_SOFTWARE=\"Bun\"\n print_info \"Installing Bun...\"\n curl -fsSL https://bun.sh/install | bash\n export PATH=\"/home/container/.bun/bin:$PATH\"\n local entry\n prompt_default \"Entry file\" \"index.ts\" entry\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"export PATH=/home/container/.bun/bin:\\$PATH && cd app && bun install 2>/dev/null; bun run ${entry}\"\n ;;\n 5) AIO_SOFTWARE=\"Go\"\n install_go\n local entry\n prompt_default \"Main file\" \"main.go\" entry\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"export PATH=/home/container/.go/bin:\\$PATH && cd app && go run ${entry}\"\n ;;\n 6) AIO_SOFTWARE=\"Rust\"\n install_rust\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"source /home/container/.cargo/env && cd app && cargo run --release\"\n ;;\n 7) AIO_SOFTWARE=\"C# .NET\"\n print_info \"Installing .NET SDK...\"\n curl -fsSL https://dot.net/v1/dotnet-install.sh | bash -s -- --channel LTS --install-dir /home/container/.dotnet\n export PATH=\"/home/container/.dotnet:$PATH\"\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"export PATH=/home/container/.dotnet:\\$PATH && cd app && dotnet run\"\n ;;\n 8) AIO_SOFTWARE=\"Redbot\"\n install_python\n source /home/container/.venv/bin/activate\n pip install Red-DiscordBot\n AIO_STARTUP_CMD=\"source /home/container/.venv/bin/activate && redbot mybot --no-prompt\"\n AIO_INSTALL_CMD=\"source /home/container/.venv/bin/activate && redbot-setup\"\n ;;\n 9) AIO_SOFTWARE=\"Custom Runtime\"\n local cmd\n prompt_choice \"Full startup command\" cmd\n AIO_STARTUP_CMD=\"$cmd\"\n ;;\n *) print_error \"Invalid choice\"; return 1 ;;\n esac\n}\n\nwizard_web() {\n print_step \"Website / Web App Setup\"\n echo \"\"\n echo -e \" ${C_WHITE}${C_BOLD}What kind of web project?${C_RESET}\"\n echo \"\"\n echo -e \" ${C_YELLOW}1)${C_RESET} Static Site (Nginx)\"\n echo -e \" ${C_YELLOW}2)${C_RESET} Node.js Web App (Express, Next.js, etc.)\"\n echo -e \" ${C_YELLOW}3)${C_RESET} Python Web App (Flask, Django, FastAPI)\"\n echo -e \" ${C_YELLOW}4)${C_RESET} PHP Site (Apache + PHP)\"\n echo -e \" ${C_YELLOW}5)${C_RESET} Code Server (VS Code in browser)\"\n echo -e \" ${C_YELLOW}6)${C_RESET} Gitea (Self-hosted Git)\"\n echo -e \" ${C_YELLOW}7)${C_RESET} Uptime Kuma (Monitoring)\"\n echo -e \" ${C_YELLOW}8)${C_RESET} Haste / Pastebin\"\n echo -e \" ${C_YELLOW}9)${C_RESET} ShareX Upload Server\"\n echo \"\"\n prompt_choice \"Enter number\" web_pick\n \n AIO_CATEGORY=\"Website / Web App\"\n AIO_TYPE=\"web\"\n \n case $web_pick in\n 1) AIO_SOFTWARE=\"Nginx Static\"\n install_nginx\n mkdir -p /home/container/www\n echo '

Forge AIO - Site Live!

Upload your files to /www

' > /home/container/www/index.html\n AIO_STARTUP_CMD=\"nginx -g 'daemon off;' -c /home/container/.forge-aio/nginx.conf\"\n mkdir -p /home/container/.forge-aio\n cat > /home/container/.forge-aio/nginx.conf << 'NGINX'\nevents { worker_connections 128; }\nhttp {\n server {\n listen ${SERVER_PORT};\n root /home/container/www;\n index index.html;\n location / { try_files $uri $uri/ =404; }\n }\n}\nNGINX\n ;;\n 2) AIO_SOFTWARE=\"Node.js Web App\"\n install_nvm_node 20\n mkdir -p /home/container/app\n AIO_STARTUP_CMD=\"source /home/container/.nvm/nvm.sh && cd app && npm install && npm start\"\n ;;\n 3) AIO_SOFTWARE=\"Python Web App\"\n install_python\n local framework\n prompt_default \"Framework (flask/django/fastapi)\" \"flask\" framework\n mkdir -p /home/container/app\n source /home/container/.venv/bin/activate\n pip install \"$framework\" gunicorn uvicorn\n if [ \"$framework\" = \"fastapi\" ]; then\n AIO_STARTUP_CMD=\"source /home/container/.venv/bin/activate && cd app && uvicorn main:app --host 0.0.0.0 --port \\${SERVER_PORT}\"\n elif [ \"$framework\" = \"django\" ]; then\n AIO_STARTUP_CMD=\"source /home/container/.venv/bin/activate && cd app && python manage.py runserver 0.0.0.0:\\${SERVER_PORT}\"\n else\n AIO_STARTUP_CMD=\"source /home/container/.venv/bin/activate && cd app && python main.py\"\n fi\n ;;\n 4) AIO_SOFTWARE=\"PHP\"\n install_php\n mkdir -p /home/container/www\n echo '' > /home/container/www/index.php\n AIO_STARTUP_CMD=\"php -S 0.0.0.0:\\${SERVER_PORT} -t /home/container/www\"\n ;;\n 5) AIO_SOFTWARE=\"Code Server\"\n print_info \"Installing Code Server...\"\n curl -fsSL https://code-server.dev/install.sh | sh -s -- --prefix=/home/container/.code-server\n local cs_pass\n prompt_default \"Password\" \"forgeaio\" cs_pass\n AIO_STARTUP_CMD=\"/home/container/.code-server/bin/code-server --bind-addr 0.0.0.0:\\${SERVER_PORT} --auth password --user-data-dir /home/container/.code-data /home/container\"\n export PASSWORD=\"$cs_pass\"\n ;;\n 6) AIO_SOFTWARE=\"Gitea\"\n print_info \"Installing Gitea...\"\n local gitea_url=$(curl -fsSL \"https://api.github.com/repos/go-gitea/gitea/releases/latest\" | jq -r '.assets[] | select(.name | test(\"linux-amd64$\")) | .browser_download_url')\n curl -fsSL \"$gitea_url\" -o /home/container/gitea && chmod +x /home/container/gitea\n AIO_STARTUP_CMD=\"/home/container/gitea web --port \\${SERVER_PORT}\"\n ;;\n 7) AIO_SOFTWARE=\"Uptime Kuma\"\n install_nvm_node 20\n print_info \"Installing Uptime Kuma...\"\n git clone https://github.com/louislam/uptime-kuma.git /home/container/uptime-kuma 2>/dev/null\n cd /home/container/uptime-kuma && npm ci --production\n AIO_STARTUP_CMD=\"source /home/container/.nvm/nvm.sh && cd /home/container/uptime-kuma && node server/server.js --port=\\${SERVER_PORT}\"\n ;;\n 8) AIO_SOFTWARE=\"Haste\"\n install_nvm_node 20\n git clone https://github.com/toptal/haste-server.git /home/container/haste 2>/dev/null\n cd /home/container/haste && npm install\n AIO_STARTUP_CMD=\"source /home/container/.nvm/nvm.sh && cd /home/container/haste && npm start\"\n ;;\n 9) AIO_SOFTWARE=\"ShareX Upload\"\n install_nvm_node 20\n AIO_STARTUP_CMD=\"source /home/container/.nvm/nvm.sh && cd app && npm start\"\n ;;\n *) print_error \"Invalid choice\"; return 1 ;;\n esac\n}\n\nwizard_database() {\n print_step \"Database Setup\"\n echo \"\"\n echo -e \" ${C_WHITE}${C_BOLD}Pick your database:${C_RESET}\"\n echo \"\"\n echo -e \" ${C_YELLOW}1)${C_RESET} MongoDB\"\n echo -e \" ${C_YELLOW}2)${C_RESET} Redis\"\n echo -e \" ${C_YELLOW}3)${C_RESET} MariaDB / MySQL\"\n echo -e \" ${C_YELLOW}4)${C_RESET} PostgreSQL\"\n echo -e \" ${C_YELLOW}5)${C_RESET} InfluxDB\"\n echo -e \" ${C_YELLOW}6)${C_RESET} Grafana (Dashboard)\"\n echo \"\"\n prompt_choice \"Enter number\" db_pick\n \n AIO_CATEGORY=\"Database\"\n AIO_TYPE=\"database\"\n \n case $db_pick in\n 1) AIO_SOFTWARE=\"MongoDB\"\n install_mongodb\n mkdir -p /home/container/.mongodb/data\n AIO_STARTUP_CMD=\"/home/container/.mongodb/bin/mongod --dbpath /home/container/.mongodb/data --port \\${SERVER_PORT} --bind_ip 0.0.0.0\"\n ;;\n 2) AIO_SOFTWARE=\"Redis\"\n install_redis\n AIO_STARTUP_CMD=\"/home/container/.redis/bin/redis-server --port \\${SERVER_PORT} --bind 0.0.0.0 --dir /home/container\"\n ;;\n 3) AIO_SOFTWARE=\"MariaDB\"\n install_mariadb\n mkdir -p /home/container/.mariadb/data\n AIO_STARTUP_CMD=\"mysqld --datadir=/home/container/.mariadb/data --port=\\${SERVER_PORT} --socket=/tmp/mysql.sock --skip-grant-tables\"\n AIO_INSTALL_CMD=\"mysql_install_db --datadir=/home/container/.mariadb/data\"\n ;;\n 4) AIO_SOFTWARE=\"PostgreSQL\"\n install_postgres\n mkdir -p /home/container/.pgdata\n AIO_STARTUP_CMD=\"pg_ctlcluster 16 main start && tail -f /var/log/postgresql/*.log\"\n ;;\n 5) AIO_SOFTWARE=\"InfluxDB\"\n print_info \"Installing InfluxDB...\"\n curl -fsSL https://dl.influxdata.com/influxdb/releases/influxdb2-2.7.5_linux_amd64.tar.gz -o /tmp/influx.tar.gz\n mkdir -p /home/container/.influxdb\n tar xzf /tmp/influx.tar.gz -C /home/container/.influxdb --strip-components=1 && rm /tmp/influx.tar.gz\n AIO_STARTUP_CMD=\"/home/container/.influxdb/influxd --http-bind-address :${SERVER_PORT} --bolt-path /home/container/.influxdb/influxd.bolt --engine-path /home/container/.influxdb/engine\"\n ;;\n 6) AIO_SOFTWARE=\"Grafana\"\n print_info \"Installing Grafana...\"\n curl -fsSL https://dl.grafana.com/oss/release/grafana-11.0.0.linux-amd64.tar.gz -o /tmp/grafana.tar.gz\n mkdir -p /home/container/.grafana\n tar xzf /tmp/grafana.tar.gz -C /home/container/.grafana --strip-components=1 && rm /tmp/grafana.tar.gz\n AIO_STARTUP_CMD=\"/home/container/.grafana/bin/grafana-server --homepath /home/container/.grafana --config /home/container/.grafana/conf/defaults.ini\"\n ;;\n *) print_error \"Invalid choice\"; return 1 ;;\n esac\n}\n\nwizard_custom() {\n print_step \"Custom Setup\"\n echo \"\"\n echo -e \" ${C_WHITE}${C_BOLD}Full control mode.${C_RESET}\"\n echo -e \" ${C_DIM} You specify exactly what to install and run.${C_RESET}\"\n echo \"\"\n \n AIO_CATEGORY=\"Custom\"\n AIO_TYPE=\"custom\"\n AIO_SOFTWARE=\"Custom\"\n \n if confirm_yn \"Run install commands first?\"; then\n local install_cmd\n prompt_choice \"Install command (e.g. apt install -y nginx)\" install_cmd\n print_info \"Running: ${install_cmd}\"\n eval \"$install_cmd\"\n AIO_INSTALL_CMD=\"$install_cmd\"\n fi\n \n local start_cmd\n prompt_choice \"Startup command\" start_cmd\n AIO_STARTUP_CMD=\"$start_cmd\"\n}\n\nrun_wizard() {\n print_banner\n echo -e \" ${C_WHITE}Welcome! Let's set up your server.${C_RESET}\"\n echo -e \" ${C_DIM}You can reconfigure anytime by typing: forgeaio setup${C_RESET}\"\n print_line\n echo \"\"\n echo -e \" ${C_WHITE}${C_BOLD}What do you want to run?${C_RESET}\"\n echo \"\"\n echo -e \" ${C_YELLOW}1)${C_RESET} 🎮 Game Server ${C_DIM}(Minecraft, CS2, Rust, Palworld, 26+ games)${C_RESET}\"\n echo -e \" ${C_YELLOW}2)${C_RESET} 🤖 Bot / Application ${C_DIM}(Node.js, Python, Java, Go, Rust, C#)${C_RESET}\"\n echo -e \" ${C_YELLOW}3)${C_RESET} 🌐 Website / Web App ${C_DIM}(Nginx, Express, Django, PHP, Code Server)${C_RESET}\"\n echo -e \" ${C_YELLOW}4)${C_RESET} 🗄️ Database ${C_DIM}(MongoDB, Redis, MariaDB, PostgreSQL)${C_RESET}\"\n echo -e \" ${C_YELLOW}5)${C_RESET} ⚙️ Custom ${C_DIM}(Full control — specify your own commands)${C_RESET}\"\n echo \"\"\n prompt_choice \"Enter number (1-5)\" main_pick\n \n case $main_pick in\n 1) wizard_game_server ;;\n 2) wizard_bot_app ;;\n 3) wizard_web ;;\n 4) wizard_database ;;\n 5) wizard_custom ;;\n *) print_error \"Invalid choice. Please restart and pick 1-5.\"; exit 1 ;;\n esac\n \n echo \"\"\n print_line\n print_success \"Setup complete!\"\n echo -e \" ${C_DIM}Software:${C_RESET} ${C_BOLD}${AIO_SOFTWARE}${C_RESET}\"\n echo -e \" ${C_DIM}Category:${C_RESET} ${AIO_CATEGORY}\"\n echo -e \" ${C_DIM}Startup: ${C_RESET} ${C_DIM}${AIO_STARTUP_CMD}${C_RESET}\"\n print_line\n echo \"\"\n \n save_config\n \n # Run any one-time install commands\n if [ -n \"$AIO_INSTALL_CMD\" ]; then\n print_info \"Running post-install setup...\"\n cd /home/container\n eval \"$AIO_INSTALL_CMD\" 2>/dev/null\n fi\n}\n\nstart_service() {\n load_config\n echo \"\"\n print_banner\n echo -e \" ${C_GREEN}${C_BOLD}Starting: ${AIO_SOFTWARE}${C_RESET} ${C_DIM}(${AIO_CATEGORY})${C_RESET}\"\n echo -e \" ${C_DIM}Type 'forgeaio setup' in console to reconfigure${C_RESET}\"\n print_line\n echo \"\"\n \n # Set up PATH for various runtimes\n [ -d \"/home/container/.nvm\" ] && source /home/container/.nvm/nvm.sh 2>/dev/null\n [ -d \"/home/container/.venv\" ] && source /home/container/.venv/bin/activate 2>/dev/null\n [ -d \"/home/container/.cargo\" ] && source /home/container/.cargo/env 2>/dev/null\n [ -d \"/home/container/.go/bin\" ] && export PATH=\"/home/container/.go/bin:$PATH\"\n [ -d \"/home/container/.dotnet\" ] && export PATH=\"/home/container/.dotnet:$PATH\"\n [ -d \"/home/container/.bun/bin\" ] && export PATH=\"/home/container/.bun/bin:$PATH\"\n [ -d \"/home/container/.java/bin\" ] && export PATH=\"/home/container/.java/bin:$PATH\"\n [ -d \"/home/container/.redis/bin\" ] && export PATH=\"/home/container/.redis/bin:$PATH\"\n [ -d \"/home/container/.mongodb/bin\" ] && export PATH=\"/home/container/.mongodb/bin:$PATH\"\n [ -d \"/home/container/.steamcmd\" ] && export PATH=\"/home/container/.steamcmd:$PATH\"\n \n cd /home/container\n echo -e \"${LOG_PREFIX} ${C_GREEN}Service is running${C_RESET}\"\n \n # Replace shell with the actual service\n exec bash -c \"${AIO_STARTUP_CMD}\"\n}\n\n## ─── Main ────────────────────────────────────────────────────────────────────\n\n# Install jq if not present\nif ! command -v jq &>/dev/null; then\n apt-get update -qq && apt-get install -y -qq jq 2>/dev/null || {\n curl -fsSL https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64 -o /usr/local/bin/jq && chmod +x /usr/local/bin/jq\n }\nfi\n\n# Create forgeaio command alias\nif [ ! -f /usr/local/bin/forgeaio ]; then\n cat > /usr/local/bin/forgeaio << 'ALIAS'\n#!/bin/bash\nif [ \"$1\" = \"setup\" ] || [ \"$1\" = \"wizard\" ] || [ \"$1\" = \"reconfigure\" ]; then\n rm -f /home/container/.forge-aio/config.json\n echo \"[Forge AIO] Reconfiguring... Restart the server to run setup wizard.\"\nelif [ \"$1\" = \"info\" ] || [ \"$1\" = \"status\" ]; then\n if [ -f /home/container/.forge-aio/config.json ]; then\n echo \"=== Forge AIO Configuration ===\"\n cat /home/container/.forge-aio/config.json | jq .\n else\n echo \"Not configured yet. Start the server to run the setup wizard.\"\n fi\nelse\n echo \"Usage: forgeaio \"\n echo \" setup - Reconfigure (runs wizard on next start)\"\n echo \" info - Show current configuration\"\nfi\nALIAS\n chmod +x /usr/local/bin/forgeaio\nfi\n\n# Check if first argument is \"setup\" (typed in console)\nif [[ \"${1}\" == \"setup\" ]] || [[ \"${1}\" == \"wizard\" ]]; then\n rm -f \"$CONFIG_FILE\"\nfi\n\n# Main flow\nif [ -f \"$CONFIG_FILE\" ] && jq -e '.configured' \"$CONFIG_FILE\" &>/dev/null; then\n start_service\nelse\n run_wizard\n echo \"\"\n print_info \"Starting your ${AIO_SOFTWARE} server now...\"\n echo \"\"\n sleep 2\n start_service\nfi\nENTRYPOINT_EOF\n\nchmod +x /mnt/server/.forge-aio/entrypoint.sh\n\n## ─── Create default directory structure ──────────────────────────────────────\nmkdir -p /mnt/server/app\nmkdir -p /mnt/server/server\nmkdir -p /mnt/server/www\n\necho \"-----------------------------------------\"\necho \"Forge AIO installed successfully!\"\necho \"Start the server to run the setup wizard.\"\necho \"-----------------------------------------\"", "container": "ghcr.io/parkervcp/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Startup Command Override", "description": "Optional: Override the startup command entirely. Leave empty to use the wizard-configured command.", "env_variable": "STARTUP_CMD", "default_value": "", "user_viewable": true, "user_editable": true, "rules": "nullable|string", "field_type": "text" } ] }