{ "_comment": "DO NOT EDIT: FILE GENERATED FOR PTERODACTYL PANEL - PTERODACTYL.IO", "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-08-22T18:28:00+01:00", "name": "NeoForge + Packwiz", "author": "hamza@ahmza.com", "description": "Reusable NeoForge Minecraft server egg with Packwiz server-side synchronization. Handles Pterodactyl memory=0 as unlimited by omitting -Xmx.", "features": [ "eula", "java_version", "pid_limit" ], "docker_images": { "Java 21": "ghcr.io/ptero-eggs/yolks:java_21" }, "file_denylist": [], "startup": "bash ./start-packwiz.sh {{SERVER_MEMORY}}", "config": { "files": "{\n \"server.properties\": {\n \"parser\": \"properties\",\n \"find\": {\n \"server-ip\": \"0.0.0.0\",\n \"server-port\": \"{{server.build.default.port}}\",\n \"query.port\": \"{{server.build.default.port}}\"\n }\n }\n}", "startup": "{\n \"done\": \")! For help, type \\\"\"\n}", "logs": "{}", "stop": "stop" }, "scripts": { "installation": { "script": "#!/bin/bash\nset -euo pipefail\n\ncd /mnt/server\n\napt-get update\napt-get install -y --no-install-recommends curl ca-certificates jq\nrm -rf /var/lib/apt/lists/*\n\necho \"Installing NeoForge ${NEOFORGE_VERSION} for Minecraft ${MC_VERSION}\"\n\nNEOFORGE_BASE=\"https://maven.neoforged.net/releases/net/neoforged/neoforge/${NEOFORGE_VERSION}\"\nINSTALLER=\"neoforge-${NEOFORGE_VERSION}-installer.jar\"\n\ncurl -fL \"${NEOFORGE_BASE}/${INSTALLER}\" -o \"${INSTALLER}\"\n\nrm -rf \"libraries/net/neoforged/neoforge/${NEOFORGE_VERSION}\"\n\njava -jar \"${INSTALLER}\" --installServer\nrm -f \"${INSTALLER}\"\n\nARGS_SRC=\"libraries/net/neoforged/neoforge/${NEOFORGE_VERSION}/unix_args.txt\"\nif [[ ! -f \"${ARGS_SRC}\" ]]; then\n echo \"ERROR: NeoForge unix_args.txt not found at ${ARGS_SRC}\"\n exit 10\nfi\n\n# Copy rather than symlink so backups/restores remain self-contained.\ncp -f \"${ARGS_SRC}\" ./unix_args.txt\n\necho \"Downloading packwiz-installer-bootstrap\"\n\nPW_URL=\"$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer-bootstrap/releases/latest \\\n | jq -r '.assets[] | select(.name==\"packwiz-installer-bootstrap.jar\") | .browser_download_url' \\\n | head -n1)\"\n\nif [[ -z \"${PW_URL}\" || \"${PW_URL}\" == \"null\" ]]; then\n echo \"ERROR: Could not resolve packwiz-installer-bootstrap release URL\"\n exit 11\nfi\n\ncurl -fL \"${PW_URL}\" -o packwiz-installer-bootstrap.jar\n\ncat > start-packwiz.sh <<'STARTSCRIPT'\n#!/bin/bash\nset -euo pipefail\n\ncd /home/container\n\nMEMORY_MB=\"${1:-0}\"\n\nif ! [[ \"${MEMORY_MB}\" =~ ^[0-9]+$ ]]; then\n echo \"ERROR: Invalid Pterodactyl memory value: '${MEMORY_MB}'\"\n exit 21\nfi\n\nif [[ \"${PACKWIZ_AUTO_SYNC:-1}\" == \"1\" ]]; then\n echo \"[packwiz] Syncing server pack from ${PACKWIZ_URL}\"\n java -jar packwiz-installer-bootstrap.jar \\\n -g \\\n -s server \\\n \"${PACKWIZ_URL}\"\nelse\n echo \"[packwiz] Auto-sync disabled\"\nfi\n\n# Pterodactyl uses 0 to mean unlimited memory. In that case omit -Xmx\n# entirely rather than passing the invalid value -Xmx0M.\nMEMORY_ARGS=(-Xms128M)\n\nif (( MEMORY_MB > 0 )); then\n MEMORY_ARGS+=(\"-Xmx${MEMORY_MB}M\")\n echo \"[java] Maximum heap: ${MEMORY_MB} MB\"\nelse\n echo \"[java] Pterodactyl memory limit is unlimited; omitting -Xmx\"\nfi\n\n# Preserve simple space-separated JVM options without putting shell logic\n# into Pterodactyl's STARTUP field.\nEXTRA_JVM_ARGS=()\nif [[ -n \"${JVM_ARGS:-}\" ]]; then\n read -r -a EXTRA_JVM_ARGS <<< \"${JVM_ARGS}\"\nfi\n\nexec java \\\n \"${MEMORY_ARGS[@]}\" \\\n \"${EXTRA_JVM_ARGS[@]}\" \\\n -Dterminal.jline=false \\\n -Dterminal.ansi=true \\\n @unix_args.txt \\\n nogui\nSTARTSCRIPT\n\nchmod +x start-packwiz.sh\n\necho \"Installation complete.\"\n", "container": "eclipse-temurin:21-jdk-jammy", "entrypoint": "bash" } }, "variables": [ { "name": "Minecraft Version", "description": "Minecraft version this server is intended to run. Informational for this egg; NeoForge version controls the actual installed loader.", "env_variable": "MC_VERSION", "default_value": "1.21.1", "user_viewable": true, "user_editable": true, "rules": "required|string|max:32", "field_type": "text" }, { "name": "NeoForge Version", "description": "Exact NeoForge version to install from the official NeoForged Maven.", "env_variable": "NEOFORGE_VERSION", "default_value": "21.1.248", "user_viewable": true, "user_editable": true, "rules": "required|regex:/^[0-9A-Za-z._+-]+$/", "field_type": "text" }, { "name": "Packwiz URL", "description": "HTTP/HTTPS URL to pack.toml. Example: https://mc-pack.example.com/forever/pack.toml", "env_variable": "PACKWIZ_URL", "default_value": "https://example.com/pack.toml", "user_viewable": true, "user_editable": true, "rules": "required|url", "field_type": "text" }, { "name": "Packwiz Auto Sync", "description": "Run packwiz-installer before every server start. 1 = enabled, 0 = disabled. Recommended: Forever=0 after deployment if you want explicit promotions; Playground=1.", "env_variable": "PACKWIZ_AUTO_SYNC", "default_value": "1", "user_viewable": true, "user_editable": true, "rules": "required|boolean", "field_type": "text" }, { "name": "JVM Arguments", "description": "Optional extra JVM arguments. Leave blank initially; Pterodactyl supplies the Xmx value from the server memory limit.", "env_variable": "JVM_ARGS", "default_value": "", "user_viewable": true, "user_editable": true, "rules": "nullable|string|max:2048", "field_type": "text" } ] }